While learning about WebPack, I also thought of a small tool I used before, gulp. It’s amazing how similar the two are actually able to do. CSS, JS, TS translation, and listening for file changes seem to do much the same thing.

They can do the same thing to some extent, but not without differences.

Both Webpack and gulp run based on configuration files and custom processes. One is defined as a packaging tool and one is defined as a Task Runner.

Difficulty: Elementary

Last Updated:

– the 2019-11-30

How to run webPack and TSC type checking at the same time

First, preconditions

entry version
OS Windows 10 20H2 Enterprise
node -v v14.15.0
npm -v 6.14.8
vscode V1.51.1 (2020-11-10)

Start by installing gulp.

npm install --save-dev gulp
Copy the code

Gulp tasks are usually stored in a gulpfile.js file in the root directory, or in a folder with the same name if you split the gulp tasks into different files. The root Task is in /gulpfile.js/index.js. [API Concepts | gulp. Js] (% 5 bmenu % 5 d (gulpjs.com/docs/en/api…).

Update: Today go to gulp Github to see gulpjs/gulp: A Toolkit to Automate & Enhance your Workflow (github.com), dude, as of 2020-11-14, this has not been updated for A year and A half.

Second, Task sample writing

Task Writing example 1. CSS mobile adaptation from PX to VW

Simple requirements:

  • Use VW adaptation scheme for mobile end adaptation
  • Compress CSS

For the implementation of VW adaptation scheme, I use postCSS and postCSS-px-to-viewport to achieve.

The need to compress CSS was implemented using gulp-clean-CSS (there was also talk of using gulp-minify-CSS extension on the web, but this extension is now deprecated, gulp-clean-CSS is preferred).

Step 1: Install dependencies first

npm i --save-dev gulp-clean-css, gulp-postcss, postcss-px-to-viewport
Copy the code

Step 2: Write Gulp tasks in gulpfile.js

const {
    src,
    dest
} = require('gulp');

const postcss = require('gulp-postcss');
const pxtoviewport = require('postcss-px-to-viewport');
const cleanCSS = require('gulp-clean-css');

/** * translate CSS: convert px units to vw units, compress CSS files */
const transpileCSS = () = > {
    const processors = [pxtoviewport({
      // The window width is the same as the design drawing
      viewportWidth: 750.// The precision is four decimal places
      unitPrecision: 4.// Window width
      viewportUnit: 'vw'
    })];

    return src(['css/**/*.css'] and {sourcemaps: true
        })
        // translate px units to vw units
        .pipe(postcss(processors))
        // Compress CSS files: remove comments, extra Spaces, empty lines, etc
        .pipe(cleanCSS())
        // Build to build/ CSS directory
        .pipe(dest('build/css'));
};

/ / export CSS
exports.css = transpileCSS;
Copy the code

As you can see, the basic scripting for gulp is to write a function that returns a build pipe.

Pipe is a concept that should be familiar to anyone who has studied Linux

The effect is to pass the output of the previous command to the next command as input. Here, too, the process is as follows

src -> postcss -> cleancss -> dist
Copy the code

SRC is extracted to the corresponding file stream and passed to PostCSS for processing. Postcss then passes its own file stream to CleancSS. Finally, CleancSS also processes the file and gives it to dest method to generate the file at the specified location.

The concept of flow is also used. The following several tasks were written at the same pace.

Console Execution command

The parameter after # NPX gulp is the name of the task location, which gulp uses to find the task script
npx gulp css
Copy the code

JS translation and compression

Requirements:

  • ADAPTS to older browsers
  • Compressed JS code

For JS translation, I used the Babel translation tool so that we could use the latest syntax without worrying about adapting to older browsers. Use uglifyJS to do JS compression.

Step 1: Install the required packages first

npm i --save-dev gulp-babel, @babel/preset-env, @babel/core, gulp-uglify
Copy the code

Step 2: Write the gulp command

const {
    src,
    dest
} = require('gulp');
const babel = require('gulp-babel');
const uglify = require('gulp-uglify');

/** * Translate and compress js code */
const transpileJS = () = > {
    // Get all.js files under app/static/scripts.
    return src(['js/**/*.js'] and {ignore: ['js/lib/**/*.js'].sourcemaps: true
        })
        // Convert ES6 code into executable JS code
        .pipe(babel())
        / / js compressed
        .pipe(uglify())
        // Output the compressed file to build/js (automatically generate dist directory if there is no dist directory)
        .pipe(dest('build/js'));
}


exports.js = transpileJS;
Copy the code

Create a.babelrc file in the root directory of the project and configure Babel. The following uses the Babel default configuration

{
    "presets": [["@babel/preset-env", {
            "loose": true."modules": false}}]]Copy the code

Step 4: Run the script on the console

npx gulp js
# check if there are any generated js files in the build/js directory
Copy the code

Update: You can see that both gulp and Webpack can call Babel to translate JS, and the functionality is somewhat similar. The difference is that GULP is procedural.

Now we can translate JS.

3, listen for file changes, and automatically compile

Listening file modification requires the watch() method in gulp, passing in the listening file and the task function.

const watchModify = () = > {
    watch(['css/**/*.css'], transpileCSS);
    watch(['js/**/*.js'], transpileJS);
}

exports.watch = watchModify;
Copy the code

Command line run:

npx gulp watch
Copy the code

If we modify the CSS /**/*.css or js/**/*.js file, it will trigger its automatic translation.

4. Asynchronous Task

The official documentation

const { watch, series } = require('gulp');

function clean(cb) {
  // body omitted
  cb();
}

function javascript(cb) {
  // body omitted
  cb();
}

function css(cb) {
  // body omitted
  cb();
}

exports.default = function() {
  // You can use a single task
  watch('src/*.css', css);
  // Or a composed task
  watch('src/*.js', series(clean, javascript));
};
Copy the code

Asynchronous tasks, with a callback function as the return value, call this callback to indicate that the task has executed successfully.

Sequential execution and parallel execution of Task combinations

Put the above examples together to form the following (the long line below is not important, but the bottom lines are important) :

const { parallel, series, src, watch, dest, } = require('gulp'); // postcss-px-to-viewport // https://github.com/evrone/postcss-px-to-viewport const postcss = require('gulp-postcss'); const pxtoviewport = require('postcss-px-to-viewport'); const cleanCSS = require('gulp-clean-css'); // gulp-babel const babel = require('gulp-babel'); const uglify = require('gulp-uglify'); const replace = require('gulp-replace'); const processorsConfig = require('./postcss.config').plugins['postcss-px-to-viewport']; const fs = require('fs'); /** ** @param {function} done indicates that the task is finished */ const displayInfo = (done) => {try {const data = fs.readFileSync('./package.json'); const info = JSON.parse(data.toString()); console.log(`${info.name}@${info.version}`); } catch (e) { console.error(e); } done(); }; /** * postcss CSS * @param {function} cb callback function to be done */ const transpileCSS = () => {const processors = [ pxtoviewport(processorsConfig), ]; return src(['css/**/*.css'], { sourcemaps: true, }) .pipe(postcss(processors)) .pipe(cleanCSS()) .pipe(dest('build/css')); }; /** * Create a task named js * @returns stream line */ const transpileJS = () => SRC (['js/**/*.js'], ['js/lib/**/*.js'], sourcemaps: ['js/lib/**/*. true, }) // convert ES6 code into executable JS code.pipe (Babel ()) // JS compressed.pipe (uglify()) // Pipe (dest('build/js')); pipe(dest('build/js'); dist/static/scripts const moveJsLib = () => src(['js/lib/**/*.js']).pipe(dest('build/js/lib')); const watchModify = () => { watch(['css/**/*.css'], transpileCSS); watch(['js/**/*.js'], transpileJS); }; const buildJS = () => src(['js/**/*.js'], { ignore: ['/js/lib / * * *. Js'],}) pipe (Babel ()) / / ES6 code translated into executable javascript code. The pipe (uglify ()) / / js compressed pipe (dest (' dist/js')); Dist /static/scripts const buildCSS = () => {const processors = [ pxtoviewport(processorsConfig), ]; return src(['css/**/*.css']) .pipe(replace('/images/', '/static/wap/images/')) .pipe(postcss(processors)) .pipe(cleanCSS()) .pipe(dest('dist/css')); }; Const buildHtml = () = > SRC ([' view / / *. * * HTML]) / / omit intermediate process pipe (dest (' dist/view ')); const moveJsLib2Dist = () => src(['js/lib/**/*.js']).pipe(dest('dist/js/lib')); Const moveImgs = () = > SRC (' images / / * * *. * ') / / omit intermediate process pipe (dest (' dist/images')); exports.css = transpileCSS; exports.js = transpileJS; exports.watch = series(moveJsLib, transpileCSS, transpileJS, watchModify); exports.build = series( displayInfo, parallel(buildCSS, buildJS, buildHtml, moveImgs, moveJsLib2Dist), ); exports.default = parallel(transpileCSS, transpileCSS);Copy the code

You can see that the bottom lines use functions that we haven’t covered yet

series()    // Execute sequentially, incoming tasks
parallel()  // Execute in parallel, incoming tasks
Copy the code

Interestingly, the two scripts can be nested within each other, as shown in line 4 from last.

Update: Task writing example 6, using Babel to translate TS with Webpack

This section links to the configuration described in yesterday’s blog post

Webpack, Babel, ESLint,typescript, Simple starter configuration for KOA server Applications (juejin. Im)

Requirements:

  • Ability to compile typescript code

  • If there is a TS error during compilation, it can prompt an error

Prerequisites:

  • Json has been set to true for compileroptions. noEmit

  • Presets and plug-ins for Babel translation TS have been configured

  • You can already use webPack’s plug-in babel-Loader to call Babel and translate typescript

    All three can be found in the last blog post: WebPack, Babel, ESLint,typescript, Simple Starter Configuration for KOA server Applications (juejin. Im)

Install the necessary dependencies webpack-stream-npm (npmjs.com)

npm install --save-dev webpack-stream gulp-typescript
Copy the code

Then write the gulp task:

/* eslint-disable global-require */
const {
  src, dest, watch, parallel,
} = require('gulp');
const webpack = require('webpack-stream');
const ts = require('gulp-typescript');

const tsProject = ts.createProject('tsconfig.json', {
  noEmit: true});// Check the typescript type
function checkTypes() {
  return tsProject.src()
    .pipe(tsProject())
    .js
    .pipe(dest('. '));
}

// Call Webpack to compile the project code, and then you can manipulate it
function runWebpack() {
  return src('src/**/*.ts')
    // You can pass in webPack configuration objects, or you can pass in configuration files directly
    .pipe(webpack(require('./webpack.config.js')))
    .pipe(dest('dist/'));
}
// Listen for changes
function watchModify() {
  watch('src/**/*.ts', parallel(checkTypes, runWebpack));
}

exports.default = runWebpack;
exports.dev = watchModify;
exports.checkTypes = checkTypes;
Copy the code

These functions enable you to open the listener service from a command line, check the TS type and run the Webpack package

npx gulp dev
Copy the code

By the end, the task flow looks something like this

(MDZZ [wipe sweat]) hahahaha.

Third, other

  • Common command line parameters can be viewed by entering gulp –help.

  • A lot of work can be done with gulp + Webpack, and when configured, developers need to enter only a few commands, which makes developers somewhat more efficient.

  • How much efficiency is improved is a matter of opinion. React, Vue, WebPack, Babel, NodeJS, and other framework libraries. This era of unprecedented prosperity, new technology emerged in an endless stream. It is a considerable mental burden. It’s really hard to tell whether that makes it more efficient or less efficient.

If it helps, I really appreciate your likes. There have been some mistakes and superficial places in the text, I also welcome your correction.