本文介绍的是AspNetCore的MVC项目,WebApi+独立前端这种前后端分离的项目就不需要多此一举了~默认前端小伙伴是懂得使用前端工具链的。
为啥要用MVC这种服务端渲染技术呢?
OK,虽然MVC的技术老了点,但依然可以结合现代前端工具链来提高效率
本文的食用需要先安装好Node.js环境,下载地址:https://nodejs.org/en/download
在开始前,先看看我们的项目文件结构
首先在项目根目录(也就是Blog/Blog.Web
)执行
npm init
生成package.json
文件
完成之后项目结构应该类似这样
然后编辑package.json
或者使用命令行npm install bootstrap
来添加需要的前端库
安装的前端库会保存在Blog/Blog.Web/node_modules
这个目录下,但我们的静态文件需要放在Blog/Blog.Web/wwwroot
里才行,也就是说,我们需要将使用到的 npm 包移动到 wwwroot 文件下。
怎么搞?手动移动或复制是不可能的,太麻烦了。
这时候就要借助自动化工具,这里选择了gulp.js
,用于实现自动移动文件,打包压缩 js、css、image、删除文件等操作。提高生产力~
首先安装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": { ... } }
继续在根目录(和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"])); });
上面定义这几个任务:
libs
常量里配置的node_modules
包的dist文件夹移动到wwwroot/lib
里wwwroot/css
和wwwroot/js
里写的css和js,每一个都压缩成xxx.min.css
/xxx.min.js
min
压缩的所有css和js,合成一个app.min.css
和app.min.js
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
的任务。方便!
VS我没有用过,我是用Rider做开发的,所以只介绍一下rider的
很简单,打开 Run/Debug Configuration,在添加配置里面选择 JavaScript Build Tools 里的 Gulp.js
然后选择项目里的GulpFile
,Tasks栏下拉可以看到我们定义好的任务,直接添加就完事了
添加完就像C#项目一样,可以直接执行
使用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>
大功告成!