Webpack: webpack.docschina.org/

First of all, what is Webpack?

  1. Webpack is a static module bundler for modern JavaScript applications. When WebPack works with an application, it recursively builds a Dependency graph containing every module the application needs, and then packages all of those modules into one or more bundles.
  2. Webpack itself is developed based on Node.js
  3. Starting with WebPack V4.0.0, it is possible not to introduce a configuration file (zero configuration file), but WebPack is still highly configurable.

Let’s take a closer look at WebPack in a few steps

1. Install webpack

We are based on the fourth generation of Webpack

In order to prevent the global installation of Webpack version conflicts, we basically installed in the local project during the project development;

// Since webpack is developed based on Node.js, before installing Webapck, we must install Node, then NPM will automatically install, then install webpack based on the NPM command
$ npm init -y
$ npm install webpack webpack-cli --save-dev
OR
$ yarn add webpack webpack-cli -D
Copy the code

2. Basic use of Webpack

Initial experience (zero configuration)

/ * * the default will be packaged in the SRC directory (the default index entry. JS) * JS file package complete directory. The default is DIST/MAIN JS npx:http://www.ruanyifeng.com/blog/2019/02/npx.html * * * By default, node_modules/bin/webpack. CMD * webpack supports CommonJS and ES6 Module specifications by default, depending on which package */
$ npx webpack
Copy the code

NPX: from nPM5.2, there is a command: NPX, based on this command we can install the local module (based on the NPM installation, can be installed globally or local, installed globally can be executed based on command, and local can not be executed based on command, of course can be configured.)

$NPX webpack implements webpack based on NPX, and this command is used to implement the package deployment

You can customize basic configurations

Although WebPack 4 supports zero configuration, of course we can customize the base configuration as required

First we create a file called webpack.config.js or webpackfile.js

// Import it because you need to use the path module in Node
let path = require('path');
module.exports = {
    //=> Package development environment Production environment Production
    mode: 'production'./ / = > entry
    entry: './src/index.js'./ / = > output
    output: {
        //=> Name of the output file
        filename: 'bundle.min.[hash].js'.//=> Output directory "absolute path"
        path: path.resolve(__dirname, 'dist')}}Copy the code

Custom configuration file name

  • $ npx webpack –config webpack.config.development.js
  • Executable script commands can be configured in package.json (development environment specific)
//package.json
"scripts": {
    "serve": "webpack --config webpack.config.development.js"."build": "webpack --config webpack.config.production.js"
},
Copy the code

3. webpack-dev-server

Webpack.js.org/configurati…

  • Install: $YARN add webpack-dev-server -d
  • Basic configuration
/* webpack.config.js */
/ / = DEV - > configuration SERVER
devServer: {
    / / = > ports
    port: 3000.//=> The compilation progress is displayed
    progress: true.//=> Specify the resource directory to access
    contentBase: './dist'.//=> Automatically open the browser
    open: true
}
Copy the code
/* package.json */
"scripts": {
    "serve": "webpack-dev-server"."build": "webpack"
}
Copy the code
  • $ npm run serve
  • $ npx webpack-dev-server

When the code changes, it is automatically recompiled, and then the page is automatically refreshed

4. html-webpack-plugin

www.webpackjs.com/plugins/htm…

  • Install: $YARN add HTML -webpack-plugin -d
  • Used in webpack.config.js
// Import the plugin first
let HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = { ... .//=> Use the plug-in in Webpack
    plugins: [
        // Since the imported plug-in is a class, we need to use it new
        new HtmlWebpackPlugin({
            //=> Specify your own template
            template: './src/index.html'.//=> Name of the output file
            filename: 'index.html'.//=> Set HASH to the imported file (clear the cache), or you can set filename: 'bundle.[HASH].js' in output to generate a different file
            hash: true.//=> Controls whether and how to minimize the output
            //=>https://github.com/kangax/html-minifier
            minify: {
                collapseWhitespace: true.removeComments: true.removeAttributeQuotes: true.removeEmptyAttributes: true}}})]Copy the code

5. Webpack loader: handles style

  • Installation: $yarn add CSs-loader style-loader less less-loader autoprefixer postCSs-loader… -D
  • use
module.exports = {
    //=> Configure the module LOADER
    module: {
        //=> Module rule: use loader (default right to left, bottom to top)
        rules: [{
            test: /\.(css|less)$/.//=> Which modules need to be processed based on regular expressions
            use: [
                "style-loader".//=> Insert the CSS into the HEAD
                "css-loader".//=> compile and parse @import/URL() syntax
                "postcss-loader".//=> Set the prefix
                {
                    loader: "less-loader".options: {
                        //=> Additional configuration of loader}}]}}Copy the code

postcss.config.js

// This file needs to be used with postCSs-loader
module.exports = {
    plugins: [
        require('autoprefixer')]};Copy the code
//package.json
"browserslist": [
    "1%" >."last 2 versions"
]
Copy the code

6. Mini-css-extract-plugin Extracts CSS content

This is just dealing with THE CSS, putting it in the structure, this is isolating the CSS and compressing it

www.npmjs.com/package/min…

  • $YARN add mini-css-extract-plugin optimize- CSS -assets-webpack-plugin uglifyjs-webpack-plugin -d
let MiniCssExtractPlugin = require('mini-css-extract-plugin'),
    OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin'),
    UglifyjsWebpackPlugin = require('uglifyjs-webpack-plugin');
module.exports = {
    //=> Set optimization items
    optimization: {
        //=> Set the compression mode
        minimizer: [
            //=> Compress CSS (but you must specify how to compress JS)
            new OptimizeCssAssetsWebpackPlugin(),
            / / = > compression JS
            new UglifyjsWebpackPlugin({
                cache: true.//=> Whether to use cache
                parallel: true.//=> Whether to compile concurrently
                sourceMap: true.//=> Start source mapping (easy debugging)}})],plugins: [
        //=> Use plug-ins
        new MiniCssExtractPlugin({
            //=> Set the compiled file name
            filename: 'main.css'})].module: {
        rules: [{
            test: /\.(css|less)$/.use: [
                // "style-loader",
                //=> Use the LOADER in the plug-in to replace the STYLE mode
                MiniCssExtractPlugin.loader,
                "css-loader"."postcss-loader"."less-loader"]]}}}Copy the code

7. ES6 conversion and ESLint syntax detection based on Babel

In step 6, you need to work on some ES6 syntax!

babeljs.io/

eslint.org/

  • Install $YARN add babel-loader @babel/ core@babel /preset-env @babel/plugin-proposal-class-properties @babel/plugin-proposal-decorators @babel/plugin-transform-runtime -D
  • Install $YARN add @babel/ runtime@babel /polyfill
  • Install $YARN add eslint eslint-loader -d
module.exports = { ... .module: {
        rules: [..., {test: /\.js$/.use: [{
                loader: 'babel-loader'.options: {
                    //=> Syntax presets for conversion (ES6->ES5)
                    presets: [
                        "@babel/preset-env"].//=> Special syntax for classes in ES6/ES7 based on plug-ins
                    plugins: [
                        ["@babel/plugin-proposal-decorators", {
                            "legacy": true
                        }],
                        ["@babel/plugin-proposal-class-properties", {
                            "loose": true}]."@babel/plugin-transform-runtime"]}}],//=>, "eslint-loader"
            //=> Sets the files to be ignored during compilation and specifies the compilation directory
            include: path.resolve(__dirname, 'src'),
            exclude: /node_modules/}}}]Copy the code

8. Expose the global Loader

  • $ yarn add expose-loader -D
  • Preloaders, post loaders, plain loaders…

For example, you want to use jquery or $directly

//=> Inline loader
import jquery from 'expose-loader? $! jquery';
console.log(window. $); {//=> Inject $globally as soon as JQUERY is introduced
    test: require.resolve('jquery'),
    use: ['expose-loader? $']}Copy the code
let webpack = require('webpack');
module.exports = {
    plugins: [
        //=> Inject $into each module
        new webpack.ProvidePlugin({
            '$': 'jquery'}})],/ / = > page
console.log($);// So there is no error
Copy the code

9. Processing and distribution of pictures in webpack

There are three ways to use images

  • Create img in js
  • Set the background image in the CSS
  • Write dead in HTML

Install $YARN add file-loader url-loader html-withimg-loader -d

module.exports = { ... .module: {
        //=> Module rule: use loader (default from right to left)
        rules: [..., {
            // There are many image formats...
            test: /\.(png|jpg|gif)$/i.use: [{
                //=> set BASE64 to the image in the specified size
                loader: 'url-loader'.options: {
                    limit: 200 * 1024.outputPath:'/images'}}].include: path.resolve(__dirname, 'src'),
            exclude: /node_modules/
        }, {
            test: /\.html$/.use: ['html-withimg-loader']]}}}Copy the code
  • Finally, the implementation of file directory publishing
module.exports = {
    output: {
        //=> Configure the reference prefix (precede all resources with this address)
        publicPath: '/'
    },
    plugins: [
        new MiniCssExtractPlugin({
            filename: 'css/main.css'})].module: {
        //=> Module rule: use loader (default from right to left)
        rules: [...,{
            test: /\.(png|jpg|gif)$/i.use: [{
                options: {
                    outputPath: 'images'}}]}}Copy the code

A more complete WebPack configuration

/* Set our custom packaging rules in this file. All rules are written in module.exports={} */
let path = require('path');
let HtmlWebpackPlugin = require('html-webpack-plugin');
let MiniCssExtractPlugin = require('mini-css-extract-plugin'), // Separate out the CSS
    OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin'), / / compress CSS
    UglifyjsWebpackPlugin = require('uglifyjs-webpack-plugin'); Js / / compression
let webpack = require('webpack');
New HtmlWebpackPlugin({});

module.exports = {
    // Configure optimization rules
    optimization: {
        // Set the compression mode
        minimizer: [
            // Compressing CSS (problem: JS compression no longer executes its default compression mode, but also uses this plugin, so it cannot be compressed, so it must set the compression mode of JS)
            new OptimizeCssAssetsWebpackPlugin(),
            Js / / compression
            new UglifyjsWebpackPlugin({
                cache: true.// Whether to use cache
                parallel: true.// Is the art of war compiled
                sourceMap: true.// Enable source mapping (easy debugging)}})],// Configuration environment development environment production environment (default)
    mode: 'production'./ / the entry
    entry: ['@babel/polyfill'.'./src/index-my.js']./ / export
    output: {
        // The name of the output file
        //bundle.min.[hash].js makes every generated file name have a hash value
        filename: 'bundle.min.js'.// filename: 'bundle.min.[hash].js',
        // The output directory must be an absolute path,__dirname current directory
        path: path.resolve(__dirname, 'dist'),
        publicPath: '/' // Import the prefix set before the resource address after compilation
    },
    // For some configuration of webpack-dev-server run the webpack-dev-server --config xxx.js command
    // If the SRC source file is modified, it will compile and refresh the browser automatically.
    // Live Server plugin in vscode.
    devServer: {
        // Create the port number specified by the service
        port: 3000.// Displays the package compilation progress
        progress: true.// Specify a directory for the current service processing resources
        contentBase: './dist'.// Automatically open the browser after compiling
        open: true
    },
    // Use plugins (arrays)
    plugins: [
        new HtmlWebpackPlugin({
            // If you do not specify a template, you will create an HTML page based on the default template
            template: './src/index.html'.// The output file name
            filename: 'index.html'.// Let's import js followed by a hash hash, but in real projects we would normally import a different JS file each time we compile it
            hash: true.// Control compression
            minify: {
                collapseWhitespace: true.removeComments: true.removeAttributeQuotes: true.removeEmptyAttributes: true}}),new MiniCssExtractPlugin({
            // Specify the name of the output file
            filename: 'main.min.css'
        }),
        // Inject $into each module
        new webpack.ProvidePlugin({
            '$': 'jquery'}),].// Use the loader loader to process the rule
    module: {
        rules: [{
            // Which files to process based on regular matches
            test: /\.(css|less)$/.// Which loader to use controls the use of the loader (sequential: right to left execution)
            use: [
                // "style-loader", // insert the compiled CSS into the page head (inline)
                MiniCssExtractPlugin.loader, // Use the loader in the plug-in instead of the style method
                "css-loader".// compile and parse @import/URL() syntax
                // "postcss-loader",// sets the prefix loader
                {
                    loader: "postcss-loader".options: {
                        ident: 'postcss'.plugins: [
                            require('autoprefixer'}}, {loader: "less-loader"./ / compile less
                    options: {
                        // Load additional configuration}}]}, {test: /\.js$/.// Process the loader that compiles JS
            use: [{
                loader: 'babel-loader'.options: {
                    // Syntax presets for conversion (ES6->ES5)
                    presets: [
                        "@babel/preset-env"].//=> Special syntax for classes in ES6/ES7 based on plug-ins
                    plugins: [
                        ["@babel/plugin-proposal-decorators", {
                            "legacy": true // Handle the decorator
                        }],
                        ["@babel/plugin-proposal-class-properties", {
                            "loose": true // Handle attributes}]."@babel/plugin-transform-runtime"]}}],// Sets the files ignored during compilation and specifies the compilation directory
            include: path.resolve(__dirname, 'src'), / / compile
            exclude: /node_modules/ // Ignore ·
        }, {
            // Image processing
            test: /\.(png|jpg|gif|jpeg|ico|webp|bpm)$/i.use: [{
                loader: 'url-loader'.options: {
                    // As long as the image is less than 200KB, base64 is directly used for processing
                    limit: 2 * 1024.// Control the directory in which the image is packed
                    outputPath: 'images'}}}, {// Process the img file imported from the HTML file
            test: /\.(html|htm|xml)$/i.use: ['html-withimg-loader']]}}}Copy the code