• 【专项学习】 —— Webpack5从入门到精通课程学习(五)


    这篇主要介绍《webpack优化环境配置(中)》。(demo代码github地址

    知识点包括:

    1. 第一种方法
    2. 第二种方法
    3. 第三种方法

    一、tree shaking

    1、复制上一篇的生产环境缓存工程文件。然后重命名。

    tree shaking(树摇)去除无用的代码

    2、在src文件夹下新建test.js,测试使用该功能,是否会把没有引用的js代码也打包。

    test.js代码如下,两个函数都使用export暴露出去。

    export function mul(x, y) {
        return x * y;
    }
    export function count(x, y) {
        return x - y;
    }
    

    3、index.js代码,我们只引入test.js中的一个mul函数,那么count函数就没有被用到,那么使用tree shaking后,打包后的文件应该没有count函数,被去掉了。

    import '../css/index.css';
    // 引入icon-font样式文件
    import '../iconfit/iconfont.css';
    
    // 只引入test.js中的一个mul函数
    import { mul } from './test';
    
    function sum(...args) {
      return args.reduce((p, c) => p + c, 0);
    }
    
    
    console.log(mul(2, 2));
    
    console.log(sum(1, 2, 3, 4));
    

    4、config中需要修改运行环境为production环境,注释说明入代码中所写

    const { resolve } = require('path');
    const minicssextractplugin = require('mini-css-extract-plugin');
    const cssminimizerwebpackplugin = require('css-minimizer-webpack-plugin');
    const Htmlwebpackplugin = require('html-webpack-plugin');
    
    // css浏览器兼容性处理,默认是运行在生产环境下,若要运行于开发环境,还需做以下代码
    process.env.NODE_ENV = 'production'
    
    // tree shaking:去除无用代码
    //前提: 1.必须使用ES6模块化2.开启production环境
    //作用:减少代码体积
    //在package.json中配置"sideEffects" : false所有代码都没有副作用(都可以进行tree shaking)
    //问题:可能会把css/@babel/polyfill (副作用)文件干掉,因为这些文件都是引入了,但没有直接使用
    //,所以需要配置为"sideEffects" : ["*.css"]
    
    module.exports = {
        entry: {
            // 把之前的单入口修改为多入口
            // 有几个入口,打包就生成几个built.js
            index: './src/js/index.js',
            test: './src/js/test.js'
        },
        output: {
            // [name]:取entry中的入口文件名进行命名
            filename: 'js/[name].[contenthash:10].js',
            path: resolve(__dirname, 'build')
        },
        module: {
            rules: [{
                // oneOf 是每一个文件,只匹配到一个loader即可,
                // 不像之前,每个文件都要把下列loader全部匹配一遍
                // 注意不能有两个loader处理同一个类型文件
                oneOf: [
                    {
                        // 检测css文件,并打包
                        test: /\.css$/,
                        use: [
                            minicssextractplugin.loader,
                            'css-loader',
                            {
                                // 对css做兼容性处理
                                // 还需要在package.json中定义browserslist
                                loader: 'postcss-loader',
                                options: {
                                    postcssOptions: {
                                        plugins: [require('postcss-preset-env')()]
                                    }
                                }
                            }
                        ]
                    },
                    {
                        // 检测less文件,并打包
                        test: /\.less$/,
                        // use内代码,是从下往上的顺序执行的
                        use: [
                            minicssextractplugin.loader,
                            'css-loader',
                            {
                                // 还需要在package.json中定义browserslist
                                loader: 'postcss-loader',
                                options: {
                                    postcssOptions: {
                                        plugins: [require('postcss-preset-env')()]
                                    }
                                }
                            },
                            'less-loader'
                        ]
                    },
                    {
                        // js兼容性处理
                        test: /\.js$/,
                        exclude: /node_modules/,
                        loader: 'babel-loader',
                        options: {
                            presets: [
                                [
                                    '@babel/preset-env', {
                                        useBuiltIns: 'usage',
                                        corejs:
                                        {
                                            version: 3
                                        },
                                        targets: {
                                            // 浏览器兼容的版本
                                            chrome: '60',
                                            firefox: '50'
                                        }
                                    }
                                ]
                            ]
                        }
        
                    },
                    {
                        //对图片进行打包处理
                        test: /\.(jpg|png|gif)$/,
                        loader: 'url-loader',
                        options: {
                            limit: 8 * 1024,
                            outputPath: 'imgs',
                            esModule: false
                        },
                        type: 'javascript/auto'
                    },
                    {
                        // 处理html中的图片文件
                        test: /\.html$/,
                        loader: 'html-loader',
                        options: {
                            esModule: false,
                        }
        
                    },
                    {
                        // 处理其他文件,如字体图标等
                        exclude: /\.(js|css|less|html|jpg|png|gif)$/,
                        loader: 'file-loader',
                        options: {
                            outputPath: 'media',
                            esModule: false,
                        },
                        type: 'javascript/auto'
                    }
                ]
            }]    
        },
        plugins: [
            new minicssextractplugin({
                // 打包提取成单独文件
                filename: 'css/built.[contenthash:10].css'
            }),
            new cssminimizerwebpackplugin(
                // 压缩css文件
            ),
            new Htmlwebpackplugin({
                template: './src/index.html',
                // 压缩html
                minify: {
                    collapseWhitespace: true,
                    removeComments: true
                }
            })
        ],
        // 生产环境下,js自动压缩
        mode: 'production'
    }
    

    5、package.json中代码

    {
      "name": "webpack_production",
      "version": "1.0.0",
      "description": "",
      "main": "webpack.config.js",
      "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1",
        "dev": "webpack --mode development",
        "build": "webpack --mode production"
      },
      "author": "",
      "license": "ISC",
      "devDependencies": {
        "@babel/core": "^7.16.5",
        "@babel/preset-env": "^7.16.5",
        "babel-loader": "^8.2.3",
        "core-js": "^3.21.1",
        "css-loader": "^6.5.1",
        "css-minimizer-webpack-plugin": "^3.3.1",
        "eslint": "^8.10.0",
        "eslint-config-airbnb-base": "^15.0.0",
        "eslint-plugin-import": "^2.25.4",
        "eslint-webpack-plugin": "^3.1.1",
        "file-loader": "^6.2.0",
        "html-loader": "^3.0.1",
        "html-webpack-plugin": "^5.5.0",
        "less-loader": "^10.2.0",
        "mini-css-extract-plugin": "^2.4.5",
        "postcss-loader": "^6.2.1",
        "postcss-preset-env": "^7.1.0",
        "style-loader": "^3.3.1",
        "url-loader": "^4.1.1",
        "webpack": "^5.65.0",
        "webpack-cli": "^4.9.1"
      },
      "browserslist": {
        "development": [
          "last 1 chrome version",
          "last 1 firefox version",
          "last 1 safari version"
        ],
        "production": [
          ">0.2%",
          "not dead",
          "not op_mini all"
        ]
      },
      "sideEffects": [
        "*.css"
      ]
    }
    

    注意:为了能够识别ES6模块,需要下载core-js包。输入npm i core-js -D然后输入npm run build即可进行打包。

    最后打包成功的built.js中只包含了引入并使用的mul函数,未被引入和使用的count函数并没有被打包进来。 

    二、code split(代码分割)

    第一种方法

    代码分割会把打包的一个大文件分割成多个不同的文件,这样在加载的时候就会并行加载,速度更快。还可以实现按需下载。

    1、复制上一小节工程文件,并重命名。

    在src下的js文件夹中有两个.js文件,我们以往打包是最后只生成了一个built.js文件,如果想生成两个呢。

    2、首先修改index.js代码,去除引入的test.js代码

    import '../css/index.css';
    // 引入icon-font样式文件
    import '../iconfit/iconfont.css';
    
    
    function sum(...args) {
      return args.reduce((p, c) => p + c, 0);
    }
    
    console.log(sum(1, 2, 3, 4));
    

    2、修改webpck.config.js代码

    const { resolve } = require('path');
    const minicssextractplugin = require('mini-css-extract-plugin');
    const cssminimizerwebpackplugin = require('css-minimizer-webpack-plugin');
    const Htmlwebpackplugin = require('html-webpack-plugin');
    
    // css浏览器兼容性处理,默认是运行在生产环境下,若要运行于开发环境,还需做以下代码
    process.env.NODE_ENV = 'production'
    
    // tree shaking:去除无用代码
    //前提: 1.必须使用ES6模块化2.开启production环境
    //作用:减少代码体积
    //在package.json中配置"sideEffects" : false所有代码都没有副作用(都可以进行tree shaking)
    //问题:可能会把css/@babel/polyfill (副作用)文件干掉,因为这些文件都是引入了,但没有直接使用
    //,所以需要配置为"sideEffects" : ["*.css"]
    
    module.exports = {
        entry: {
            // 把之前的单入口修改为多入口
            // 有几个入口,打包就生成几个built.js
            index: './src/js/index.js',
            test: './src/js/test.js'
        },
        output: {
            // [name]:取entry中的入口文件名进行命名
            filename: 'js/[name].[contenthash:10].js',
            path: resolve(__dirname, 'build')
        },
        module: {
            rules: [{
                // oneOf 是每一个文件,只匹配到一个loader即可,
                // 不像之前,每个文件都要把下列loader全部匹配一遍
                // 注意不能有两个loader处理同一个类型文件
                oneOf: [
                    {
                        // 检测css文件,并打包
                        test: /\.css$/,
                        use: [
                            minicssextractplugin.loader,
                            'css-loader',
                            {
                                // 对css做兼容性处理
                                // 还需要在package.json中定义browserslist
                                loader: 'postcss-loader',
                                options: {
                                    postcssOptions: {
                                        plugins: [require('postcss-preset-env')()]
                                    }
                                }
                            }
                        ]
                    },
                    {
                        // 检测less文件,并打包
                        test: /\.less$/,
                        // use内代码,是从下往上的顺序执行的
                        use: [
                            minicssextractplugin.loader,
                            'css-loader',
                            {
                                // 还需要在package.json中定义browserslist
                                loader: 'postcss-loader',
                                options: {
                                    postcssOptions: {
                                        plugins: [require('postcss-preset-env')()]
                                    }
                                }
                            },
                            'less-loader'
                        ]
                    },
                    {
                        // js兼容性处理
                        test: /\.js$/,
                        exclude: /node_modules/,
                        loader: 'babel-loader',
                        options: {
                            presets: [
                                [
                                    '@babel/preset-env', {
                                        useBuiltIns: 'usage',
                                        corejs:
                                        {
                                            version: 3
                                        },
                                        targets: {
                                            // 浏览器兼容的版本
                                            chrome: '60',
                                            firefox: '50'
                                        }
                                    }
                                ]
                            ]
                        }
        
                    },
                    {
                        //对图片进行打包处理
                        test: /\.(jpg|png|gif)$/,
                        loader: 'url-loader',
                        options: {
                            limit: 8 * 1024,
                            outputPath: 'imgs',
                            esModule: false
                        },
                        type: 'javascript/auto'
                    },
                    {
                        // 处理html中的图片文件
                        test: /\.html$/,
                        loader: 'html-loader',
                        options: {
                            esModule: false,
                        }
        
                    },
                    {
                        // 处理其他文件,如字体图标等
                        exclude: /\.(js|css|less|html|jpg|png|gif)$/,
                        loader: 'file-loader',
                        options: {
                            outputPath: 'media',
                            esModule: false,
                        },
                        type: 'javascript/auto'
                    }
                ]
            }]    
        },
        plugins: [
            new minicssextractplugin({
                // 打包提取成单独文件
                filename: 'css/built.[contenthash:10].css'
            }),
            new cssminimizerwebpackplugin(
                // 压缩css文件
            ),
            new Htmlwebpackplugin({
                template: './src/index.html',
                // 压缩html
                minify: {
                    collapseWhitespace: true,
                    removeComments: true
                }
            })
        ],
        // 生产环境下,js自动压缩
        mode: 'production'
    }
    

    最后打包生成的文件,这就是对js文件进行了代码分割,通过修改入口文件的方法。  

    第二种方法

    1、我们将config.js代码的入口文件改回一个,并使用一个内置的配置splitChunks开启代码分割功能

    const { resolve } = require('path');
    const minicssextractplugin = require('mini-css-extract-plugin');
    const cssminimizerwebpackplugin = require('css-minimizer-webpack-plugin');
    const Htmlwebpackplugin = require('html-webpack-plugin');
    
    // css浏览器兼容性处理,默认是运行在生产环境下,若要运行于开发环境,还需做以下代码
    process.env.NODE_ENV = 'production'
    
    // tree shaking:去除无用代码
    //前提: 1.必须使用ES6模块化2.开启production环境
    //作用:减少代码体积
    //在package.json中配置"sideEffects" : false所有代码都没有副作用(都可以进行tree shaking)
    //问题:可能会把css/@babel/polyfill (副作用)文件干掉,因为这些文件都是引入了,但没有直接使用
    //,所以需要配置为"sideEffects" : ["*.css"]
    
    module.exports = {
        entry: './src/js/index.js',
        output: {
            // [name]:取entry中的入口文件名进行命名
            filename: 'js/[name].[contenthash:10].js',
            path: resolve(__dirname, 'build')
        },
        module: {
            rules: [{
                // oneOf 是每一个文件,只匹配到一个loader即可,
                // 不像之前,每个文件都要把下列loader全部匹配一遍
                // 注意不能有两个loader处理同一个类型文件
                oneOf: [
                    {
                        // 检测css文件,并打包
                        test: /\.css$/,
                        use: [
                            minicssextractplugin.loader,
                            'css-loader',
                            {
                                // 对css做兼容性处理
                                // 还需要在package.json中定义browserslist
                                loader: 'postcss-loader',
                                options: {
                                    postcssOptions: {
                                        plugins: [require('postcss-preset-env')()]
                                    }
                                }
                            }
                        ]
                    },
                    {
                        // 检测less文件,并打包
                        test: /\.less$/,
                        // use内代码,是从下往上的顺序执行的
                        use: [
                            minicssextractplugin.loader,
                            'css-loader',
                            {
                                // 还需要在package.json中定义browserslist
                                loader: 'postcss-loader',
                                options: {
                                    postcssOptions: {
                                        plugins: [require('postcss-preset-env')()]
                                    }
                                }
                            },
                            'less-loader'
                        ]
                    },
                    {
                        // js兼容性处理
                        test: /\.js$/,
                        exclude: /node_modules/,
                        loader: 'babel-loader',
                        options: {
                            presets: [
                                [
                                    '@babel/preset-env', {
                                        useBuiltIns: 'usage',
                                        corejs:
                                        {
                                            version: 3
                                        },
                                        targets: {
                                            // 浏览器兼容的版本
                                            chrome: '60',
                                            firefox: '50'
                                        }
                                    }
                                ]
                            ]
                        }
        
                    },
                    {
                        //对图片进行打包处理
                        test: /\.(jpg|png|gif)$/,
                        loader: 'url-loader',
                        options: {
                            limit: 8 * 1024,
                            outputPath: 'imgs',
                            esModule: false
                        },
                        type: 'javascript/auto'
                    },
                    {
                        // 处理html中的图片文件
                        test: /\.html$/,
                        loader: 'html-loader',
                        options: {
                            esModule: false,
                        }
        
                    },
                    {
                        // 处理其他文件,如字体图标等
                        exclude: /\.(js|css|less|html|jpg|png|gif)$/,
                        loader: 'file-loader',
                        options: {
                            outputPath: 'media',
                            esModule: false,
                        },
                        type: 'javascript/auto'
                    }
                ]
            }]    
        },
        plugins: [
            new minicssextractplugin({
                // 打包提取成单独文件
                filename: 'css/built.[contenthash:10].css'
            }),
            new cssminimizerwebpackplugin(
                // 压缩css文件
            ),
            new Htmlwebpackplugin({
                template: './src/index.html',
                // 压缩html
                minify: {
                    collapseWhitespace: true,
                    removeComments: true
                }
            })
        ],
        // 代码分割的配置,可以将node_modules中代码单独打包一个chunk输出
        // 自动分析多入口chunk中,有没有公共的文件。如果有会打包成单独一个chunk输出
        optimization: {
            splitChunks: {
                chunks: 'all'
            }
        },
        // 生产环境下,js自动压缩
        mode: 'production'
    }
    

    2、然后修改index.js代码,增加一个官方的node_modules(jquery)。

    import '../css/index.css';
    // 引入icon-font样式文件
    import '../iconfit/iconfont.css';
    // 引入jquery
    import $ from 'jquery';
    
    
    function sum(...args) {
      return args.reduce((p, c) => p + c, 0);
    }
    
    console.log($);
    
    console.log(sum(1, 2, 3, 4));
    

    3、然后安装jquery,npm i jquery --save,最后打包npm run build

    会将自己编写的index.js和jquery有关的js分开生成,即生成两个.js文件。

    第三种方法

    第三种方法是通过修改index.js文件实现的,import动态导入语法,能将某个文件单独打包,config.js中入口还是修改为单入口

    我们希望除了官方的node_modules,其他使用的js文件也可以被分割打包出来

    1、首先把config.js中的第二种方法使用的插件去掉。

    const { resolve } = require('path');
    const minicssextractplugin = require('mini-css-extract-plugin');
    const cssminimizerwebpackplugin = require('css-minimizer-webpack-plugin');
    const Htmlwebpackplugin = require('html-webpack-plugin');
    
    // css浏览器兼容性处理,默认是运行在生产环境下,若要运行于开发环境,还需做以下代码
    process.env.NODE_ENV = 'production'
    
    // tree shaking:去除无用代码
    //前提: 1.必须使用ES6模块化2.开启production环境
    //作用:减少代码体积
    //在package.json中配置"sideEffects" : false所有代码都没有副作用(都可以进行tree shaking)
    //问题:可能会把css/@babel/polyfill (副作用)文件干掉,因为这些文件都是引入了,但没有直接使用
    //,所以需要配置为"sideEffects" : ["*.css"]
    
    module.exports = {
        entry: './src/js/index.js',
        output: {
            // [name]:取entry中的入口文件名进行命名
            filename: 'js/[name].[contenthash:10].js',
            path: resolve(__dirname, 'build')
        },
        module: {
            rules: [{
                // oneOf 是每一个文件,只匹配到一个loader即可,
                // 不像之前,每个文件都要把下列loader全部匹配一遍
                // 注意不能有两个loader处理同一个类型文件
                oneOf: [
                    {
                        // 检测css文件,并打包
                        test: /\.css$/,
                        use: [
                            minicssextractplugin.loader,
                            'css-loader',
                            {
                                // 对css做兼容性处理
                                // 还需要在package.json中定义browserslist
                                loader: 'postcss-loader',
                                options: {
                                    postcssOptions: {
                                        plugins: [require('postcss-preset-env')()]
                                    }
                                }
                            }
                        ]
                    },
                    {
                        // 检测less文件,并打包
                        test: /\.less$/,
                        // use内代码,是从下往上的顺序执行的
                        use: [
                            minicssextractplugin.loader,
                            'css-loader',
                            {
                                // 还需要在package.json中定义browserslist
                                loader: 'postcss-loader',
                                options: {
                                    postcssOptions: {
                                        plugins: [require('postcss-preset-env')()]
                                    }
                                }
                            },
                            'less-loader'
                        ]
                    },
                    {
                        // js兼容性处理
                        test: /\.js$/,
                        exclude: /node_modules/,
                        loader: 'babel-loader',
                        options: {
                            presets: [
                                [
                                    '@babel/preset-env', {
                                        useBuiltIns: 'usage',
                                        corejs:
                                        {
                                            version: 3
                                        },
                                        targets: {
                                            // 浏览器兼容的版本
                                            chrome: '60',
                                            firefox: '50'
                                        }
                                    }
                                ]
                            ]
                        }
        
                    },
                    {
                        //对图片进行打包处理
                        test: /\.(jpg|png|gif)$/,
                        loader: 'url-loader',
                        options: {
                            limit: 8 * 1024,
                            outputPath: 'imgs',
                            esModule: false
                        },
                        type: 'javascript/auto'
                    },
                    {
                        // 处理html中的图片文件
                        test: /\.html$/,
                        loader: 'html-loader',
                        options: {
                            esModule: false,
                        }
        
                    },
                    {
                        // 处理其他文件,如字体图标等
                        exclude: /\.(js|css|less|html|jpg|png|gif)$/,
                        loader: 'file-loader',
                        options: {
                            outputPath: 'media',
                            esModule: false,
                        },
                        type: 'javascript/auto'
                    }
                ]
            }]    
        },
        plugins: [
            new minicssextractplugin({
                // 打包提取成单独文件
                filename: 'css/built.[contenthash:10].css'
            }),
            new cssminimizerwebpackplugin(
                // 压缩css文件
            ),
            new Htmlwebpackplugin({
                template: './src/index.html',
                // 压缩html
                minify: {
                    collapseWhitespace: true,
                    removeComments: true
                }
            })
        ],
        // 代码分割的配置,可以将node_modules中代码单独打包一个chunk输出
        // 自动分析多入口chunk中,有没有公共的文件。如果有会打包成单独一个chunk输出
        optimization: {
            splitChunks: {
                chunks: 'all'
            }
        },
        // 生产环境下,js自动压缩
        mode: 'production'
    }
    

    2、修改index.js代码,import动态导入语法,能将某个文件单独打包

    import '../css/index.css';
    // 引入icon-font样式文件
    import '../iconfit/iconfont.css';
    
    
    function sum(...args) {
      return args.reduce((p, c) => p + c, 0);
    }
    
    console.log(sum(1, 2, 3, 4));
    
    // 通过js代码,实现代码分割功能。以ES10的方法引入test.js
    // import动态导入语法,能将某个文件单独打包
    // webpackChunkName:'test'表示打包后的文件名为test
    import(/*webpackChunkName:'test'*/'../js/test')
      .then((result) => {
        console.log(result);
      })
      .catch(() => {
        console.log('文件加载失败~');
      })
    

    3、输入npm run build打包


    注:笔记转载自疯子的梦想@博客,课程来自尚硅谷b站Webpack5实战课程

  • 相关阅读:
    Linux信号列表(zz)
    TCP状态转移图学习总结
    UNP学习笔记之四select和poll
    RSS2.0结构
    UNP学习笔记二简单的并发服务器(concurrent servers)
    js面向对象基础(zz)
    libevent introduction
    Linux下Makefile的automake生成全攻略(zz)
    UNP学习笔记之三POSIX Signal Handling
    关于网络编程(服务端)的一些笔记(zz)
  • 原文地址:https://www.cnblogs.com/ljq66/p/15979657.html
Copyright © 2020-2023  润新知