Gulp&Webpack搭建属于本身的特性化前端脚手架

前言

以前看了不少教程,好比vue的脚手架,gulp的脚手架和大牛本身写的脚手架。发现没有什么是银弹可以知足公司业务的须要又可以开发的爽。因此结合公司业务的特性,本身动手用gulp和webpack写了一套适合我司的脚手架。css

使用范围

  • 专题等静态页面多
  • 后台主导逻辑业务,前端主导交互等
  • 须要整合es6,scss,eslint等

上面只列出了三点。其实适用范围还有挺多。html

技术栈

  • webpack^3
  • gulp-webpack^1.5
  • gulp-pug^3.3
  • gulp^3.9
  • eslint^4
  • eslint-config-alloy^1.4
  • babel^6.5
  • gulp-postcss^6.2
  • autoprefixer^6.4
  • browser-sync^2.1
  • gulp-sass^2.3

固然还有一些就不一一列出了,这里只列出几个主要的模块 下面来解释一下上述模块对应的功能。s前端

webpack

我我的是比较讨厌webpack作除了js之外的事情,包括打包css,copy等。 我不否定webpack的强大,可是我仍是更但愿术业有专攻,webpack只负责js相关的事情就好。 因此webpack负责的范围为 es6->es5,eslint的检测,js的sourcemap文件的生成。vue

babel

这个没什么好说的,babel也提供了cli的形式,但这里整合进了webpack当中。webpack

gulp-sourcemaps&gulp-sass&gulp-postcss&autoprefixer

这些都是用来处理sass的相关,好比 sass的编译,css的浏览器兼容性处理,css的sourcemap对应。git

browser-sync

webpack也提供了静态服务器而且支持增量刷新,可是这里我选择使用browser-sync提供了静态服务器。 browser-sync能够快速的搭建起一个静态服务器而且支持api级别的接口刷新。因此我能够很方便的去自动或者手动调用刷新页面功能es6

eslint&eslint-config-alloy

这里使用的是腾讯alloy团队的eslint检测配置,我的比较喜欢此方案。github

gulp

最后说说gulp,全部的模块都是由gulp来主导而且粘合的。为何这么说。 由于全部的模块都不知道啥时候去调用啥时候去作该作的事情,那么这里就用到了gulp.watch和gulp.src。 简单来个例子web

/**
 *
 * 监听文件
 *
 */
gulp.task("watch", () => {
    let bs = browserSync.init({
        server: {
            baseDir: "./",
            directory: true,
        },
        open: false,
        ui: {
            port: 3008,
            weinre: {
                port: 3009
            }
        },
        port: devConf.gulp.webPort?devConf.gulp.webPort:3012,
        ghostMode: false
    });
    gulp.watch(["dev/jade-html/**/*.pug", "dev/jade-component/**/*.pug"], ["compile:pug"]);
    gulp.watch(["dev/js/**/*.js"], ["compile:js"]);
    gulp.watch(["dev/sass/**/*.scss"], ["compile:sass"]);
    gulp.watch(["dev/img/**/*.*", "dev/lib/**/*.*"], ["copy"]);
});
复制代码

比较简单,大意就是监听某些文件变更的时候执行对应的task。npm

使用问题

  1. gulp-webpack编译每次都是从新编译

gulp-webpack每次调用webpack都须要从新编译,因此时间会很长很长很长。其实还好 我的测试中,webpack增量编译时间为1s的话,gulp-webpack编译时间为2s-3s左右。若是对时间不是特别敏感的能够忽略。 固然这个问题仍是有解决方案的,也是以前看的某篇文章提出的 使用proxy机制, webpack的增量编译刷新调动browserSync的刷新。 这样一来能够作到同步刷新 而且不适用gulp-webpack来从新编译转而使用webpack的增量编译和静态服务器功能。固然具体怎么实现尚未研究 可是能够得出的结论就是 不难。

  1. pug,sass文件过多每次都编译出额外的文件

这个什么意思呢?看代码说话

gulp.task("compile:sass", (event) => {
    return gulp.src('dev/sass/output/**/*.scss')
    //.pipe(changed("dist/css")) disabled changed sass须要所有编译..
        .pipe(sourcemaps.init())
        .pipe(sass(sassOptions).on("error", sass.logError))
        .pipe(gulpif(extBase64File,base64({
            maxImageSize: 15*1024, // bytes 15KB
        })))
        .pipe(postcss([autoprefixer()]))
        .pipe(sourcemaps.write("./"))
        .pipe(gulp.dest("dist/css"))
        .pipe(gulp.dest(copyCssPath))
        .on("finish", () => {
            browserReload()
        })
});
复制代码

这里若是编译的话 每次都会把output下面全部的scss文件编译出来,同理 编译pug的时候也是同样会把某个文件夹下面的全部pug所有编译出来。固然解决办法也很简单

配置文件,没错,再使用额外的配置文件,好比

const devConf=require("./dev-conf");
let compilePugFile= devConf.gulp.compilePugFile?devConf.gulp.compilePugFile:["dev/jade-html/**/*.pug"];
let compileSassFile= devConf.gulp.compileSassFile?devConf.gulp.compileSassFile:["dev/sass/output/**/*.scss"];
let copyJsPath=devConf.gulp.copyJsPath?devConf.gulp.copyJsPath:`/public/dist/js`;
let copyCssPath=devConf.gulp.copyCssPath?devConf.gulp.copyCssPath:`/public/dist/css`;
let copyImgPath=devConf.gulp.copyImgPath?devConf.gulp.copyImgPath:`/public/img`;
复制代码

使用额外的配置文件来作到按需编译和加载

  1. prod和dev如何区分。

这个其实很简单 可使用npm run 也可使用gulp的多个任务方式

gulp.task('default::production',['set-env::production','watch']);

/**
 * 设置环境变量
 */
gulp.task('set-env::production',()=>{
    webpackEnv='production';
    return Promise.resolve(true);
});
复制代码

须要dev模式那么直接 gulp就好 须要生产模式就 gulp default::production 这里的设置变量能够经过process.env来设置,这样就能够在全局拿到参数了。

process.env.NODE_ENV = 'dev'||'prod';
复制代码
  1. 报错退出机制

gulp的每次报错都会致使gulp退出,好比调用gulp-webpack编译js的时候 某个js错误致使整个gulp退出, 固然解决办法也很简单

const plumber = require('gulp-plumber');
const webpackFile=require("./webpack.config.js");
gulp.task("compile:js", () => {
    return gulp.src("dev/js/main.js")
        .pipe(plumber({errorHandler:function () {
                
            }}))
        .pipe(webpack(webpackFile({env:webpackEnv})))
        .pipe(gulp.dest("dist/js/"))
        .pipe(gulp.dest(copyJsPath))
        .on("finish", () => {
            browserReload()
        })
});

复制代码

使用gulp-plumber即可以解决问题了, 由于webpack自带错误提示功能 因此不须要gulp-plumber再次报错, 这里就把errorHandler给定义了空函数不作处理。

改进

基本上说到这里整个方案就差很少了。 这一套方案的好处就是 html,css,js分离而且互不影响。 html,css,js都使用了代替品来方便开发 好比html使用了pug(说pug很差的同窗,大家有嵌套过10层以上的html吗?),css使用了sass,js使用了es6,而且三者能够快速替换和代替 好比 我哪天不想使用pug了 那么能够快速使用ejs等其余模板 只须要改改gulp的task, 哪天我想使用vue了 那么只须要改改webpack的配置文件,而且增长gulp.watch范围就能够了。 是否是听着很强大?难道就没什么弊端么?

答案是....没有...哈哈哈哈 有点狂。 不过其实仍是有不少问题的,好比webpack的性能,在文件量大的话 其实会编译的比较久,会影响开发效率,这个问题在后期是不可忽视的。 耦合过大也是个问题,全部的编译都是依靠文件目录来作分配的,若是某个目录变了那么不少东西都须要修改重来。 等等... 不事后面再慢慢改进吧,毕竟从一开始本身搭建脚手架到如今公司中稳定使用也经历了重构—>改版->抽离->放弃(???什么鬼)。

这里给出一个vue2.0的demo

相关文章
相关标签/搜索