• This is my first blog post
  • The relevant code covered in this article

Since the release of WebPack4, I have written projects using scaffolding, even for simple projects, really shame. While there was a lot of hearsay about webpack4 features, nothing was tried because it had the feel of em… It is very difficult. But today I started with the easy part, building a project piece by piece.

0 configuration, what is configured

Let’s start from 0 and create a new project that executes the following statement at the terminal:

mkdir webpack-4-quickstart && cd webpack-4-quickstart
npm init -y
npm i webpack --save-dev
npm i webpack-cli --save-dev
Copy the code

Modify the scripts section of package.json code:

"scripts": {
  "build": "webpack"
}
Copy the code

Now, our package.json looks like this:

{
  "name": "webpack-4-quickstart"."version": "1.0.0"."description": ""."main": "index.js"."scripts": {
     "build": "webpack"
  },
  "keywords": []."author": ""."license": "ISC"."devDependencies": {
    "webpack": "^ 4.14.0"."webpack-cli": "^ 3.0.8"}}Copy the code

At this point, we run NPM run build and get the following prompt/error:

  1. Error: There is no entry file
  2. Warning: The value is recommendedmodeoptions

entry & output

To solve the first problem, we try creating a new SRC /index.js:

console.log(`I'm a entry point`);
Copy the code

Dist /main.js is successfully packaged by executing NPM run build again, so we can see:

Webpack4 more configure entry (entry) SRC /index.js and output (exit) dist/main.js

Of course, if you want to override this configuration (e.g. change it to./foo/ SRC /js/index.js), you can change it in package.json:

"scripts": {
  "dev": "webpack --mode development ./foo/src/js/index.js --output ./foo/main.js"."build": "webpack --mode production ./foo/src/js/index.js --output ./foo/main.js"
}
Copy the code

production & development

Before webpack4, we used to set up at least two types of files when writing a project:

  • Webpack.dev.conf.js for the development environment, the server that defines the webpack startup, etc
  • Webpack.prod.conf.js for production environment, define UglifyJSPlugin or other configuration etc

Webpack4 mode provides two configurations: development and production.

We modify the scripts part of package.json:

"scripts": {
  "dev": "webpack --mode development"."build": "webpack --mode production"
}
Copy the code

We execute NPM run dev and NPM run build respectively

NPM run dev packages uncompressed code, while NPM run build is compressed code.

  • In production mode: enabled code compression, scope promotion, tree-shaking, making the code the most compact
  • Development mode: provides an optimization in packaging speed compared to smaller code volumes

conclusion

The zero configuration of WebPack 4 is mainly used for:

  • entryThe default is./src/index.js
  • outputThe default is./dist/main.js
  • productiondevelopmentTwo modes

Project structures,

For project construction, our appeal to Webpack is as follows:

  • Js processing: conversion ES6 code to solve browser compatibility problems
  • Handling of CSS: compiling CSS, automatically adding prefixes, extracting CSS to separate files
  • HTML processing: Copy and compress HTML files
  • Dist cleanup: Clean up the source directory files before packaging
  • Processing of assets: Static resource processing
  • Server enablement: Start the server in Development mode and refresh it in real time

Convert ES6 code to solve browser compatibility issues

Convert ES6 code with Babel

To convert ES6 code with Babel, we need to use babel-Loader. We need to install a series of dependencies:

    npm i babel-core babel-loader babel-preset-env --save-dev
Copy the code

Then create a new Babel configuration file in the root directory. Babelrc:

    {
        "presets": [
            "env"]}Copy the code

So how do you use configuration in webPack packaging?

  • Create a new webPack configuration file
  • Used in NPM scripts--module-bind
  1. To use webpack configuration files:

    New webpack. Config. Js:

        module.exports = {
          module: {
            rules: [{test: /\.js$/.exclude: /node_modules/.use: {
                  loader: "babel-loader"}}]}}Copy the code
  2. Methods configured in NPM scripts:

    "scripts": {
      "dev": "webpack --mode development --module-bind js=babel-loader",
      "build": "webpack --mode production --module-bind js=babel-loader"
    }
Copy the code

Use Babel-Polyfill to resolve compatibility issues

However, the browser still does not support the use of some syntax, resulting in compatibility problems, we use babel-polyfill to solve:

    npm i babel-polyfill babel-plugin-transform-runtime  --save-dev
Copy the code

.babelrc add configuration:

{
    "presets": [
        "env"]."plugins": [
       "transform-runtime"]}Copy the code

Finally add babel-polyfill to your entry array in webpack.config.js:

const path = require('path');
module.exports = {
    entry: [
        "babel-polyfill",
        path.join(__dirname, './src/index.js')].// ...
};
Copy the code

Compile CSS, automatically add prefixes, extract CSS to separate files

  • postcss-loader
  • mini-css-extract-plugin

Webpack does not actively extract your CSS code into a file, in the past we used extract-text-webpack-plugin, in Webpack 4 we used mini-CSs-extract-plugin to solve this problem.

Postcss-loader is used to add browser prefixes. I like to create postcss.config.js configuration in the root directory

    npm i mini-css-extract-plugin css-loader --save-dev
    npm i style-loader postcss-loader  --save-dev
Copy the code
    // webpack.config.js
    const MiniCssExtractPlugin = require("mini-css-extract-plugin");
    module.exports = (env, argv) = > {
      constdevMode = argv.mode ! = ='production'
      return {
        module: {
          rules: [
            / /... .
            {
                test: /\.css$/.use: [
                    devMode ? 'style-loader' : MiniCssExtractPlugin.loader,
                    'css-loader'.'postcss-loader']},]},plugins: [
            / /... .
            new MiniCssExtractPlugin({
              filename: "[name].css".chunkFilename: "[id].css"}}})]Copy the code
// postcss.config.js
    module.exports = {
        plugins: {
            autoprefixer: {}}}Copy the code

Copy and compress the HTML filehtml-webpack-plugin

    npm i html-webpack-plugin html-loader --save-dev
Copy the code
    // webpack.config.js
    const HtmlWebPackPlugin = require("html-webpack-plugin");
    module.exports = {
        module: {
            rules: [
                / /... .
                {
                    test: /\.html$/.use: [{
                        loader: "html-loader".options: {
                            minimize: true}}]}]},plugins: [
            new HtmlWebPackPlugin({
                template: "./src/index.html".filename: "./index.html"}})];Copy the code

Clean up the source directory files before packagingclean-webpack-plugin

With the addition and deletion of some files, some static resources that are no longer used may be generated in our Dist directory. Webpack does not automatically determine which resources are needed. In order to prevent these old files from occupying space in the production environment, So it’s a good idea to clean up the dist directory before webpack.

    npm install clean-webpack-plugin --save-dev
Copy the code
  const CleanWebpackPlugin = require('clean-webpack-plugin');
  module.exports = {
    plugins: [
      new CleanWebpackPlugin(['dist'])]};Copy the code

Static resource processingfile-loader

    npm install file-loader --save-dev
Copy the code
    // webpack.config.js
    module.exports = {
      module: {
        rules: [{test: /\.(png|jpg|gif)$/.use: [{loader: 'file-loader'.options: {}}]}}Copy the code

Start the server in Development mode and refresh in real timewebpack-dev-server

    npm i webpack-dev-server --save-dev
Copy the code

package.json

    "scripts": {
      "start": "webpack-dev-server --mode development --open",
      "build": "webpack --mode production"
    }
Copy the code

Create the React project using WebPack 4

Create-react-app creates a react project and precompilers it with less:

├─ public │ ├─ ├.html# HTML templates├─ SRC │ ├─ assets# static resources│ ├─ ├─ ├─ exercises# components│ ├─ ├─ ├.js# import file│ ├─ styles │ ├─ ├─ ├.├ ─ download.txt ├─ ├.txt ├─ download.txt ├─ webpack.config.jsCopy the code

Install the React module and less module based on the above foundation (project construction part) :

    npm i react react-dom --save
    npm i babel-preset-react --save-dev
    npm i less less-loader --save-dev
Copy the code

Modify. Babelrc:

    {
      "presets": ["env"."react"]}Copy the code

Modify the webpack. Config. Js:

    // webpack.config.js
    const path = require('path');
    module.exports = (env, argv) = > {
        constdevMode = argv.mode ! = ='production'
        return {
            entry: [
                "babel-polyfill",
                path.join(__dirname, './src/index.js')].devServer: {
                port: 3000./ / the port number
            },
            module: {
                rules: [
                    // ...
                    / / handle the react
                    {
                        test: /\.(js|jsx)$/.exclude: /node_modules/.use: {
                            loader: "babel-loader"}},/ / deal with less
                    {
                        test: /\.less$/.use: [
                            devMode ? 'style-loader' : MiniCssExtractPlugin.loader,
                            'css-loader'.'postcss-loader'.'less-loader',]}]}}};Copy the code

We’re almost done building this project, if you want to see the whole code

Set up vUE projects using WebPack 4

Similarly, we modeled the vue-CLI structure and built a VUE project ourselves, this time using SCSS for our CSS precompiled language:

├─ public │ ├─ ├.html# HTML templates├─ SRC │ ├─ assets# static resources│ ├─ ├─ ├─ exercises# components│ ├─ ├─ ├─ ├.js# import file│ ├ ─ ─ the main js# import file│ ├─ styles │ ├─ ├─ download.txt ├─ download.txt ├─ download.txt ├─ download.txt └─ webpack.config.jsCopy the code

On the above foundation (project construction part), install vUE related modules and SASS modules:

    npm i vue --save
    npm i vue-loader vue-template-compiler --save-dev
    npm i node-sass sass-loader --save-dev
Copy the code
    // webpack.config.js
    const path = require('path');
    const VueLoaderPlugin = require('vue-loader/lib/plugin')

    module.exports = (env, argv) = > {
        constdevMode = argv.mode ! = ='production'
        return {
            entry: [
                "babel-polyfill",
                path.join(__dirname, './src/main.js')].module: {
                rules: [
                    // ...
                    / / parsing vue
                    {
                        test: /\.vue$/.loader: 'vue-loader'.options: {
                            loaders: {}}}./ / SCSS processing
                    {
                        test: /\.scss$/.use: [
                            devMode ? 'style-loader' : MiniCssExtractPlugin.loader,
                            'css-loader'.'postcss-loader'.'sass-loader',]}]},plugins: [
                // ...
                new VueLoaderPlugin()
            ]
        }
    };
Copy the code

A simple VUE-CLI is also built, if you want to see the complete code

The resources

  • webpack documentation
  • Webpack 4 Tutorial: from 0 Conf to Production Mode