您现在的位置是:亿华云 > 数据库

前端工程师:我用gulp4.0搭建一个前端脚手架

亿华云2025-10-03 20:41:02【数据库】1人已围观

简介本文将会介绍如何使用gulp4来搭建项目脚手架,如果您还在使用gulp3或更老的版本,您也以通过本文的一些思想将之前的项目进行完善,更新。如果gulp不是你们团队的重点,也可以移步我的Webpack4

本文将会介绍如何使用gulp4来搭建项目脚手架,前端如果您还在使用gulp3或更老的工程个前版本,您也以通过本文的师用手架一些思想将之前的项目进行完善,更新。搭建端脚如果gulp不是前端你们团队的重点,也可以移步我的工程个前Webpack4.0搭建文章.

前言

由于本文重点是介绍gulp4.0搭建脚手架的思路,相关插件的师用手架用法以及项目结构的设计,由于gulp的搭建端脚基本用法很简单,如果不熟悉可以移步官网自行研究学习。前端该脚手架的工程个前设计思路和功能如下:

 

同时为了提高开发环境的效率,这里我们参考webpack的师用手架配置,区分开发环境和生产环境,搭建端脚在接下来将会具体介绍。前端

脚手架用到的工程个前第三方插件介绍

gulp-jshint ——js语法检测 gulp-util ——终端控制台打印自定义错误信息 http-proxy-middleware ——设置代理,配合gulp-connect使用 gulp-less ——将less编译成css gulp-file-include ——用于文件模块化导入,师用手架如用include的方式导入公共部分 gulp-connect ——用于启动本地服务器 gulp-clean ——清理目录 gulp-uglify --压缩js gulp-minify-css ——压缩css gulp-autoprefixer ——自动添加浏览器前缀 imagemin-pngquant ——png图片压缩 gulp-imagemin ——图压缩 gulp-cache ——设置gulp打包的缓存,一般用于img gulp-md5-plus ——将文件名进行md5处理便于打包更新

当然gulp还有很多常用的源码下载插件可以更好的为我们的项目服务,大家也可以整合自己的插件让项目更加完善。

项目目录设计

1.src目录,即我们开发项目时的源目录,具体结构如下:

我们定义views是我们视图层,即页面文件的目录,js目录为业务逻辑的脚本文件,lib存放第三方框架,include目录为公共部分的存放目录,我们可以用gulp-file-include来导入到html中,images和css大家都比较清楚,分别时存放image和css文件的目录。

2. dist目录,即输出的目录,具体结构如下:

可以看到我们会看到src打包后的目录对应static目录,为什么我们会加一层static呢?我的设计是如果项目使用node等服务层框架,我们可以用gulp一并打包放入dist下,这样dist就是一个完整的包括前后端服务的亿华云项目目录了,当然大家也可以直接将src打包后的文件和文件夹直接放到dist下,根具业务需求灵活设计吧。

在这里我要说一点,由于笔者亲测gulp-md5-plus有时候打包不稳定,可能不会给html自动添加对应的md5后缀,所以笔者在这块做了特殊的处理,如果大家在工作中有更好的方案,可以及时和笔者沟通交流。

3. gulpfile文件配置

由于我们要区分开发环境和生产环境,所以这里我们使用两个不同的配置文件,根据NODE_ENV来区分用哪个文件。

我们将配置文件统一放到build目录下,config为公共配置文件,gulp.dev.js和gulp.prod.js分别为开发和生产环境配置文件。我们整体的目录结构如下:

脚手架完整源码(部分插件和配置会给出详细注释)

1 config.js

module.exports = {      dist: ./dist/static,  // 配置构建目录 } 

2 gulp.dev.js

const gulp = require(gulp); // js const Jshint = require("gulp-jshint");          //js检查 const Gutil = require(gulp-util); const Proxy = require(http-proxy-middleware); // const Webpack = require(webpack); // const WebpackConfig = require(./webpack.config.js); // css const Less = require(gulp-less);              // 编译less // html const FileInclude = require(gulp-file-include); // 文件模块化 // server const Connect = require(gulp-connect);        //引入gulp-connect模块  const Clean = require(gulp-clean);            // 清理目录 // 配置文件 const config = require(./config); const {  dist } = config; // html async function html() {      return gulp.src(src/views/*.html)         .pipe(FileInclude({  // HTML模板替换,具体用法见下文             prefix: ##,             basepath: @file         })).on(error, function(err) {              console.error(Task:copy-html,, err.message);             this.end();         })         .pipe(gulp.dest(dist)) // 拷贝          .pipe(Connect.reload()) } // css async function css() {      return await gulp.src(src/css/*.less)     .pipe(Less())       //编译less     .pipe(gulp.dest(dist + /css)) //当前对应css文件     .pipe(Connect.reload());//更新 } // js // const compilerJS = Webpack(WebpackConfig); async function js() {      return await gulp.src(src/js/**)     .pipe(Jshint())//检查代码     // .pipe(Babel({      //     presets: [es2015]     // }))     .on(error, function(err) {          Gutil.log(Gutil.colors.red([Error]), err.toString());     })     .pipe(gulp.dest(dist + /js)) // 拷贝     .pipe(Connect.reload()); //更新     // 使用es6+可以单独配置     // compilerJS.run(function(err, stats) {      //     if(err) throw new Gutil.PluginError("webpack:js", err);     //     Gutil.log("[webpack]", stats.toString({      //         colors: true     //     }));     //     cb()     // }); } // image async function image() {      return await gulp.src(src/images/*)     .pipe(gulp.dest(dist + /images)); } // clean dir async function clean() {      // 不设置allowEmpty: true会报File not found with singular glob     return await gulp.src(dist, { allowEmpty: true}).pipe(Clean()); } // 服务器函数 async function server() {      Connect.server({          root:dist, //根目录         // ip:192.168.11.62,//默认localhost:8080         livereload:true, //自动更新         port:9909, //端口         middleware: function(connect, opt) {              return [                 Proxy(/api, {                      target: http://localhost:8080,                     changeOrigin:true                 }),                 Proxy(/otherServer, {                      target: http://IP:Port,                     changeOrigin:true                 })             ]         }     }) } module.exports = {      html,     css,     js,     image,     clean,     server } 

3 gulp.prod.js

const gulp = require(gulp); // const Rename = require(gulp-rename);          // 重命名 // js const Uglify = require(gulp-uglify);          // 压缩js // const Babel = require(gulp-babel); // css const Minifycss = require(gulp-minify-css);   // 压缩css const Less = require(gulp-less);              // 编译less const Autoprefixer = require(gulp-autoprefixer);  // 浏览器前缀 // html const MinifyHtml = require("gulp-minify-html"); //压缩html const FileInclude = require(gulp-file-include); // 文件模块化 // image const Imagemin = require(gulp-imagemin); const Pngquant = require(imagemin-pngquant);  //png图片压缩插件 const Cache = require(gulp-cache);  const Clean = require(gulp-clean);            // 清理目录 // md5 发版本的时候为了避免浏览器读取了旧的缓存文件,需要为其添加md5戳 const md5 = require("gulp-md5-plus"); const config = require(./config); const {  dist } = config; // html async function html() {      return gulp.src(src/views/*.html)         .pipe(FileInclude({  // HTML模板替换,具体用法见下文             prefix: ##,             basepath: @file         }))         // .pipe(MinifyHtml())         .on(error, function(err) {              console.error(Task:copy-html,, err.message);             this.end();         })         .pipe(gulp.dest(dist)) // 拷贝  } // css async function css() {      return await gulp.src(src/css/**)     .pipe(Less())       //编译less     .pipe(Autoprefixer({          cascade: true, //是否美化属性值 默认:true 像这样:         //-webkit-transform: rotate(45deg);         //        transform: rotate(45deg);         remove: true //是否去掉不必要的前缀 默认:true     }))     .pipe(Minifycss({    // 压缩css         //类型:Boolean 默认:true [是否开启高级优化(合并选择器等)]         advanced: true,         //保留ie7及以下兼容写法 类型:String 默认:or* [启用兼容模式; ie7:IE7兼容模式,ie8:IE8兼容模式,*:IE9+兼容模式]         compatibility: ,         //类型:Boolean 默认:false [是亿华云计算否保留换行]         keepBreaks: false,         //保留所有特殊前缀 当你用autoprefixer生成的浏览器前缀,如果不加这个参数,有可能将会删除你的部分前缀                 keepSpecialComments: *     }))     .pipe(gulp.dest(dist + /css))     .pipe(md5(10, dist + /*.html, {          mappingFile: manifest.json,         connector: . // 文件名和hash的连接符     }))     .pipe(gulp.dest(dist + /css)) //当前对应css文件 } // js async function js() {      return await gulp.src(src/js/**)     // .pipe(Babel({      //     presets: [es2015]     // }))     .pipe(Uglify()) // 压缩js     .pipe(gulp.dest(dist + /js))     .pipe(md5(10, dist + /*.html, {          mappingFile: manifest.json,         connector: .     }))     .pipe(gulp.dest(dist + /js)) // 拷贝 } // image async function image() {      return await gulp.src(src/images/*)     .pipe(Cache(Imagemin({          optimizationLevel: 5, //类型:Number  默认:3  取值范围:0-7(优化等级)         progressive: true, //类型:Boolean 默认:false 无损压缩jpg图片         interlaced: true, //类型:Boolean 默认:false 隔行扫描gif进行渲染         multipass: true, //类型:Boolean 默认:false 多次优化svg直到完全优化         svgoPlugins: [{ removeViewBox: false}],//不要移除svg的viewbox属性         use: [Pngquant()] //使用pngquant深度压缩png图片的imagemin插件     })))     .pipe(gulp.dest(dist + /images)); } // clean dir async function clean() {      // 不设置allowEmpty: true会报File not found with singular glob     return await gulp.src(dist, { allowEmpty: true}).pipe(Clean()); } module.exports = {      html,     css,     js,     image,     clean } 

4 gulpfile.js

const gulp = require(gulp); // 根据环境引入不同的配置文件 let buildConfig; if(process.env.NODE_ENV === dev) {      buildConfig = require(./build/gulp.dev);     gulp.task(server, buildConfig.server);  // 本地服务 } else {      buildConfig = require(./build/gulp.prod);     // gulp.task(md5, gulp.series(buildConfig.md5Css, buildConfig.md5Js));     gulp.task(clean, buildConfig.clean);    // 清理目录    } gulp.task(html, buildConfig.html);      // 打包html gulp.task(js, buildConfig.js);          // 打包js gulp.task(css, buildConfig.css);        // 打包css gulp.task(images, buildConfig.image);   // 打包image gulp.task(sources, gulp.series(html, gulp.parallel(js, css, images))); // 监听文件变化 gulp.task(watch, async () => {      gulp.watch(src/views/*, gulp.series(html)); // 监听HTML变化     gulp.watch(src/js/**, gulp.series(js)); // 监听js变化     gulp.watch(src/css/*, gulp.series(css)); // 监听css变化     gulp.watch(src/images/*, gulp.series(images)); // 监听image变化 }); // build if(process.env.NODE_ENV === dev) {      gulp.task(dev, gulp.series(sources, server, watch)); } else {      gulp.task(build, gulp.series(sources)); } 

5 package.json

{    "dependencies": {      "@babel/core": "^7.4.5",     "babel-preset-es2015": "^6.24.1",     "gulp": "^4.0.2",     "gulp-autoprefixer": "^6.1.0",     "gulp-babel": "^8.0.0",     "gulp-cache": "^1.1.2",     "gulp-clean": "^0.4.0",     "gulp-connect": "^5.7.0",     "gulp-file-include": "^2.0.1",     "gulp-imagemin": "^6.0.0",     "gulp-jshint": "^2.1.0",     "gulp-less": "^4.0.1",     "gulp-md5-plus": "^1.0.3",     "gulp-minify-css": "^1.2.4",     "gulp-minify-html": "^1.0.6",     "gulp-rename": "^1.4.0",     "gulp-uglify": "^3.0.2",     "gulp-util": "^3.0.8",     "http-proxy-middleware": "^0.19.1",     "http-server": "^0.11.1",     "imagemin-pngquant": "^8.0.0",     "jshint": "^2.10.2",     "jsonfile": "^5.0.0",     "webpack": "^4.35.2"   },   "scripts": {      "start": "NODE_ENV=dev gulp dev",     "build": "NODE_ENV=prod gulp clean && gulp build",     "serve": "http-server dist/static -p 3000"   },   "devDependencies": { } } 

要想获取项目完整源码和demo,请移步gulp4_multi_pages。

最后 

该脚手架任然有需要完善的地方,比如如何兼容uglify和babel,md5需要使用两次的情况,如果更好的解决方案,欢迎随时交流。在脚手架选型上,也不一定非要用gulp,webpack,一般的经验是传统型的静态网站适合用gulp,由于不需要编译es6,所以有更小的体积,当然也可以用webpack,本文主要是给大家提供一使用gulp4搭建个脚手架的思路,希望能有所收获。

很赞哦!(4)