express搭建网站的时候需要优化资源加载速度,减少服务器资源消耗 例如:样式使用less分模块编写,最后我们需要将less编译成css, 并且合并编译后的文件.
虽然express有插件可以编译less,但是这样会占用服务端资源,每次访问的时候需要先编译. 这些静态资源我希望直接引用. 使用express编译后还有一个问题是less文件虽然被编译成css, 但是后缀名依旧为.less, 这对有强迫症的同学简直是一种折磨.
我这里使用gulp帮助我解决这些问题,webpack太庞大,学习成本太高,其他编译工具没看过,因此只能选择gulp了.
这里我们需要解决这样几个问题(完整代码见文末):
前三个问题其实比较好解决, 直接引入对应的编译压缩插件然后创建task, 最后运行即可
const less = require('gulp-less');
const minify = require('gulp-clean-css');
const concat = require('gulp-concat');
const imagemin = require('gulp-imagemin');
// less编译+压缩
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/'))
});
// 压缩img
gulp.task('img', () => {
return gulp.src('public/images/**/*')
//压缩图片
.pipe(plumber())
.pipe(imagemin({optimizationLevel: 3, progressive: true, interlaced: true}))
.pipe(gulp.dest('dist/images/'))
});
比较复杂一点的是第四个问题, 这里需要会使用browser-sync
, gulp-nodemon
, 原先项目启动直接从express中启动,这里需要在gulp文件中启动项目,因为这样可以在项目启动的时候做一些特殊处理, 这里browser-sync服务代理了express服务地址,原先的localhost:3000会变成localhost:3001
const browserSync = require('browser-sync').create();
const reload = browserSync.reload;
const nodemon = require('gulp-nodemon');
// 启动express
gulp.task('node', ()=>{
nodemon({
script: './bin/www',
ext: 'js html css',
env: { 'NODE_ENV': 'development' }
})
})
// 启动服务
gulp.task('serve', ['node'],() => {
browserSync.init({
proxy: 'localhost:3000', // 指定代理url
notify: false, // 刷新不弹出提示
port: 3001, // 端口
});
// 监听
gulp.watch('public/stylesheets/**/*', ['less']).on('change', reload);
gulp.watch('public/lib/**/*', ['copy']).on('change', reload);
gulp.watch('public/images/**/*',['img']).on('change',reload);
});
最后我们需要执行定义的这些任务, 解决一些可能存在的错误导致监听停止, 并且添加了一个clean方法, 在每次启动的时候都会清除dist文件内容,重新生成新的内容,需要注意的是clean方法必须最先执行.
const runSequence = require('run-sequence'); // 顺序执行task任务
const plumber = require('gulp-plumber'); // 有错误不停止监听程序
// 删除文件
gulp.task('clean', async () => {
await del(['dist/']);
});
gulp.task('default', () =>{
runSequence('clean', ['less', 'img', 'copy'], 'serve')
});
完整代码如下
// 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'); // 顺序执行task任务
const plumber = require('gulp-plumber'); // 有错误不停止程序
// 启动express
gulp.task('node', ()=>{
nodemon({
script: './bin/www',
ext: 'js html css',
env: { 'NODE_ENV': 'development' }
})
})
// 删除文件
gulp.task('clean', async () => {
await del(['dist/']);
});
// less编译+压缩
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/'))
});
// 压缩img
gulp.task('img', () => {
return gulp.src('public/images/**/*')
//压缩图片
.pipe(plumber())
.pipe(imagemin({optimizationLevel: 3, progressive: true, interlaced: true}))
.pipe(gulp.dest('dist/images/'))
});
// 不需要处理的文件直接复制
gulp.task('copy', () => {
return gulp.src('public/lib/**/*')
.pipe(plumber())
.pipe(gulp.dest('dist/lib/'))
});
// 启动服务
gulp.task('serve', ['node'],() => {
browserSync.init({
proxy: 'localhost:3000', // 指定代理url
notify: false, // 刷新不弹出提示
port: 3001,
});
// 监听less文件编译
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')
});
文章参考:
https://www.jianshu.com/p/2f923c8782c8
https://segmentfault.com/a/1190000016236780