返回文章列表文章索引阅读全文
STARBLOG / 阅读手记
Asp-Net-Core开发笔记

Asp-Net-Core Development Notes: Managing Frontend Static Files with NPM and Gulp

Introduction This article covers ASP.NET Core MVC projects. For frontend-backend separated projects like WebApi plus a standalone frontend, there's no need for this extra step~ Frontend folks are assumed to already know how to use the frontend toolchain. Why use MVC, a server-side rendering technology? Simple projects don't need to force a split that adds complexity (e.g., the blog project I'm currently developing) Server-side rendering is good for SEO and friendly to blog sites OK, although MVC is a bit dated, it can still be combined with a modern frontend toolchain to improve efficiency To follow this article, you need to have the Node.js environment installed first

曦远 (DealiAxy)约 23 分钟
目录8 个章节

Introduction

This article covers ASP.NET Core MVC projects. For frontend-backend separated projects like WebApi plus a standalone frontend, there's no need for this extra step~ Frontend folks are assumed to already know how to use the frontend toolchain.

Why use MVC, a server-side rendering technology?

  1. Simple projects don't need to force a split that adds complexity (e.g., the blog project I'm currently developing)
  2. Server-side rendering is good for SEO and friendly to blog sites

OK, although MVC is a bit dated, it can still be combined with a modern frontend toolchain to improve efficiency

To follow this article, you need to have the Node.js environment installed first. Download: https://nodejs.org/en/download

Before we start, let's take a look at our project file structure

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

Installing Dependencies with NPM

First, in the project root directory (that is, Blog/Blog.Web), run

npm init

This generates a package.json file

After that, the project structure should look something like this

  • Blog/
    • Blog.Web/
      • Program.cs
      • Blog.Web.csproj
      • package.json (file created by the npm init command)

Then edit package.json or use the command line npm install bootstrap to add the frontend libraries you need

Installed frontend libraries will be saved in the Blog/Blog.Web/node_modules directory, but our static files need to be placed in Blog/Blog.Web/wwwroot, which means we need to move the npm packages we use into the wwwroot folder.

How to do this? Manually moving or copying is out of the question—too much hassle.

This is where we turn to automation tools. Here I chose gulp.js, which is used to automatically move files, bundle and minify js, css, and images, delete files, and more. Boost productivity~

Installing gulp

First, install the gulp global tool

npm install --global gulp-cli

Then install gulp and several plugins in the project as development dependencies (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

After installation, the project's package.json file should look something like this:

{
  "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": {
      ...
  }
}

Configuring gulp

Continue by creating a gulpfile.js file in the root directory (the same directory as package.json)

/// <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"]));
});

Running Tasks

The tasks defined above are:

  • move: Move the dist folders of the node_modules packages configured in the libs constant into wwwroot/lib
  • min: Minify each of the css and js files we wrote in wwwroot/css and wwwroot/js into xxx.min.css/xxx.min.js
  • concatmin: Combine all the css and js minified by min above into a single app.min.css and app.min.js
  • auto: Automatically watch for file changes and then automatically run the min and concatmin tasks above

Enter gulp --tasks in the terminal to view the tasks we defined

> 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

Use the gulp task-name command to run a task, for example:

> 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

This completes the task of minifying each of the css and js files we wrote in wwwroot/css and wwwroot/js into xxx.min.css/xxx.min.js. Convenient!

Integrating with the IDE

I haven't used VS; I develop with Rider, so I'll only cover Rider

It's simple: open Run/Debug Configuration, and in add configuration, select Gulp.js under JavaScript Build Tools

Then select the GulpFile in the project. In the Tasks dropdown you can see the tasks we defined—just add them and you're done

image-20220217174557405

After adding, you can run them directly, just like a C# project

Using in Razor

After using Gulp.js to collect static files into the wwwroot directory, the references in Razor files need a small change, as follows:

Referencing CSS files

<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">

Referencing JS files

<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/js/app.min.js"></script>

All done!

References

_EOF_

Asp-Net-Core Development Notes: Managing Frontend Static Files with NPM and Gulp

本文作者:
程序设计实验室
版权声明:
本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

相关文章

Asp-Net-Core开发笔记:快速在已有项目中引入EFCore

很多项目一开始选型的时候没有选择EFCore,不过EFCore确实好用,也许由于种种原因后面还是需要用到,这时候引入EFCore也很方便。 本文以 StarBlog 为例,StarBlog 目前使用的 ORM 是 FreeSQL ,引入 EFCore 对我来说最大的好处是支持多个数据库,如果是 FreeSQL 的话,服务注册的时候是单例模式,只能连接一个数据库,如果需要使用 FreeSQL 同时

2023-10-08 · Asp-Net-Core开发笔记 · 约 1 分钟

讨论

共 0 条

良言一句三冬暖,恶语伤人六月寒。

加载评论中…