preface

I have seen many tutorials before, such as vue’s scaffolding, Gulp’s scaffolding and Daniel’s own scaffolding. Discover that there is no silver bullet that can meet the needs of the company’s business and develop cool. Therefore, combined with the characteristics of the company’s business, I wrote a set of scaffolding suitable for our company by myself using GULP and Webpack.

Using range

  • Thematic static pages
  • Background logic business, front-end interaction and so on
  • Need to integrate ES6, SCSS, ESLint, etc

There are only three listed above. There’s a lot more to it.

Technology stack

  • webpack^3
  • Gulp – webpack ^ 1.5
  • Gulp – ^ 3.3 relation
  • 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

Of course, there are some other modules, but only a few main modules are listed here to explain the corresponding functions of the above modules. s

webpack

I personally hate webpack for doing things other than JS, including packing CSS,copy, etc. I don’t deny the power of Webpack, but I’d rather the industry specialize and webpack just do JS stuff. So webpack is responsible for es6-> ES5, esLint detection,js sourcemap file generation.

babel

This is not much to say, Babel also provides cli form, but this is integrated into Webpack.

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

These are used to handle sASS related issues, such as SASS compilation, CSS browser compatibility handling, CSS sourcemap correspondence.

browser-sync

Webpack also provides a static server and supports incremental refreshing, but HERE I chose to use Browser-sync to provide a static server. Browser-sync can quickly set up a static server and supports API level interface refresh. So I can easily call the page refresh function automatically or manually

eslint&eslint-config-alloy

The esLint detection configuration of Tencent Alloy team is used here, and I prefer this scheme.

gulp

Finally, gulP, all modules are led and glued together by GULP. Why do you say so? Since all modules don’t know when to call and when to do what they need to do, gulp.watch and gulp.src are used. Let’s do a quick example

/** ** listen on file ** / 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"]);
});
Copy the code

Execute tasks that listen for changes in certain files.

Use of

  1. Gulp-webpack compilation is recompiled every time

Gulp-webpack needs to be recompiled every time webpack is called, so it can take a long, long time. Fortunately, in personal tests, the incremental compilation time of webpack was 1s, while the compilation time of gulp-Webpack was around 2s-3s. If you are not particularly sensitive to time, you can ignore it. Of course, there is a solution to this problem, as suggested in a previous article, which is to use the proxy mechanism, the incremental compilation refresh of WebPack and the refresh of browserSync. This allows simultaneous refreshes and instead of using gulp-Webpack for recompilation, uses incremental compilation and static server functionality of Webpack. Of course, there is no research on how to achieve this but the conclusion can be drawn is not difficult.

  1. The puG, SASS file overload compiles extra files each time

What does that mean? Look at the code and talk

gulp.task("compile:sass", (event) => {
    return gulp.src('dev/sass/output/**/*.scss')
    //.pipe(changed("dist/css") disabled changed sass requires full compilation.. .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()
        })
});
Copy the code

In this case, all the SCSS files under output will be compiled each time. Similarly, puG compilation will compile all the PUGs under a folder. Of course, the solution is simple

Configuration files, yeah, and then use additional configuration files, like

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"];
letcopyJsPath=devConf.gulp.copyJsPath? devConf.gulp.copyJsPath:`/public/dist/js`;letcopyCssPath=devConf.gulp.copyCssPath? devConf.gulp.copyCssPath:`/public/dist/css`;letcopyImgPath=devConf.gulp.copyImgPath? devConf.gulp.copyImgPath:`/public/img`;Copy the code

Use additional configuration files to compile and load on demand

  1. How to distinguish prod from Dev.

This is actually quite simple and can be done using NPM run or using gulp’s multi-task approach

gulp.task('default::production'['set-env::production'.'watch']); /** * Set environment variables */ gulp.task('set-env::production',()=>{
    webpackEnv='production';
    return Promise.resolve(true);
});
Copy the code

Gulp default::production gulp default::production

    process.env.NODE_ENV = 'dev'||'prod';
Copy the code
  1. An error is reported to exit the mechanism

Gulp exits every time a gulp error occurs. For example, when you call gulp-webpack to compile JS, a JS error causes the entire gulp to exit

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()
        })
});

Copy the code

Webpack has an error notification function, so there is no need for gulp-plumber to report an error again. In this case, the errorHandler is defined as an empty function.

To improve the

So that’s basically the whole plan. The advantage of this approach is that HTML, CSS, and JS are separate and do not affect each other. HTML, CSS, and JS all use alternatives to facilitate development such as PUG for HTML (have you ever nested MORE than 10 layers of HTML?). CSS uses SASS, JS uses ES6, and the three can be quickly replaced and replaced. For example, when I don’t want to use PUG, I can quickly use EJS or other templates. I just need to change the Gulp task. One day WHEN I want to use Vue, all I need to do is change the webpack configuration file and increase the gulp.watch range. Does that sound powerful? Isn’t there a downside?

The answer is… There is no… Ha ha ha a little crazy. But in fact, there are still many problems, such as the performance of Webpack, in the case of large files will be compiled for a long time, will affect the development efficiency, this problem in the later stage is not to be ignored. Too much coupling is also a problem. All compilations rely on file directories for allocation, and if a directory changes a lot of things need to be changed again. And so on… But then slowly improve it, after all, from the beginning of their own scaffolding to now stable use in the company has also experienced reconstruction -> revision -> pull away -> abandon (?? What the hell).

Here is a vue2.0 demo