I. Functions of plug-ins

This plugin extracts CSS into separate files. It creates a CSS file per JS file which contains CSS. It supports On-Demand-Loading of CSS and SourceMaps.

The plugin extracts CSS into a separate file. It creates a CSS file for each JS file that contains CSS. It supports on-demand loading of CSS and SourceMap.”

The JS file contains the CSS. The JS file is not the corresponding JS file of the component, but the generated JS file after packaging.Copy the code

Second, the advantages of plug-ins

Before Webpackage 4.0, the ExtractTextWebpackPlugin is used to extract CSS, compared with the following advantages

  • Asynchronous loading
  • No duplicate compilation (performance)
  • Easier to use
  • Specific to the CSS

3. Simple use of plug-ins

Build a simple Wenpack Demo to demonstrate.

Install the MiniCssExtractPlugin.

npm install --save-dev mini-css-extract-plugin
Copy the code

After successful installation, configure it in the webpack.config.js file.

const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
    entry: {
        main: "./src/main.js",
    },
    plugins:[
        new MiniCssExtractPlugin(),
    ],
    module:{
        rules:[
            {
                test: /\.css$/,
                use:[MiniCssExtractPlugin.loader,'css-loader']
            },
        ]
    }
}
Copy the code

The entry file is main.js

import './css/main.css'
import './index'
console.log('main')
Copy the code

index.js

import './css/index.css'
import './index'
console.log('main')
Copy the code

Main. CSS has the same content as index. CSS

.class{
    color:red
}
Copy the code

Execute the webpack command and you can see the three generated files from the package in the dist folder

There are two JS files containing CSS in the project, but only one CSS file is generated by packaging, confirming that the JS file containing CSS in “it creates a CSS file for each JS file containing CSS” above refers to the generated JS file after packaging.

Open index.html in your browser and you’ll see something like the following in developer tools

The CSS files generated by the package are imported with the link tag

If you don’t use the MiniCssExtractPlugin, change the configuration in the webpack.config.js file.

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

Then execute the webpack command. Open index.html in a browser and you’ll find styles embedded in the header with

.

The MiniCssExtractPlugin is used to extract CSS styles from JS and use link to reduce the size of JS files. It is referred to as CCSS style separation.

The MiniCssExtractPlugin cannot be shared with style-loaderCopy the code

4. Parameters of the plug-in

filename

Controls the name of the CSS file generated by extracting CSS styles from the packaged entry JS file.

module.exports = {
    entry: {
        main: "./src/main.js",
    },
    plugins:[
        new MiniCssExtractPlugin({
            filename: '[name]-test.css',
        }),
    ]
}
Copy the code

After executing the webpack command, you can see in the dist folder that the CSS file name generated by the package is main-test.css

chunkFilename

Controls the name of the CSS file generated by extracting CSS styles from a packaged non-entry JS file.

module.exports = {
    entry: {
        main: "./src/main.js",
    },
    plugins:[
        new MiniCssExtractPlugin({
            filename: '[name]-test.css',
            chunkFilename: '[name]-test.css'
        }),
    ]
}
Copy the code

main.js

import './css/main.css'
import(/*webpackChunkName: "index"*/ './index')
console.log('main')
Copy the code

Run the webpack command, you can see the CSS file named index-test.css extracted from the non-entry JS file index.bundle. JS in the dist folder.

moduleFilename

The value of this parameter is a function that mainly applies to multi-entry scenarios and controls the name of the CSS file generated by extracting CSS styles from the packaged entry JS file.

If shared with filename, filename has no effect.

module.exports = {
    entry: {
        main: "./src/main.js",
        main1: "./src/main1.js",
    },
    plugins: [
        new MiniCssExtractPlugin({
            filename: 'css/[name].css',
            moduleFilename: (
                { name }) => {
                    return `${name}.css`
                },
        }),
    ],
}
Copy the code

performwebpackCommand to package the generated file as shown in the following figure

ignoreOrder

Controls whether to warn if the CSS is not introduced in the same order. The value of true indicates warning, and the value of false indicates no warning.

In simple terms, this is a problem caused by the order in which CSS is introduced in JS. If multiple CSS are introduced in different order in JS, this warning will be generated. For example, in 1.js, the order of import is A.css, b.css; In 2.js, the import order is B.css,a.css. Set the import order to be the same in both js and you’ll be fine. In 1.js and 2.js, the order of introduction is changed to a. CSS, and b. CSS does not have the warning.

You can also turn these warnings off by setting the ignoreOrder parameter to false.

For details, please refer to this issue on the official website.

5. Parameters of plug-in loader

publicPath

The default is webpackoptions.output, which is path.resolve(__dirname, ‘dist’) as shown below.

module.exports = {
    output: {
        filename: "[name].bundle.js",
        path: path.resolve(__dirname, 'dist'),
    },
}
Copy the code

Is used to specify a custom public path to the object file. It’s a little hard to understand, but here’s an example.

main.css

body{
    background: url('./LOGO.png');
}
Copy the code

Main.js entry file

import './css/main.css'
console.log('main')
Copy the code

Since main.css is importing images, we need to use file-loader to handle it. Do this in webpack.config.js

module.exports = {
    module: {
        rules: [
            {
                test: /\.png$/,
                use: [
                    {
                        loader: 'file-loader',
                        options: {
                            name: 'img/[name].[hash:8].[ext]'
                        }
                    }
                ]
            },
        ],
    },
};
Copy the code

performwebpackCommand to package the CSS file as followsmain.cssAs shown below. Pictures ondistfolderimgFolder, when opened in the browserindex.htmlImages can be loaded out.

If you change the generated CSS file path.

module.exports = {
    plugins:[
        new MiniCssExtractPlugin({
            filename: 'css/[name].css',
        }),
    ]
}
Copy the code

To performwebpackCommand to package the CSS file as followsmain.cssAs shown below. I’m going to put the picturedistfolderimgFolder, but open in browserindex.html.The image cannot load.

Because the reference path of the image in main. CSS is img/ logo.af6d901d.png, obviously the path is not correct, so the image cannot be loaded, we need to change the reference path of the image to.. /img/ logo.af6d901d. PNG can be loaded.

But it is not possible to modify the generated file of the package, so how to fix this error? You can use the publicPath parameter to modify the image reference path and modify the webpack.config.js configuration.

module.exports = {
    module: {
        rules: [
            {
                test: /\.css$/,
                use: [
                    {
                        loader:MiniCssExtractPlugin.loader,
                        options:{
                            publicPath:'../'
                        }
                    },
                'css-loader']
            },
        ],
    }
}
Copy the code

Then run the webpack command to pack the CSS file as follows: main. CSS

Open index.html in your browser and the image will load.

PublicPath specifies a custom publicPath to the object file. /img/ logo.af6d901d. PNG Path before img.. /.

esModule

The default value is false, which means MiniCssExtractPlugin generates JS modules using CommonJS module syntax.

If true, MiniCssExtractPlugin generates JS modules using ES6 module syntax.

hmr

The default is false. When true, hot update of the style file is started.

If the style file hot update is not enabled, when you modify the CSS source file, the modified style is not automatically displayed on the page. You need to manually refresh the page to load the changes. After hot update of style files is enabled, the entire page does not need to be refreshed, and the changed styles are automatically displayed on the page.

As mentioned above, MiniCssExtractPlugin cannot be used with style-loader. Style-loader is generally configured in the development environment and MiniCssExtractPlugin is configured in the production environment. In fact style-loader can also implement style file hot update.

HMR is an opt-in feature that only affects modules containing HMR code. One example would be patching styling through the style-loader. In order for patching to work, the style-loader implements the HMR interface; when it receives an update through HMR, it replaces the old styles with the new ones.

However, the MiniCssExtractPlugin style file hot update is a little more powerful than style-loader. If you change the source code of the CSS style file, using style-loader will not trigger the hot update of the style file, because style-loader only updates the styles introduced in JS. However, the MiniCssExtractPlugin hotupdates all styles.

HMR is generally set to true only in production environments.

module.exports = {
    module: {
        rules: [
            {
                test: /\.css$/,
                use: [
                    {
                        loader:MiniCssExtractPlugin.loader,
                        options:{
                            publicPath:'../',
                            hmr: process.env.NODE_ENV === 'development',
                        }
                    },
                'css-loader']
            },
        ],
    }
}
Copy the code

reloadAll

if hmr does not work, this is a forceful method.

Generally used in conjunction with the HRM parameter, when true, it means that all styles are reloaded when style file hot update does not work.

module.exports = {
    module: {
        rules: [
            {
                test: /\.css$/,
                use: [
                    {
                        loader:MiniCssExtractPlugin.loader,
                        options:{
                            publicPath:'../',
                            hmr: process.env.NODE_ENV === 'development',
                            reloadAll: true
                        }
                    },
                'css-loader']
            },
        ],
    }
}
Copy the code

Extract all CSS into one file

Use SplitChunks to do this. See the SplitChunks plugin for details in my other article: Webpack SplitChunks

module.exports = {
    optimization: {
        splitChunks: {
            cacheGroups: {
                styles: {
                    name: 'styles',
                    test: /\.css$/,
                    chunks: 'all',
                    enforce: true,
                },
            },
        },
    },
}
Copy the code

Run the webpack command to pack the generated files as shown below