When express builds a website, it needs to optimize the loading speed of resources and reduce the consumption of server resources. For example, style is written in less modules. Finally, we need to compile less into css and merge compiled files.
Although Express has plug-ins to compile less, it takes up server resources and needs to be compiled first every time it accesses. These static resources I want to refer to directly. Another problem after compiling express is that the less file is compiled into css, but the suffix name is still. less, which is simply for students with obsessive-compulsive disorder. A form of torture.
I use gulp here to help me solve these problems. The web pack is too big, the cost of learning is too high, other compiler tools have not seen it, so gulp is the only choice.
Here we need to solve these problems (see the end of the article for the complete code):
- Compile files (here I use less to compile css)
- Merge each module file (merge all CSS files into one main.min.css)
- Compressed pictures
- Monitor file changes and automatically refresh pages
- Task execution sequence and error handling
In fact, the first three problems are better solved. We can directly introduce the corresponding compiler and compression plug-in, then create task, and finally run it.
const less = require('gulp-less'); const minify = require('gulp-clean-css'); const concat = require('gulp-concat'); const imagemin = require('gulp-imagemin'); // less Compilation + Compression gulp.task('less', () => { return gulp.src([ 'public/stylesheets/reset.css', 'public/stylesheets/common.css', 'public/stylesheets/less/*.less' ]) .pipe(plumber()) .pipe(less()) .pipe(minify()) .pipe(concat('main.min.css')) .pipe(gulp.dest('dist/css/')) }); // Compressed img gulp.task('img', () => { return gulp.src('public/images/**/*') //Compressed pictures .pipe(plumber()) .pipe(imagemin({optimizationLevel: 3, progressive: true, interlaced: true})) .pipe(gulp.dest('dist/images/')) });
Complicated is the fourth problem, here we need to use browser-sync, gulp-nodemon, the original project start directly from express, here you need to start the project in gulp file, because this can do some special processing when the project starts, here browser-sync service proxy express service address, the original. localhost:3000 will become localhost:3001
const browserSync = require('browser-sync').create(); const reload = browserSync.reload; const nodemon = require('gulp-nodemon'); // Start express gulp.task('node', ()=>{ nodemon({ script: './bin/www', ext: 'js html css', env: { 'NODE_ENV': 'development' } }) }) // Start up service gulp.task('serve', ['node'],() => { browserSync.init({ proxy: 'localhost:3000', // Designated proxy url notify: false, // Refresh no pop-up prompt port: 3001, // port }); // Monitor gulp.watch('public/stylesheets/**/*', ['less']).on('change', reload); gulp.watch('public/lib/**/*', ['copy']).on('change', reload); gulp.watch('public/images/**/*',['img']).on('change',reload); });
Finally, we need to perform these tasks defined, solve some possible errors that cause the listening to stop, and add a clean method, which will clear the dist file content and regenerate new content at each boot. It is important to note that the clean method must be first implemented.
const runSequence = require('run-sequence'); // Sequential task execution const plumber = require('gulp-plumber'); // Do not stop the monitoring procedure if there is a mistake // Delete files gulp.task('clean', async () => { await del(['dist/']); }); gulp.task('default', () =>{ runSequence('clean', ['less', 'img', 'copy'], 'serve') });
The complete code is as follows
// package.json "devDependencies": { "browser-sync": "^2.26.7", "del": "^5.0.0", "gulp": "^3.9.1", "gulp-autoprefixer": "^6.1.0", "gulp-base64": "^0.1.3", "gulp-clean-css": "^4.2.0", "gulp-concat": "^2.6.1", "gulp-imagemin": "^6.0.0", "gulp-less": "^4.0.1", "gulp-nodemon": "^2.4.2", "gulp-plumber": "^1.2.1", "gulp-replace": "^1.0.0", "gulp-uglify": "^3.0.2", "gulp-watch": "^5.0.1", "nodemon": "^1.18.6", "run-sequence": "^2.2.1" } // ========================================================= // gulpfile.js const gulp = require('gulp'); const del = require('del'); const less = require('gulp-less'); const minify = require('gulp-clean-css'); // const autoprefixer = require('gulp-autoprefixer'); const concat = require('gulp-concat'); const imagemin = require('gulp-imagemin'); const browserSync = require('browser-sync').create(); const reload = browserSync.reload; const nodemon = require('gulp-nodemon'); const runSequence = require('run-sequence'); // Sequential task execution const plumber = require('gulp-plumber'); // Failure to stop the program // Start express gulp.task('node', ()=>{ nodemon({ script: './bin/www', ext: 'js html css', env: { 'NODE_ENV': 'development' } }) }) // Delete files gulp.task('clean', async () => { await del(['dist/']); }); // less Compilation + Compression gulp.task('less', () => { return gulp.src([ 'public/stylesheets/reset.css', 'public/stylesheets/common.css', 'public/stylesheets/less/*.less' ]) .pipe(plumber()) .pipe(less()) .pipe(minify()) .pipe(concat('main.min.css')) .pipe(gulp.dest('dist/css/')) }); // Compressed img gulp.task('img', () => { return gulp.src('public/images/**/*') //Compressed pictures .pipe(plumber()) .pipe(imagemin({optimizationLevel: 3, progressive: true, interlaced: true})) .pipe(gulp.dest('dist/images/')) }); // Direct copy of files that do not need to be processed gulp.task('copy', () => { return gulp.src('public/lib/**/*') .pipe(plumber()) .pipe(gulp.dest('dist/lib/')) }); // Start up service gulp.task('serve', ['node'],() => { browserSync.init({ proxy: 'localhost:3000', // Designated proxy url notify: false, // Refresh no pop-up prompt port: 3001, }); // Listen for less file compilation gulp.watch('public/stylesheets/**/*', ['less']).on('change', reload); gulp.watch('public/lib/**/*', ['copy']).on('change', reload); gulp.watch('public/images/**/*',['img']).on('change',reload); console.log('watching...'); }); gulp.task('default', () =>{ runSequence('clean', ['less', 'img', 'copy'], 'serve') });
Reference:
https://www.jianshu.com/p/2f923c8782c8
https://segmentfault.com/a/1190000016236780