前言
本文介紹的是AspNetCore的MVC專案,WebApi+獨立前端這種前後端分離的專案就不需要多此一舉了~預設前端小夥伴是懂得使用前端工具鏈的。
為啥要用MVC這種服務端渲染技術呢?
- 簡單專案不需要強行分離增加複雜度(如:我正在開發的部落格專案)
- 後端渲染利於SEO,對部落格網站友好
OK,雖然MVC的技術老了點,但依然可以結合現代前端工具鏈來提高效率
本文的食用需要先安裝好Node.js環境,下載地址:https://nodejs.org/en/download
在開始前,先看看我們的專案檔案結構
- Blog/
- Blog.Web/
- Program.cs
- Blog.Web.csproj
- Blog.Data/
- Blog.sln
- Blog.Web/
使用NPM安裝依賴
首先在專案根目錄(也就是Blog/Blog.Web
)執行
npm init
生成package.json
檔案
完成之後專案結構應該類似這樣
- Blog/
- Blog.Web/
- Program.cs
- Blog.Web.csproj
- package.json (npm init 命令建立的檔案)
- Blog.Web/
然後編輯package.json
或者使用命令列npm install bootstrap
來新增需要的前端庫
安裝的前端庫會儲存在Blog/Blog.Web/node_modules
這個目錄下,但我們的靜態檔案需要放在Blog/Blog.Web/wwwroot
裡才行,也就是說,我們需要將使用到的 npm 包移動到 wwwroot 檔案下。
怎麼搞?手動移動或複製是不可能的,太麻煩了。
這時候就要藉助自動化工具,這裡選擇了gulp.js
,用於實現自動移動檔案,打包壓縮 js、css、image、刪除檔案等操作。提高生產力~
安裝gulp
首先安裝gulp全域性工具
npm install --global gulp-cli
然後在專案中安裝gulp以及幾個外掛作為開發依賴(devDependencies)
//gulp.js
npm install gulp --save-dev
//壓縮 css
npm install gulp-clean-css --save-dev
//合併檔案
npm install gulp-concat --save-dev
//壓縮 js
npm install gulp-uglify --save-dev
//重新命名
npm install gulp-rename --save-dev
//刪除檔案、資料夾
npm install rimraf --save-dev
//監聽檔案變化
npm install gulp-changed --save-dev
安裝完了之後,專案的package.json
檔案應該類似下面這樣:
{
"name": "star-blog",
"devDependencies": {
"gulp": "^4.0.2",
"gulp-changed": "^4.0.3",
"gulp-clean-css": "^4.3.0",
"gulp-concat": "^2.6.1",
"gulp-rename": "^2.0.0",
"gulp-uglify": "^3.0.2",
"rimraf": "^3.0.2"
},
"dependencies": {
...
}
}
配置gulp
繼續在根目錄(和package.json
同級目錄)下新建gulpfile.js
檔案
/// <binding BeforeBuild='min' Clean='clean' ProjectOpened='auto' />
"use strict";
//載入使用到的 gulp 外掛
const gulp = require("gulp"),
rimraf = require("rimraf"),
concat = require("gulp-concat"),
cssmin = require("gulp-clean-css"),
rename = require("gulp-rename"),
uglify = require("gulp-uglify"),
changed = require("gulp-changed");
//定義 wwwroot 下的各檔案存放路徑
const paths = {
root: "./wwwroot/",
css: './wwwroot/css/',
js: './wwwroot/js/',
lib: './wwwroot/lib/'
};
//css
paths.cssDist = paths.css + "**/*.css";//匹配所有 css 的檔案所在路徑
paths.minCssDist = paths.css + "**/*.min.css";//匹配所有 css 對應壓縮後的檔案所在路徑
paths.concatCssDist = paths.css + "app.min.css";//將所有的 css 壓縮到一個 css 檔案後的路徑
//js
paths.jsDist = paths.js + "**/*.js";//匹配所有 js 的檔案所在路徑
paths.minJsDist = paths.js + "**/*.min.js";//匹配所有 js 對應壓縮後的檔案所在路徑
paths.concatJsDist = paths.js + "app.min.js";//將所有的 js 壓縮到一個 js 檔案後的路徑
//使用 npm 下載的前端元件包
const libs = [
{name: "jquery", dist: "./node_modules/jquery/dist/**/*.*"},
{name: "popper", dist: "./node_modules/popper.js/dist/**/*.*"},
{name: "bootstrap", dist: "./node_modules/bootstrap/dist/**/*.*"},
{name:"bootswatch",dist: "./node_modules/bootswatch/dist/**/*.*"}
];
//清除壓縮後的檔案
gulp.task("clean:css", done => rimraf(paths.minCssDist, done));
gulp.task("clean:js", done => rimraf(paths.minJsDist, done));
gulp.task("clean", gulp.series(["clean:js", "clean:css"]));
//移動 npm 下載的前端元件包到 wwwroot 路徑下
gulp.task("move", done => {
libs.forEach(function (item) {
gulp.src(item.dist)
.pipe(gulp.dest(paths.lib + item.name + "/dist"));
});
done()
});
//每一個 css 檔案壓縮到對應的 min.css
gulp.task("min:css", () => {
return gulp.src([paths.cssDist, "!" + paths.minCssDist], {base: "."})
.pipe(rename({suffix: '.min'}))
.pipe(changed('.'))
.pipe(cssmin())
.pipe(gulp.dest('.'));
});
//將所有的 css 檔案合併打包壓縮到 app.min.css 中
gulp.task("concatmin:css", () => {
return gulp.src([paths.cssDist, "!" + paths.minCssDist], {base: "."})
.pipe(concat(paths.concatCssDist))
.pipe(changed('.'))
.pipe(cssmin())
.pipe(gulp.dest("."));
});
//每一個 js 檔案壓縮到對應的 min.js
gulp.task("min:js", () => {
return gulp.src([paths.jsDist, "!" + paths.minJsDist], {base: "."})
.pipe(rename({suffix: '.min'}))
.pipe(changed('.'))
.pipe(uglify())
.pipe(gulp.dest('.'));
});
//將所有的 js 檔案合併打包壓縮到 app.min.js 中
gulp.task("concatmin:js", () => {
return gulp.src([paths.jsDist, "!" + paths.minJsDist], {base: "."})
.pipe(concat(paths.concatJsDist))
.pipe(changed('.'))
.pipe(uglify())
.pipe(gulp.dest("."));
});
gulp.task("min", gulp.series(["min:js", "min:css"]));
gulp.task("concatmin", gulp.series(["concatmin:js", "concatmin:css"]));
//監聽檔案變化後自動執行
gulp.task("auto", () => {
gulp.watch(paths.css, gulp.series(["min:css", "concatmin:css"]));
gulp.watch(paths.js, gulp.series(["min:js", "concatmin:js"]));
});
執行任務
上面定義這幾個任務:
- move:把在
libs
常量裡配置的node_modules
包的dist資料夾移動到wwwroot/lib
裡 - min:把我們在
wwwroot/css
和wwwroot/js
裡寫的css和js,每一個都壓縮成xxx.min.css
/xxx.min.js
- concatmin:把上面
min
壓縮的所有css和js,合成一個app.min.css
和app.min.js
- auto:自動監聽檔案變化後自動執行上面的
min
和concatmin
任務
在終端中輸入gulp --tasks
,可以檢視我們定義的這些任務
> gulp --tasks
[17:37:44] Tasks for /home/da/Code/StarBlog/StarBlog.Web/gulpfile.js
[17:37:44] ├── clean:css
[17:37:44] ├── clean:js
[17:37:44] ├─┬ clean
[17:37:44] │ └─┬ <series>
[17:37:44] │ ├── clean:js
[17:37:44] │ └── clean:css
[17:37:44] ├── move
[17:37:44] ├── min:css
[17:37:44] ├── concatmin:css
[17:37:44] ├── min:js
[17:37:44] ├── concatmin:js
[17:37:44] ├─┬ min
[17:37:44] │ └─┬ <series>
[17:37:44] │ ├── min:js
[17:37:44] │ └── min:css
[17:37:44] ├─┬ concatmin
[17:37:44] │ └─┬ <series>
[17:37:44] │ ├── concatmin:js
[17:37:44] │ └── concatmin:css
[17:37:44] └── auto
使用gulp task-name
的命令可以執行任務,例如:
> gulp min
[17:41:41] Using gulpfile /home/da/Code/StarBlog/StarBlog.Web/gulpfile.js
[17:41:41] Starting 'min'...
[17:41:41] Starting 'min:js'...
[17:41:41] Finished 'min:js' after 19 ms
[17:41:41] Starting 'min:css'...
[17:41:41] Finished 'min:css' after 21 ms
[17:41:41] Finished 'min' after 44 ms
這就完成了把我們在wwwroot/css
和wwwroot/js
裡寫的css和js,每一個都壓縮成xxx.min.css
/xxx.min.js
的任務。方便!
結合IDE
VS我沒有用過,我是用Rider做開發的,所以只介紹一下rider的
很簡單,開啟 Run/Debug Configuration,在新增配置裡面選擇 JavaScript Build Tools 裡的 Gulp.js
然後選擇專案裡的GulpFile
,Tasks欄下拉可以看到我們定義好的任務,直接新增就完事了
新增完就像C#專案一樣,可以直接執行
razor裡使用
使用Gulp.js
收集靜態檔案到wwwroot
目錄後,razor檔案裡的引用需要小小的改一下,如下:
引用CSS檔案
<link rel="stylesheet" href="~/lib/fontawesome-free-6.0.0-web/css/all.css">
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css">
<link rel="stylesheet" href="~/lib/bootswatch/dist/united/bootstrap.min.css">
<link rel="stylesheet" href="~/css/app.min.css">
引用JS檔案
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/js/app.min.js"></script>
大功告成!