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


    这篇主要介绍《webpack详细配置》。(demo代码github地址

    知识点包括:


    一、webpack详细配置之entry

    1、新建工程文件目录如下

    2、config.js中代码

    const { resolve } = require('path');
    const HtmlwebpackPlugin = require('html-webpack-plugin')
    /**
     * entry : 入口起点有三种值
     * 1. string
     * 2. array
     * 3. object
     */
    module.exports = {
        entry: './src/index.js ',
        output: {
            filename: 'built.js',
            path: resolve(__dirname, 'build')
        },
        plugins: [
            new HtmlwebpackPlugin()
        ],
        mode: 'development'
    };
    

    3、index.js代码

    import add from './add';
    import count from './count'
    console.log('index.js文件被加载了');
    console.log(add(1, 2));
    console.log(count(2, 3));
    

    4、add.js

    function add(x, y) {
        return x + y;
    }
    export default add;
    

    5、count.js  

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

    6、然后在终端命令依次输入:  

    npm init
    webpack_entry
    npm i webpack webpack-cli -D
    npm i html-webpack-plugin -D
    

    然后此时工程目录如下  

    7、修改package.json

    {
      "name": "webpack_entry",
      "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": {
        "html-webpack-plugin": "^5.5.0",
        "webpack": "^5.65.0",
        "webpack-cli": "^4.9.1"
      }
    }

    8、然后终端命令输入npm run dev。build文件夹下生成了两个文件。  

    所以说,entry入口起点,使用string形式,输入一个单文件,则会打包形成一个built.js文件,之前自己写的add.js,count.js全杂糅进来了。

    entry: './src/index.js', //string写法
    

    修改config.js文件,改为数组形式的多入口文件配置,则最终只会形成一个built.js文件,之前自己写的add.js,count.js全杂糅进来了。

    在HMR功能中使用该方法。 

    entry: ['./src/index.js', './src/add.js'] //array写法
    

    修改config.js文件,改为对象形式(key:value)写法,有几个入口文件,就打包成几个文件,打包后文件的名称,为key的名称。  

    entry: {
        index: './src/index.js',
        add: './src/add.js'
    },//对象object形式写法
    

    object形式还有个特殊用法:  

     // object有个特殊用法
     {
     //index数组中的所有入口文件最终只会形成一个chunk,打包输出出去只有一个bundle文件。
     index: [ './src/index.js', './src/count.js'],
     //add中的入口文件形成一个chunk,打包输出一个bundle文件。
     add: './src/add.js'
     }
    

    !!!entry的object形式的两种写法,我在测试的时候执行失败,用不了,不知道是什么原因~~~~  

    二、webpack详细配置之output

    1、复制entry工程文件。并重命名。修改config.js代码,增添一些对打包输出文件的相关配置。 

    const { resolve } = require('path');
    const HtmlwebpackPlugin = require('html-webpack-plugin')
    module.exports = {
        entry: './src/index.js',
        output: {
            //文件名称(指定名称+目录)
            filename: 'built.js',
            //输出文件目录(将来所有资源输出的公共目录)
            path: resolve(__dirname, 'build'),
            // 所有资源引入公共路径的前缀,比如imgs/a.jpg' 变成 '/imgs/a.jpg'
            publicPath: '/',
            chunkFilename: 'js/[name]_chunk.js',// 非入口chunk的名称,entry指定的文件就叫入口chunk
            library: '[name]',// 整个库向外暴露的变量名
            // libraryTarget: 'window'//变量名添加到哪个上 browser上
            libraryTarget: 'global' //变量名添加到哪个上 nodejs上
    
        },
        plugins: [
            new HtmlwebpackPlugin()
        ],
        mode: 'development'
    };
    

    2、修改index.js代码 

    import count from './count'
    console.log('index.js文件被加载了');
    
    import('./add').then(({ default: add }) => {
        console.log(add(1, 2));
    });
    
    
    console.log(add(1, 2));
    console.log(count(2, 3));
    

    3、输入npm run build查看打包生成的文件,非入口文件add,被单独打包了,且在js文件夹下,名为add_js_chunk.js。index.html中引入的built.js前也加上了“/”。  

     

    三、webpack详细配置之module

    1、复制上一节工程,并重命名。修改其中的config.js。一些常用的配置已在代码注释说明中。 

    const { resolve } = require('path');
    const HtmlwebpackPlugin = require('html-webpack-plugin')
    module.exports = {
        entry: './src/index.js',
        output: {
            //文件名称(指定名称+目录)
            filename: 'built.js',
            //输出文件目录(将来所有资源输出的公共目录)
            path: resolve(__dirname, 'build'),
        },
        module: {
            rules: [
                {
                    //loder的配置
                    test: /\.css$/,
                    //多个loader用use
                    use: ['style-loader ', 'css-loader']
                },
                {
                    test: /\.js$/,
                    // exclude排除检查node_modules下的js文件
                    exclude: /node_modules/,
                    // 只检查src下的js文件
                    include: resolve(__dirname, 'src'),
                    // 优先执行
                    enforce: 'pre',
                    //单个loader用loader
                    loader: 'eslint-loader',
                },
                {
                    // 以下loader配置只会生效一个
                    oneOf: []
                }
            ]
        },
        plugins: [
            new HtmlwebpackPlugin()
        ],
        mode: 'development'
    };

    2、输入npm i eslint-loader -D下载eslint插件,然后输入npm run dev进行打包。注意的是。

    在webpack5中推荐使用eslint-webpack-plugin代替eslint-loader进行使用。

    打包后生成的文件如下

    四、webpack详细配置之resolve

    1、复制上一节工程文件,并重命名。resolve表示是解析模块的规则

    2、先下载相关包。终端输入npm i css-loader style-loader -D工程文件目录修改如下

    3、然后修改config.js代码

    const { resolve } = require('path');
    const HtmlwebpackPlugin = require('html-webpack-plugin')
    module.exports = {
        entry: './src/js/index.js',
        output: {
            //文件名称(指定名称+目录)
            filename: 'built.js',
            //输出文件目录(将来所有资源输出的公共目录)
            path: resolve(__dirname, 'build'),
        },
        module: {
            rules: [
                {
                    //loder的配置
                    test: /\.css$/,
                    //多个loader用use
                    use: ['style-loader', 'css-loader']
                },
            ]
        },
        plugins: [
            new HtmlwebpackPlugin()
        ],
        mode: 'development',
        // 解析模块的规则
        resolve: {
            //配置解析模块路径别名.优点:可以简写路径,缺点:没有路径提示了
            // 在index.js中引入css文件时,只需写$css/index.css,即自动定位到src/css文件夹,在寻找index.css
            alias: {
                $css: resolve(__dirname, 'src/css')
            },
            //省略文件路径的后缀名,比如引入index.css时,可以只写到index即可。
            extensions: ['.js', '.json', '.css'],
            // 告诉webpack 解析模块是去找哪个目录
            // 默认是node_modules
            modules: ['node_modules']
    
        }
    };
    

    4、修改index.js代码  

    import '$css/index.css'
    

    5、index.css代码

    html,
    body {
        height: 100%;
        background-color: blue;
    }
    

    6、最后输入npm run dev运行打包。

    五、webpack详细配置之devserver

    1、复制上一节工程文件,并重命名。注意devserver一定用于开发环境development

    2、先下载相关包,输入npm install -D webpack-dev-server

    注意的是:  

    // 开发时可直接访问到 ./build 下的静态资源,这些资源在开发中不必打包
    // contentBase: resolve(__dirname, 'build'),在webpack5中不需要配置这个contentBase

    3、修改config.js代码

    const { resolve } = require('path');
    const HtmlwebpackPlugin = require('html-webpack-plugin')
    module.exports = {
        entry: './src/js/index.js',
        output: {
            filename: 'built.js',
            path: resolve(__dirname, 'build'),
        },
        module: {
            rules: [
                {
                    test: /\.css$/,
                    use: ['style-loader', 'css-loader']
                },
            ]
        },
        plugins: [
            new HtmlwebpackPlugin()
        ],
        mode: 'development',
        resolve: {
            alias: {
                $css: resolve(__dirname, 'src/css')
            },
            extensions: ['.js', '.json', '.css'],
            modules: ['node_modules']
        },
        devServer: {
            // 开发时可直接访问到 ./build 下的静态资源,这些资源在开发中不必打包
            // contentBase: resolve(__dirname, 'build'),在webpack5中不需要配置这个contentBase
            //启动gzip压缩
            compress: true,
            //端口号
            port: 5000,
            //域名
            host: 'localhost',
            //自动打开浏览器
            open: true,
            //开启hmr功能
            hot: true,
            // 如果出错了,不要全屏提示
            client: {
                overlay: false,
            },
            // 服务器代理,解决开发环境的跨域问题
            proxy: {
                //一旦devServer(5000)服务器接受到/api/xxx的请求,就会把请求转发到另外一个服务器
                '/api': {
                    target: 'http://localhost:3000',
                    // 发送请求时,请求路径重写,将/api/xxx -->/xxx(去掉/api)
                    pathRewrite: {
                        '^/api': ''
                    }
                }
            }
        }
    };
    

    然后输入npm run dev先打包一下,在输入npx webpack serve启动服务器。启动成功会自动弹出一个页面。

    !!!原博主使用npx webpack serve启动成功了,我本地测试的时候启动失败,不知道什么原因~~~  

    六、webpack详细配置之optimization

    1、将详细配置resolve的工程文件复制并重命名。修改一些文件夹如下所示  

    2、其中index.js代码,写成了import动态引入的方式,所以打包后,会生成两个.js文件。 

    import('./a.js').then(({ add }) => {
        console.log(add(1, 2));
    });

    3、a.js代码

    export function add(x, y) {
        return x + y;
    }    
    

    4、config.js代码  

    const { resolve } = require('path');
    const HtmlwebpackPlugin = require('html-webpack-plugin')
    module.exports = {
        entry: './src/js/index.js',
        output: {
            filename: 'js/[name].[contenthash:10].js',
            path: resolve(__dirname, 'build'),
        },
        module: {
            rules: [
                {
                    test: /\.css$/,
                    use: ['style-loader', 'css-loader']
                },
            ]
        },
        plugins: [
            new HtmlwebpackPlugin()
        ],
        mode: 'production',
        resolve: {
            alias: {
                $css: resolve(__dirname, 'src/css')
            },
            extensions: ['.js', '.json', '.css'],
            modules: ['node_modules']
        },
        // 代码分割的配置,可以将node_modules中代码单独打包一个chunk输出
        // 自动分析多入口chunk中,有没有公共的文件。如果有会打包成单独一个chunk输出
        optimization: {
            splitChunks: {
                chunks: 'all',
                // 如果使用默认值,下边内容可以不写
                // minsize: 30 * 1024,// 分割的chunk最小为30kb,低于30kb就不分割
                // maxSize: 0,//最大没有限制
                // minChunks: 1,//要提取的chunk最少被引用1次
                // maxAsyncRequests: 5,// 按需加载时,并行加载的文件最大数量为5
                // maxInitialRequests: 3,//入口js文件最大并行请求数量
                // automaticNameDelimiter: '~',
                // name: true,// 可以使用命名规则
                // cacheGroups: {// 分割chunk的组
                //     // node_modules文件会被打包到 vendors 组的chunk中。--> vendors~xxx.js
                //     //满足上面的公共规则,如:大小超过3okb,至少被引用一次。
                //     defaultvendors: {
                //         test: /[\\/]node_modules[\\/]/,
                //         // 优先级为-10
                //         priority: -10
                //     },
                //     default: {
                //         //要提取的chunk最少被引用2次,会覆盖掉前边代码规定的公共的引用规则设定
                //         minChunks: 2,
                //         //优先级
                //         priority: -20,
                //         //如果当前要打包的模块,和之前已经被提取的模块是同一个,就会复用,而不是重新打包模块
                //         reuseExistingChunk: true
                //     }
                // }
            }
        }
    };
    

    5、输入npm run build打包结果如下  

    6、但是此时,因为文件中都带了哈希值,我们生成的main.js(对应index.js)要通过715.js(对应a.js)对应的hash值来引入里边的函数。所以当我改动a.js代码时,在打包,会发生a.js和index.js都重新打包的问题。此时需要在optimization中增加一个属性runtimeChunk

    修改config.js代码:

    const { resolve } = require('path');
    const HtmlwebpackPlugin = require('html-webpack-plugin')
    module.exports = {
        entry: './src/js/index.js',
        output: {
            filename: 'js/[name].[contenthash:10].js',
            path: resolve(__dirname, 'build'),
        },
        module: {
            rules: [
                {
                    test: /\.css$/,
                    use: ['style-loader', 'css-loader']
                },
            ]
        },
        plugins: [
            new HtmlwebpackPlugin()
        ],
        mode: 'production',
        resolve: {
            alias: {
                $css: resolve(__dirname, 'src/css')
            },
            extensions: ['.js', '.json', '.css'],
            modules: ['node_modules']
        },
        // 代码分割的配置,可以将node_modules中代码单独打包一个chunk输出
        // 自动分析多入口chunk中,有没有公共的文件。如果有会打包成单独一个chunk输出
        optimization: {
            splitChunks: {
                chunks: 'all',
                // 如果使用默认值,下边内容可以不写
                // minsize: 30 * 1024,// 分割的chunk最小为30kb,低于30kb就不分割
                // maxSize: 0,//最大没有限制
                // minChunks: 1,//要提取的chunk最少被引用1次
                // maxAsyncRequests: 5,// 按需加载时,并行加载的文件最大数量为5
                // maxInitialRequests: 3,//入口js文件最大并行请求数量
                // automaticNameDelimiter: '~',
                // name: true,// 可以使用命名规则
                // cacheGroups: {// 分割chunk的组
                //     // node_modules文件会被打包到 vendors 组的chunk中。--> vendors~xxx.js
                //     //满足上面的公共规则,如:大小超过3okb,至少被引用一次。
                //     defaultvendors: {
                //         test: /[\\/]node_modules[\\/]/,
                //         // 优先级为-10
                //         priority: -10
                //     },
                //     default: {
                //         //要提取的chunk最少被引用2次,会覆盖掉前边代码规定的公共的引用规则设定
                //         minChunks: 2,
                //         //优先级
                //         priority: -20,
                //         //如果当前要打包的模块,和之前已经被提取的模块是同一个,就会复用,而不是重新打包模块
                //         reuseExistingChunk: true
                //     }
                // }
            },
            // 将当前模块中,记录其他模块的hash值单独打包为一个文件runtime
            // 解决问题:修改a文件导致b文件的contenthash变化
            runtimeChunk: {
                name: (entrypoint) => `runtime~${entrypoint.name}`,
            },
        }
    };
    

    7、输入npm run build打包 

     8、此时改动a.js文件

    export function add(x, y) {
        return x - y;
    }    
    

    9、再重新打包。发现变化的只有我们的715.js文件和存放哈希值的文件。

    10、最后还有一个对js和css文件修改压缩方案的功能,修改config.js

    const { resolve } = require('path');
    const HtmlwebpackPlugin = require('html-webpack-plugin');
    const TerserPlugin = require("terser-webpack-plugin");
    module.exports = {
        entry: './src/js/index.js',
        output: {
            filename: 'js/[name].[contenthash:10].js',
            path: resolve(__dirname, 'build'),
        },
        module: {
            rules: [
                {
                    test: /\.css$/,
                    use: ['style-loader', 'css-loader']
                },
            ]
        },
        plugins: [
            new HtmlwebpackPlugin()
        ],
        mode: 'production',
        resolve: {
            alias: {
                $css: resolve(__dirname, 'src/css')
            },
            extensions: ['.js', '.json', '.css'],
            modules: ['node_modules']
        },
        // 代码分割的配置,可以将node_modules中代码单独打包一个chunk输出
        // 自动分析多入口chunk中,有没有公共的文件。如果有会打包成单独一个chunk输出
        optimization: {
            splitChunks: {
                chunks: 'all',
                // 如果使用默认值,下边内容可以不写
                // minsize: 30 * 1024,// 分割的chunk最小为30kb,低于30kb就不分割
                // maxSize: 0,//最大没有限制
                // minChunks: 1,//要提取的chunk最少被引用1次
                // maxAsyncRequests: 5,// 按需加载时,并行加载的文件最大数量为5
                // maxInitialRequests: 3,//入口js文件最大并行请求数量
                // automaticNameDelimiter: '~',
                // name: true,// 可以使用命名规则
                // cacheGroups: {// 分割chunk的组
                //     // node_modules文件会被打包到 vendors 组的chunk中。--> vendors~xxx.js
                //     //满足上面的公共规则,如:大小超过3okb,至少被引用一次。
                //     defaultvendors: {
                //         test: /[\\/]node_modules[\\/]/,
                //         // 优先级为-10
                //         priority: -10
                //     },
                //     default: {
                //         //要提取的chunk最少被引用2次,会覆盖掉前边代码规定的公共的引用规则设定
                //         minChunks: 2,
                //         //优先级
                //         priority: -20,
                //         //如果当前要打包的模块,和之前已经被提取的模块是同一个,就会复用,而不是重新打包模块
                //         reuseExistingChunk: true
                //     }
                // }
            },
            // 将当前模块中,记录其他模块的hash值单独打包为一个文件runtime
            // 解决问题:修改a文件导致b文件的contenthash变化
            runtimeChunk: {
                name: (entrypoint) => `runtime~${entrypoint.name}`,
            },
            minimizer: [
                //配置生产环境的压缩方案:js和css
                // 需要下载插件terser-webpack-plugin
                // webpack v5 开箱即带有最新版本的 terser-webpack-plugin
                new TerserPlugin({
                    // 开启多进程打包
                    parallel: true,
                })
            ]
        }
    };
    

    七、webpack4至webpack5详细变化

    请见此处。  


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

  • 相关阅读:
    png-8 和 png-24的区别
    css控制标题长度超出部分显示省略号
    php正则表达式
    10分钟了解JSON Web令牌(JWT)
    Python制作微信小助手
    优质网站、赚钱、教程、分享、网赚
    从Github上将laravel项目拉到新开发环境
    gitlab添加公钥
    Git 配置用户名、密码
    虚拟机Oracle VM VirtualBox linux系统如何访问windows共享文件夹
  • 原文地址:https://www.cnblogs.com/ljq66/p/15984314.html
Copyright © 2020-2023  润新知