前言

本文介绍的是AspNetCore的MVC项目,WebApi+独立前端这种前后端分离的项目就不需要多此一举了~默认前端小伙伴是懂得使用前端工具链的。

为啥要用MVC这种服务端渲染技术呢?

  1. 简单项目不需要强行分离增加复杂度(如:我正在开发的博客项目)
  2. 后端渲染利于SEO,对博客网站友好

OK,虽然MVC的技术老了点,但依然可以结合现代前端工具链来提高效率

本文的食用需要先安装好Node.js环境,下载地址:https://nodejs.org/en/download

在开始前,先看看我们的项目文件结构

  • Blog/

    • Blog.Web/

      • Program.cs
      • Blog.Web.csproj
    • Blog.Data/
    • Blog.sln

使用NPM安装依赖

首先在项目根目录(也就是Blog/Blog.Web)执行

npm init

生成package.json文件

完成之后项目结构应该类似这样

  • Blog/

    • Blog.Web/

      • Program.cs
      • Blog.Web.csproj
      • package.json (npm init 命令创建的文件)

然后编辑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>

大功告成!

参考资料

Asp-Net-Core开发笔记:使用NPM和gulp管理前端静态文件的更多相关文章

  1. Django项目引入NPM和gulp管理前端资源

    前言 之前写了一篇<Asp-Net-Core开发笔记:使用NPM和gulp管理前端静态文件>,现在又来用Django开发项目了,之前我搞了一个Django的快速开发脚手架「DjangoSt ...

  2. Asp.Net Core Linux环境下 找不到配置文件、静态文件的问题

    直接发布会找不到配置文件,和静态文件.需要先cd到项目文件夹,然后在发布.

  3. 在 ASP.NET Core 项目中使用 npm 管理你的前端组件包

    一.前言 在项目的前端开发中,对于绝大多数的小伙伴来说,当然,也包括我,不可避免的需要在项目中使用到一些第三方的组件包.这时,团队中的小伙伴是选择直接去组件的官网上下载,还是图省事直接在网上搜索,然后 ...

  4. 在CentOS7 开发与部署 asp.net core app笔记

    原文:在CentOS7 开发与部署 asp.net core app笔记 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/lihongzhai/art ...

  5. asp.net core开发环境准备

    1.1  安装sdk和运行时 浏览器打开网址https://www.microsoft.com/net/download, 到.Net Core下载页面. 根据操作系统,下载对应的SDK进行安装.安装 ...

  6. C# -- HttpWebRequest 和 HttpWebResponse 的使用 C#编写扫雷游戏 使用IIS调试ASP.NET网站程序 WCF入门教程 ASP.Net Core开发(踩坑)指南 ASP.Net Core Razor+AdminLTE 小试牛刀 webservice创建、部署和调用 .net接收post请求并把数据转为字典格式

    C# -- HttpWebRequest 和 HttpWebResponse 的使用 C# -- HttpWebRequest 和 HttpWebResponse 的使用 结合使用HttpWebReq ...

  7. 2月送书福利:ASP.NET Core开发实战

    大家都知道我有一个公众号“恰童鞋骚年”,在公众号2020年第一天发布的推文<2020年,请让我重新介绍我自己>中,我曾说到我会在2020年中每个月为所有关注“恰童鞋骚年”公众号的童鞋们送一 ...

  8. [转]ASP.NET Core 开发-Logging 使用NLog 写日志文件

    本文转自:http://www.cnblogs.com/Leo_wl/p/5561812.html ASP.NET Core 开发-Logging 使用NLog 写日志文件. NLog 可以适用于 . ...

  9. ASP.NET Core 开发-中间件(Middleware)

    ASP.NET Core开发,开发并使用中间件(Middleware). 中间件是被组装成一个应用程序管道来处理请求和响应的软件组件. 每个组件选择是否传递给管道中的下一个组件的请求,并能之前和下一组 ...

随机推荐

  1. Go数组遍历与排序

    遍历数组 Go遍历数组有两种方式 1.按照数组下标进行遍历 2.用range遍历 package main import ( "fmt" ) func main() { // 声明 ...

  2. redis持久层设置

    1.默认为RDB存储方式,每次修改数据库,需要输入指令save才会存入磁盘的dump.rdb文件里,相当于备份快照,下次开启服务后会自动缓存于内存里.当然,满足下面几个条件也会自动保存到磁盘:save ...

  3. 创建react开发环境

    准备工作 1.下载node.js(http://nodejs.cn/download/)推荐下载长期支持的版本 2.下载cnpm(https://jingyan.baidu.com/article/9 ...

  4. vue2.0与vue3.0项目创建

    脚手架安装与卸载 安装 npm install -g vue-cli //or npm install -g @vue/cli 卸载 npm uninstall -g vue-cli //or npm ...

  5. 微信小程序动画实现(API,css)

    微信小程序动画API实现 index.js clicktap:function(){ var Animation=wx.createAnimation({ duration: 2000, }) Ani ...

  6. 学习笔记--Java中的变量

    Java中的变量 /** * 关于 Java 语言当中的变量: * * 1. 什么是变量? * - 变量的本质上来说是内存空间,这块空间有(数据类型.名字.字面值) * - 变量包括三部分:数据类型. ...

  7. 使用.NET 6开发TodoList应用(25)——实现RefreshToken

    系列导航及源代码 使用.NET 6开发TodoList应用文章索引 需求 在上一篇文章使用.NET 6开发TodoList应用(24)--实现基于JWT的Identity功能中,我们演示了如何使用.N ...

  8. 如何将Excl内数据导入数据库?

    最近有个Excl表格内的数据需要导入SQL Server数据库内,使用SQL Server Management Studio客户端图形界面操作了一番,步骤还挺多,感觉有必要分享给大家一下,顺便自己也 ...

  9. [USB波形分析] 全速USB波形数据分析(一)

    在之前的文章一次CAN波形分析之旅里,根据示波器采集的波形数据,详细地分析了CAN通信.今天来分析USB数据,还是同样的流程,但是这次使用matplotlib来协助分析. USB基本波形 USB通过一 ...

  10. java类的反射机制

    1.获得一个类的类对象有哪些方式? - 方法1:类型.class,例如:String.class- 方法2:对象.getClass(),例如:"hello".getClass()- ...