Packing CSS Resources

Using the loader

Webpack can use a variety of loaders to preprocess resources in different formats.

  1. Add files to project directory:

// src/index.html <! DOCTYPE html> <html> <head> <meta charset='utf-8'>
    <meta http-equiv='X-UA-Compatible' content='IE=edge'>
    <title>Page Title</title>
    <meta name='viewport' content='width=device-width, initial-scale=1'>
</head>
<body>
    <div class="box"></div>
</body>
</html>
Copy the code
// src/css/style.css
.box{
    width:50px;
    height: 50px;
    background-color: pink;
}
Copy the code
  1. The installationcss-loaderandstyle-loader

    css-loaderResponsible for reading CSS files and then usingstyle-loaderInject CSS content into JS, and eventually embed it in Html code as style tags

    npm i -D css-loader style-loader
  2. Changing a Configuration file
module:
{
    test: /\.css$/,
    use: [
        {
            loader:'style-loader'Options :{insertAt:top, top means top, does not overwrite the HTML style}}'css-loader'// parse CSS file]},Copy the code

Module usage:

  • rules: an array containing various Loaders
  • test: regular expression to match different file name suffixes
  • loader: There are many ways to use it
{
    test:/\.js$/,
    loader:'babel-loader'// Only one loader} {test:/\.css$/,
    use:['style-loader'.'css-loader'] // Multiple loaders from right to left} {test:/\.css$/,
    use:[ 
        'style-loader'{//loader can use object loader to set parameters:'css-loader',
            options:{
                minimize:true}}}]Copy the code

Use the MiniCssExtractPlugin

You can use CSS-loader +style-loader by packing styles into a JS file and embedding them into the page as style tags. Mixing CSS styles with JS files can cause some style confusion, so use plug-ins to pack CSS styles into a single CSS file and embed them in the page as link tags for resource requests. Webpack3 usually uses the ExtractWebpackPlugin, but it is no longer supported in WebPack4. MiniCssExtractPlugin is officially recommended to replace it. Install first: NPM I-d mini-CSS-extract-plugin to modify configuration files

const miniCssExtractPlugin=require('mini-css-extract-plugin');

module.exports = {
    entry: path.join(__dirname, 'src/index.js'),
    output: {
        path: path.join(__dirname, 'dist'),
        filename:'bundle.js',
    },
    module: {
        rules:[
            {
                test: /\.css$/,
                use: [
                    {
                        loader:miniCssExtractPlugin.loader
                    },
                    'css-loader'
                ]
            }
        ]
    },
    plugins: [
        new htmlWebpackPlugin({
            template:'./src/index.html'
        }),
        new miniCssExtractPlugin({
            filename:'[name].css'// Output CSS file name, placed in dist directory})]}Copy the code

Open dist/index.html and you can see the CSS styles introduced in link form.

Automatic prefix adding

We want to be able to add browser prefixes to CSS automatically using the plugin Autoprefixer.

  1. First install,npm i -D postcss-loader autoprefixer
  2. postcss-loaderA configuration file is required. Create one in the root directorypostcss.config.jsFile, write:
module.exports={
    plugins:[require('autoprefixer')]}Copy the code
  1. Configure the loader
// webpack.config.js
{
    test: / \. CSS $/, use: [{loader: miniCssExtractPlugin loader / / pull away into a CSS file},'css-loader'// Parse the CSS'postcss-loader'// add prefix]}Copy the code
  1. Write CSS test code
// src/css/style.css
.box{
    width:50px;
    height: 50px;
    background-color: pink;
    transform: rotateX(30deg);
}
Copy the code
  1. packagingnpm run buildAfter the opendist/main.cssYou can see that Tranform has been prefixed with webKit.

Compress CSS/JS code

Use the optimize- CSS -assets-webpack-plugin to compress CSS code.

  1. The installationnpm i -D optimize-css-assets-webpack-plugin
  2. Modifying a Configuration File
// webpack.config.js

const opimizeCss=require('optimize-css-assets-webpack-plugin');

module.exports = {
    optimization:{   
        minimizer:[
            new opimizeCss()
        ]   
    },
    mode:'production'. }Copy the code
  1. NPM run build: if we open main.css, we will find that the js code is compressed, but the default environment is productionuglifyjs-webpack-pluginTo compress js code.
  2. The installationnpm i -D uglifyjs-webpack-plugin
  3. Modifying a Configuration File
//webpack.config.js
const uglifyJsWebpackPlugin=require('uglifyjs-webpack-plugin')

module.exports = {
    optimization:{   
        minimizer:[
            new uglifyJsWebpackPlugin({
                cache:true, // Whether to cache parallel:true, // Whether to package multiple files concurrentlysourceMap:true// Packaged code and source mapping, easy debugging})... ] . }Copy the code

Turn es6 es5

Webpack uses a lot of ES6 syntax, we need to convert to ES5 and use Babel to do this.

  1. Install Babelnpm i -D babel-loader @babel/core @babel/preset-env
  2. Configure the loader
{
    test:/\.js$/,
    use:[
        {
            loader:'babel-loader', options:{presets:[' @babel/preset-env '// ES6 to ES5]}}]}Copy the code

Package image resources

Create an image import in JS

(1) Imported images need to be imported into the js file of the entrance

// index.js

import img from './img/big.jpg'; Var imgElement = document.createElement(var imgElement = document.createElement('img');
imgElement.src = img;
document.body.appendChild(imgElement);
Copy the code

(2) Install file-loader and configure NPM i-d file-loader

// webpack.config.js

{
    test: /\.(png|jpg|gif|svg|jpeg)$/,
    loader: 'file-loader',}Copy the code

Introduce background images in CSS

In the same way that JS introduces images, url-loader is more commonly used than file-loader. It can encode small images directly in Base64 to reduce HTTP requests. (1) Install url-loader and configure NPM I-d url-loader

// webpack.config.js

{
    test: /\.(png|jpg|jpeg|gif|svg)$/,
    loader: 'url-loader',
    options: {
        limit: 1024, // Images less than this value will use base64 encoding name:'[name].[hash:8].[ext]'// Package the image name [ext] refers to the image format}}Copy the code

Write directly in HTMLThe label

// src/index.html <! DOCTYPE html> <html> <head> <meta charset='utf-8'>
    <meta http-equiv='X-UA-Compatible' content='IE=edge'>
    <title>Page Title</title>
    <meta name='viewport' content='width=device-width, initial-scale=1'>
</head>
<body>
    <div class="box"></div>
    <img src="./img/big.png">
</body>
</html>
Copy the code

After packaging, it was found that the address of the image was written dead, which was not relative to DIST, so the image could not be found. Html-withimg-loader was used to process the images in HTML. Install and configure NPM i-d html-withimg-loader

// webpack.config.js
{
    test:/\.html$/,
    loader:'html-withimg-loader'
}
Copy the code

After packaging and running again, I found that I could load the image correctly.

Configure different resource paths

In this configuration, all resources are placed in the dist directory, which looks confusing. We want js in the JS folder, CSS in the CSS folder, and images in the IMG folder to change the configuration.

//webpack.config.js

module.exports = {
    entry: path.join(__dirname, 'src/index.js'),
    output: {
        path: path.join(__dirname, 'dist'),
        filename:'js/bundle.js'}, module: {rules:[{test: /\.css$/,
                use: [
                    {
                        loader:miniCssExtractPlugin.loader
                    },
                    'css-loader'.'postcss-loader'] {},test:/\.js$/, // Will be packaged into the output js file, so there is no need to configure path use:[{loader:'babel-loader',
                        options:{
                            presets:[
                                `@babel/preset-env`
                            ]
                        },
                    }
                ]
            },
            {
                test: /\.(png|jpg)$/,
                loader: 'url-loader',
                options: {
                    limit: 10000,
                    name: '[name].[hash:8].[ext]'// Can not add path by name, because the background image will be processed by CSS again, will add CSS path // finally become CSS /img/big.1763821.png outputPath:'img/'// The output path is packaged with an extra layer publicPath:'http://cdn.com'/ / picture access path for http://cdn.com/img/big.561361.png},}, {test:/\.html$/,
                loader:'html-withimg-loader'}}, plugins: [new htmlWebpackPlugin({template:'./src/index.html'
        }),
        new miniCssExtractPlugin({
            filename:'css/[name].css'}), new cleanWebpackPlugin()]}Copy the code

Finally, after NPM run build, you can have different folders and index.html handles the path correctly.