The solution is really more of a plug-in index for WebPack. The purpose of writing this article is to form a so, in the future when used directly to find. Index catalog

1. Build HTML automatically, compress space, add version number or random number to referenced JS: html-webpack-plugin 2. Handling CSS: CSS-loader and style-loader 3. 4. Extract CSS code into CSS file: extract-text-webpack-plugin 5. Server setup in development environment: Webpack-dev-server 6. Parse ES6 code: babel-core babel-env babel-loader 7. Parse ES6’s new object function: babel-Polyfill 8. React JSX syntax: babel-preth-react 9 Convert relative path to absolute path: nodejs path module 10. Hash the file to [chunkhash],[hash] 11. Empty the output file before the output folder: clean-webpack-plugin 12. Module hot replacement: NamedModulesPlugin and HotModuleReplacementPlugin 13. 14. Use environment variables across platforms: cross-env 15. Image processing path: file-loader and html-loader 16. Image compression: image-webpack-loader 17. Locate source file code: source-map 18. Separate configuration files for production and development environments

1. Build HTML automatically, compress space, add version number or random number to referenced JS: html-webpack-plugin

The solution: use the html-webpack-plugin webpack.config.js as follows:

module.exports = { entry: './src/app.js', output: { path: __dirname + '/dist', filename: 'app.bundle.js' }, plugins: [new HtmlWebpackPlugin({template: './ SRC/template file.html ', filename: 'build.html ', minify: {collapseWhitespace: true, }, hash: true, })] };Copy the code

Note the path, because the HTML for this output needs to know the output directory

2. Handling CSS: CSS-loader and style-loader

Loader is used to preprocess the source code of a module.

Solution: Use CSS-loader, style-loader

Take a look at the project structure:




References the JS of CSS

Running the webpack command at this point throws an error:




Webpack cannot package CSS

Then install CSS-loader and style-loader

npm install --save-dev css-loader style-loader
Copy the code

Change webpack.config.js to:




The red box shows the newly added configuration

The rules array is the array of rules that loader uses to match and convert resources. Test represents a regular expression that matches files to be converted, and the figure matches all files that end in CSS. The use array represents which loaders are used to process the matched files.

When you run WebPack, the bundled file bundle.js contains the CSS code. Css-loader loads the CSS and packages the CSS to JS. Style-loader is responsible for generation: while JS is running, the CSS code is injected into the DOM via the style tag.

3. Handle LESS: less-loade and LESS

Solution: Use less-loader but using less-loader simply converts less code to CSS code. If you want to package files into JS, you still need to use the csS-loader and style-loader mentioned above.

Take a look at the project structure:




Less Project structure

Then the code for app.js is:

import styles from './app.less'; Console. info(' I am a JS file 123')Copy the code

To resolve this situation, install less-loader first, and less-loader is based on less, so install less as well.

npm i --save-dev less less-loader
Copy the code

Change webpack.config.js to:

module: {
  rules: [
    {
      test: /\.less$/,
      use: [ 'style-loader', 'css-loader', 'less-loader' ]
    }
  ]
}
Copy the code

4. Extract CSS code into CSS file: extract-text-webpack-plugin

A lot of times what we want is not to pack a few LESS or CSS into a JS file, but to pack it into a CSS file. Here comes the extract-text-webpack-plugin. Install it first

npm i --save-dev extract-text-webpack-plugin
Copy the code

Then change webpack.config.js to:




New or modified configurations are displayed in the red box

Compared with the original configuration can be found that more than HTML – webpack – the plugin this plugin did step, is the use in matching and transformation rules were used in the ExtractTextPlugin. Extract. Note that fallback means that the style-loader will continue to package the file into JS after it fails to extract the file. Run webpack at this point and you’ll see that the output directory build generates a style.css file, which is the one we expected to generate in webpack.config.js, and is referenced in the generated demo.html.

5. Server setup in the development environment: Webpack-dev-server

Webpack-dev-server can build a simple server in the local development environment, automatically open the browser, and can achieve the effect of Webpack-Watch. First install:

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

There is no need to change webpack.config.js and run the command directly

webpack-dev-server
Copy the code

View console output:




Console output

Show that the project is running in the output directory of http://localhost:8080/ webpack under/and the server will automatically recognize the HTML file named index in the output directory, as opposed to the previous output file named demo.html. So you also need to be HTML – webpack – before the plugin configured in the filename to index. The HTML, or directly with http://localhost:8080/demo.html. When we modify the source code, the open web page will be updated automatically.

For a more flexible application development environment server, you can also add the following code to webpack.config.js:




image.png

DevServer configuration function
port Change the port to 8787 instead of the default 8080.
open True means that the browser will open automatically, rather than having to manually open the browser and type in ithttp://localhost:8080.
compress Provides gzip compression for files returned by the local server
index Specifies the file to map the home page of a website. The default is index.html

ES6 code: babel-core babel-env babel-loader

ES6 is actually a higher version of ECMAScript, but it’s just a proxy. The purpose of Babel is to convert advanced JS code that is not yet supported by the browser into JS code that can be supported by the specified browser.

Here is the general syntax that can be converted:




Babel-preset -preset- transitions supported by env

The first step is to install Babel

npm install babel-core babel-preset-env --save-dev
Copy the code

Then, to combine with Webpack, use the babel-loader

npm install babel-loader --save-dev
Copy the code

Then add the following code to the rules array of webpack.config.js:

{
  test: /\.js$/,
  exclude: /(node_modules)/,
  use: {
    loader: 'babel-loader',
    options: {
      presets: ['env']
    }
  }
}
Copy the code

Use babel-loader to parse all js files except node_modules. The babel-loader uses Babel to parse JS code. The content of options is similar to the configuration of the.babelrc file, which is not needed. Presets are preprocessors, and Babel doesn’t need as many preprocessors as it used to, just one env.

Modify the previous code in app.js to:

Console. info(' I am a JS file 123') const doSomething=() => {console.info('do do do')}Copy the code

After using the webpack command, you can see that the code in our final package JS file looks like this:




image.png

7. Parse ES6’s new object function: babel-polyfill

Here are the new functions:




Babel-polyfill supports conversions

Installation:

npm install --save-dev babel-polyfill
Copy the code

To ensure that babel-polyfill is loaded and parsed first, babel-polyfill is usually introduced in the very beginning of the script. In webpack, it is in entry, so you need to change the configuration in webpack.config.js to:


The red box shows the modified parts

8. React JSX syntax: babel-preset-react

The installation

npm install --save-dev babel-preset-react
Copy the code

Configuration:




Modified configuration

This matches all files ending in JS or JSX and is parsed with babel-preset-env and babel-preset-react

9. Convert relative path to absolute path: nodeJS path module

The nodeJS path module starts with a feature called resolve. Convert a relative path to an absolute path. Reference the PATH module at the beginning

Var path = require('path');Copy the code

You can then modify the code in the output Settings to:

  output: {
    path: path.resolve(__dirname, 'build'),
    filename: 'bundle.js'
  },
Copy the code

It doesn’t look any different from our original code.

10. Hash the file: [chunkhash],[hash]

Hash differs from chunkhash in that all output files use the same hash value, whereas chunkhash is calculated by modules and has a different hash value for each output file. Change the output file directly to

output: {
  path: path.resolve(__dirname, 'build'),
  filename: 'bundle.[chunkhash].js'
},
Copy the code

[chunkhash] represents a random hash value

11. Empty the output file before the output folder: clean-webpack-plugin

When we constantly change the output file as above, the previous output file is not removed. To solve this problem, the clean-webpack-plugin is needed. First installation

npm i clean-webpack-plugin --save-dev
Copy the code

You then reference the plug-in and declare the folder that needs to be emptied each time you generate output

var CleanWebpackPlugin = require('clean-webpack-plugin');
var pathsToClean = [
  'build',
]
Copy the code

Add the following to the plug-in configuration:

new CleanWebpackPlugin(pathsToClean)
Copy the code

12. The module hot replacement: NamedModulesPlugin and HotModuleReplacementPlugin

The previous Webpack-dev-server provided a listening function that refreshed the browser whenever the code changed. However, module hot replacement does not refresh the browser, only the modified part of the module. Hot replacement modules do not need to be installed. First you need to introduce modules

var webpack = require('webpack')
Copy the code

Add:

new webpack.NamedModulesPlugin(),
new webpack.HotModuleReplacementPlugin()
Copy the code

Running webPack may cause an error, we need to change the [chunkhash] we wrote in the output environment to [hash]

13. Environment variables

You can write this in the script:

“scripts”: {

“dev”: “webpack-dev-server”,

“prod”: “set NODE_ENV=production && webpack -p”

},

Modify the above things in webpack.config.js like this:


if (isProduction) {
    config.output.filename = 'bundle.[chunkhash].js'
} else {
    config.plugins.push(new webpack.NamedModulesPlugin())
    config.plugins.push(new webpack.HotModuleReplacementPlugin())
}
Copy the code

This allows you to run different configurations depending on your environment

14. Use the environment variable cross-platform: cross-env

The preceding script for setting environment variables is valid only on Windows and is required on Linux and MAC

"prod": "NODE_ENV=production webpack -p"
Copy the code

To solve this problem so that people on different platforms can share a common set of code, we can use cross-env. Install first:

npm i --save-dev cross-env
Copy the code

Then the command directly uses the same usage as on the MAC

"prod": "cross-env NODE_ENV=production webpack -p"
Copy the code

15. Image processing path: file-loader and html-loader

File-loader is used to handle the path of image and font files in the CSS file. The output CSS file references the address of the output file. Html-loader can be used to handle image paths in HTML, such as img elements. First installation

npm i --save-dev file-loader html-loader
Copy the code

Configuration:

{ test: /\.(gif|png|jpe? g|svg)$/i, use: { loader: 'file-loader', options: { name: '[name].[ext]', outputPath: 'src/images/' } } }, { test: /\.html$/, use: [{ loader: 'html-loader', options: { minimize: true } }], }Copy the code

16. Image compression: image-webpack-loader

Installation:

npm i --save-dev image-webpack-loader
Copy the code

Configuration:

{ test: /\.(gif|png|jpe? g|svg)$/i, use: [{ loader: 'file-loader', options: { name: '[name].[ext]', outputPath: 'images/' } }, { loader: 'image-webpack-loader', options: { bypassOnDebug: true, } } ] },Copy the code

Options can also specify the compression quality of each image type

17. Locate source file code: source-map

If we run our output file with web-dev-server, find some bugs in it, and then open the developer tool to retrieve the location file, only our output file will be located. These output files are processed, and we can only solve the problem by finding our source code and modifying it accordingly. So here we need source-map. Simply add the following configuration to webpack.config.js:

devtool: 'source-map',
Copy the code

It’s as simple as that, and no plug-ins need to be installed. But this only works for JS. If our CSS is wrong, the answer is:




Append these loaders with? SourceMap can

18. Separate configuration files for production and development environments

Earlier we did different configurations by setting environment variables in the command and judging the environment by the environment variables. Now let’s use the official recommended method to separate the configuration files for production and development environments. We split webpack.config.js into three files

  • webpack.common.js
  • webpack.dev.js
  • webpack.prod.js

Webpack.common.config. js is the configuration shared by the production environment and development environment, dev is the configuration unique to the development environment, and prod is the configuration unique to the build environment. To synthesize a real configuration file, you need another tool: webpack-Merge.

  npm install --save-dev webpack-merge
Copy the code

Here is our previous webpack.config.js code:

var ExtractTextPlugin = require('extract-text-webpack-plugin') var HtmlWebpackPlugin = require('html-webpack-plugin') var CleanWebpackPlugin = require('clean-webpack-plugin') var path = require('path') var webpack = require('webpack') var  pathsToClean = [ 'build', ] var isProduction = process.env.NODE_ENV === 'production' var config = { entry: ['babel-polyfill', './src/app.js'], output: { path: path.resolve(__dirname, 'build'), filename: '[name].[hash].js' }, devtool: 'source-map', devServer: { port: 8787, open: true, compress: true, index: 'demo.html' }, plugins: [ new HtmlWebpackPlugin({ template: './template/index.html', filename: 'demo.html', minify: { collapseWhitespace: true, }, hash: true }), new ExtractTextPlugin({ filename: 'style.css', allChunks: false }), new CleanWebpackPlugin(pathsToClean) ], module: { rules: [{ test: /\.css$/, use: ExtractTextPlugin.extract({ fallback: 'style-loader', use: ['css-loader?sourceMap'] }) }, { test: /\.less$/, use: ExtractTextPlugin.extract({ fallback: 'style-loader', use: ['css-loader?sourceMap', 'less-loader?sourceMap'] }) }, { test: /\.jsx?$/, exclude: /(node_modules)/, use: { loader: 'babel-loader', options: { presets: ['env', 'react'] } } }, { test: /\.(gif|png|jpe?g|svg)$/i, use: [{ loader: 'file-loader', options: { name: '[name].[ext]', outputPath: 'images/' } }, { loader: 'image-webpack-loader', options: { bypassOnDebug: true, } } ] }, { test: /\.html$/, use: [{ loader: 'html-loader', options: { minimize: true } }], } ] } }; if (isProduction) { config.output.filename = '[name].[chunkhash].js' } else { config.plugins.push(new webpack.NamedModulesPlugin()) config.plugins.push(new webpack.HotModuleReplacementPlugin()) } module.exports = configCopy the code

The next three files are webpack.common.js: var ExtractTextPlugin = require(‘extract-text-webpack-plugin’) var HtmlWebpackPlugin = require(‘html-webpack-plugin’) var CleanWebpackPlugin = require(‘clean-webpack-plugin’) var path = require(‘path’) var webpack = require(‘webpack’)

var pathsToClean = [
    'build',
]

var isProduction = process.env.NODE_ENV === 'production'

module.exports = {
    entry: ['babel-polyfill', './src/app.js'],
    output: {
        path: path.resolve(__dirname, 'build'),
        filename: '[name].[chunkhash].js'
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: './template/index.html',
            filename: 'demo.html',
            minify: {
                collapseWhitespace: true,
            },
            hash: isProduction
        }),
        new ExtractTextPlugin({ filename: '[name].[contenthash].css', allChunks: false }),
        new CleanWebpackPlugin(pathsToClean)
    ],
    module: {
        rules: [{
                test: /\.jsx?$/,
                exclude: /(node_modules)/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: ['env', 'react']
                    }
                }
            },
            {
                test: /\.(gif|png|jpe?g|svg)$/i,
                use: [{
                        loader: 'file-loader',
                        options: {
                            name: '[name].[ext]',
                            outputPath: 'images/'
                        }
                    },
                    {
                        loader: 'image-webpack-loader',
                        options: {
                            bypassOnDebug: true,
                        }
                    }
                ]
            },
            {
                test: /\.html$/,
                use: [{
                    loader: 'html-loader',
                    options: {
                        minimize: true
                    }
                }],
            }
        ]
    }
};
Copy the code

And then webpack.dev.js:

const merge = require('webpack-merge');
const common = require('./webpack.common.js');
const webpack = require('webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin')

module.exports = merge(common, {
    output: {
        filename: '[name].[hash].js'
    },
    devtool: 'source-map',
    devServer: {
        port: 8787,
        open: true,
        compress: true,
        index: 'demo.html'
    },
    plugins: [
        new webpack.NamedModulesPlugin(),
        new webpack.HotModuleReplacementPlugin()
    ],
    module: {
        rules: [{
                test: /\.css$/,
                use: ExtractTextPlugin.extract({
                    fallback: 'style-loader',
                    use: ['css-loader?sourceMap']
                })
            },
            {
                test: /\.less$/,
                use: ExtractTextPlugin.extract({
                    fallback: 'style-loader',
                    use: ['css-loader?sourceMap', 'less-loader?sourceMap']
                })
            }
        ]
    }
});
Copy the code

Finally the webpack. Prod. Js:

const merge = require('webpack-merge');
const common = require('./webpack.common.js');
const ExtractTextPlugin = require('extract-text-webpack-plugin')

module.exports = merge(common, {
    module: {
        rules: [{
                test: /\.css$/,
                use: ExtractTextPlugin.extract({
                    fallback: 'style-loader',
                    use: ['css-loader']
                })
            },
            {
                test: /\.less$/,
                use: ExtractTextPlugin.extract({
                    fallback: 'style-loader',
                    use: ['css-loader', 'less-loader']
                })
            }
        ]
    }
});
Copy the code

Then modify the script in package.json

  "scripts": {
    "dev": "webpack-dev-server --config webpack.dev.js",
    "prod": "cross-env NODE_ENV=production webpack -p --config webpack.prod.js"
},
Copy the code

.

Conclusion:

There are many other ways to play plug-ins and Loaders, but I won’t go into details here. The final scaffolding was put up: webpack4Hanzilu