前端进阶之路-三、如何用gulp搭建一套web前端开发框架(3)
导读
首先,我们将安装下面一系列的插件:
gulp-postcss //模块打包postcss-load-config //加载 .postcssrc.jsgulp-connect //websock更新文件刷新浏览器gulp-plumber //避免出错task终止minimist // 用于命令行传参数gulp-if // 条件控制输出gulp-newer //增量更新gulp-babel // ES6以上语法转ES5gulp-tinypng-nokey //免key图片压缩opn //打开浏览器del //删除文件夹
cnpm install gulp-postcss postcss-load-config gulp-connect gulp-plumber minimist gulp-if gulp-newer gulp-babel gulp-tinypng-nokey opn del --save
01
将项目在浏览器中跑起来
那么我们先从第一步开始,利用nodeJS将项目运行起来。在根目录下创建个utils.js文件。
const os = require('os');const net = require('net');const host = showObj(os.networkInterfaces());const getPort = async function () {const a = await getPortPromise();console.log(a)return a}function getPortPromise() {return new Promise((resolve) => {portIsOccupied(1234);function portIsOccupied(port) {// 创建服务并监听该端口var server = net.createServer().listen(port, host);server.on('listening', function () { // 执行这块代码说明端口未被占用server.close() // 关闭服务resolve(port)})server.on('error', function (err) {if (err.code === 'EADDRINUSE') { // 端口已经被使用port += 1;portIsOccupied(port);}})}})}// 获取本地IP地址function showObj(obj) {for (var devName in obj) {var iface = obj[devName];for (var i = 0; i < iface.length; i++) {var alias = iface[i];if (alias.family === 'IPv4' && alias.address !== '127.0.0.1' && !alias.internal) {return alias.address;}}}}module.exports = {host,getPort}
const { host } = require('./utils');const Config = {connect: {root: 'dist', //运行目录livereload: true,port: 1234, //端口号host}};module.exports = Config;
const Config = require('./config');const { getPort } = require('./utils');// 命令行传参数const knownOptions = {string: 'env',default: { env: process.env.NODE_ENV || 'production' }};const options = minimist(process.argv.slice(2), knownOptions);// 检查端口冲突const checkPort = async () => {Config.connect.port = await getPort();};// 开启文件服务器const openServer = async () => await connect.server(Config.connect);// 自动打开浏览器const openBrowser = async () => {const { host, port } = Config.connect;const url = `http://${host}:${port}/view`;opn(url);};
const prodbuild = gulp.series(checkPort,gulp.parallel(openServer, htmls, styles, images, scripts), //并行运行openBrowser);
cnpm install @babel/core --save
02
实现自动打包并同步刷新
我们接着讲第二步,如何在修改代码保存后,自动打包到dist文件夹中,并实现浏览器同步刷新。
// HTML文件const htmls = () => {return gulp.src('src/view/**/*.html').pipe(changed('src/view/**/*.html')).pipe(plumber()).pipe(gulp.dest('dist/view/')).pipe(connect.reload());};// CSS文件const styles = () => {return gulp.src('src/css/**/*.styl').pipe(changed('src/css/**/*.styl')).pipe(plumber()).pipe(stylus()).pipe(cleanCss()).pipe(gulp.dest('dist/css/')).pipe(connect.reload());};// 图片文件const images = () => {return gulp.src('src/images/**/*').pipe(changed('src/images/**/*')).pipe(plumber()).pipe(gulp.dest('dist/images/')).pipe(connect.reload());};// JS文件const scripts = () => {return gulp.src('src/js/**/*.js').pipe(changed('src/js/**/*.js')).pipe(plumber()).pipe(uglify()).pipe(gulp.dest('dist/js/')).pipe(connect.reload());};//检测文件是否有更新const watchFiles = () => {gulp.watch('src/view/**/*.html', htmls); //检测到html文件更新,更新版本号gulp.watch('src/css/**/*.styl', styles);gulp.watch('src/images/*', images);gulp.watch('src/js/**/*.js', scripts);};
const prodbuild = gulp.series(checkPort,gulp.parallel(openServer, htmls, styles, images, scripts),openBrowser,watchFiles);
04
请图片压缩和JS语法转换
// 图片压缩const imgTiny = () => {return gulp.src('src/images/**/*').pipe(changed('src/images/**/*')).pipe(tinypng_nokey()).pipe(gulp.dest('dist/images/')).pipe(connect.reload());}// JS文件const scripts = () => {return gulp.src('src/js/**/*.js').pipe(changed('src/js/**/*.js')).pipe(plumber()).pipe(babel()) //ES6转换.pipe(uglify()).pipe(gulp.dest('dist/js/')).pipe(connect.reload());};
const prodbuild = gulp.series(checkPort,gulp.parallel(openServer, htmls, styles, imgTiny, scripts),openBrowser,watchFiles);
cnpm install @babel/preset-env --save
{"presets": ["@babel/env"]}
03
将项目打包输出
第三步是将项目输出到生产环境build目录下。这步看起来不是很好理解,我们可以回到这篇的头部第一短话,就明白了。
const gulp = require('gulp');const stylus = require('gulp-stylus');const uglify = require('gulp-uglify');const cleanCss = require('gulp-clean-css');const postcss = require('gulp-postcss');const postcssrc = require('postcss-load-config');const connect = require('gulp-connect');const plumber = require('gulp-plumber'); // 避免出错task终止const minimist = require('minimist'); // 用于命令行传参数const gulpif = require('gulp-if'); // 用于命令行传参const cleanCSS = require('gulp-clean-css'); // 缩小css文件const changed = require('gulp-newer'); // 增量更新const babel = require('gulp-babel');const tinypng_nokey = require('gulp-tinypng-nokey'); //压缩图片--免keyconst opn = require('opn'); // 开启浏览器const del = require('del'); // 删除dist文件夹const { getPort } = require('./utils');const Config = require('./config');// 命令行传参数const knownOptions = {string: 'env',default: { env: process.env.NODE_ENV || 'production' }};const options = minimist(process.argv.slice(2), knownOptions);// 检查端口冲突const checkPort = async () => {Config.connect.port = await getPort();};// 开启文件服务器const openServer = async () => await connect.server(Config.connect);// 自动打开浏览器const openBrowser = async () => {const { host, port } = Config.connect;const url = `http://${host}:${port}/view`;opn(url);};// HTML文件const htmls = () => {return gulp.src('src/view/**/*.html').pipe(changed('src/view/**/*.html')).pipe(plumber()).pipe(gulp.dest('dist/view/')).pipe(connect.reload());};// CSS文件const styles = () => {return gulp.src('src/css/**/*.styl').pipe(changed('src/css/**/*.styl')).pipe(plumber()).pipe(stylus()).pipe(gulpif(options.env === 'production', cleanCSS())).pipe(gulp.dest('dist/css/')).pipe(connect.reload());};// 图片文件const images = () => {return gulp.src('src/images/**/*').pipe(changed('src/images/**/*')).pipe(plumber()).pipe(gulp.dest('dist/images/')).pipe(connect.reload());};// 图片压缩const imgTiny = () => {return gulp.src('src/images/**/*').pipe(changed('src/images/**/*')).pipe(tinypng_nokey()).pipe(gulp.dest('dist/images/')).pipe(connect.reload());}// JS文件const scripts = () => {return gulp.src('src/js/**/*.js').pipe(changed('src/js/**/*.js')).pipe(plumber()).pipe(babel()) //ES6转换.pipe(gulpif(options.env === 'production', uglify())).pipe(gulp.dest('dist/js/')).pipe(connect.reload());};//检测文件是否有更新const watchFiles = () => {gulp.watch('src/view/**/*.html', htmls); //检测到html文件更新,更新版本号gulp.watch('src/css/**/*.styl', styles);gulp.watch('src/images/*', images);gulp.watch('src/js/**/*.js', scripts);};// 删除dist目录const clean = () => {return del(['dist']);};// 开发环境-不压缩JS、css和图片const devbuild = gulp.series(checkPort,gulp.parallel(openServer, htmls, styles, imgTiny, scripts),openBrowser,watchFiles);// 生产环境-不运行服务、不开启浏览器、代码压缩和图片压缩const prodbuild = gulp.series(clean,gulp.parallel(htmls, styles, imgTiny, scripts),);gulp.task('dev',devbuild); //开发环境运行命令gulp.task('build', prodbuild); // 生产环境打包命令const build = options.env === 'production' ? prodbuild : devbuild; //判断是开发环境还是生产环境gulp.task('dev',build);
gulp dev --env development //开发环境gulp dev --env production //生产环境
gulp dev --env build
以上就是这篇的全部内容了,或许有点长,但是花费点时间能学到东西,相信还是值得的。
得到了再失去,总比从来就没有得到更伤人。
--《追风筝的人》
