【专项学习】 —— Webpack5从入门到精通课程学习(七)
这篇主要介绍《webpack详细配置》。(demo代码github地址)
知识点包括:
- webpack详细配置之entry
- webpack详细配置之output
- webpack详细配置之module
- webpack详细配置之resolve
- webpack详细配置之devserver
- webpack详细配置之optimization
- webpack4至webpack5详细变化
一、webpack详细配置之entry
1、新建工程文件目录如下
2、config.js中代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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代码
1 2 3 4 5 | 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
1 2 3 4 | function add(x, y) { return x + y; } export default add; |
5、count.js
1 2 3 4 | function count(x, y) { return x - y; } export default count; |
6、然后在终端命令依次输入:
1 2 3 4 | npm init webpack_entry npm i webpack webpack-cli -D npm i html-webpack-plugin -D |
然后此时工程目录如下
7、修改package.json
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | { "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全杂糅进来了。
1 | entry: './src/index.js' , //string写法 |
修改config.js文件,改为数组形式的多入口文件配置,则最终只会形成一个built.js文件,之前自己写的add.js,count.js全杂糅进来了。
在HMR功能中使用该方法。
1 | entry: [ './src/index.js' , './src/add.js' ] //array写法 |
修改config.js文件,改为对象形式(key:value)写法,有几个入口文件,就打包成几个文件,打包后文件的名称,为key的名称。
1 2 3 4 | entry: { index: './src/index.js' , add: './src/add.js' }, //对象object形式写法 |
object形式还有个特殊用法:
1 2 3 4 5 6 7 | // 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代码,增添一些对打包输出文件的相关配置。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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代码
1 2 3 4 5 6 7 8 9 10 | 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。一些常用的配置已在代码注释说明中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | 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代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | 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代码
1 | import '$css/index.css' |
5、index.css代码
1 2 3 4 5 | html, body { height: 100%; background-color: blue; } |
6、最后输入npm run dev
运行打包。
五、webpack详细配置之devserver
1、复制上一节工程文件,并重命名。注意devserver一定用于开发环境development。
2、先下载相关包,输入npm install -D webpack-dev-server
。
注意的是:
1 2 | // 开发时可直接访问到 ./build 下的静态资源,这些资源在开发中不必打包 // contentBase: resolve(__dirname, 'build'),在webpack5中不需要配置这个contentBase |
3、修改config.js代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | 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文件。
1 2 3 | import ( './a.js' ).then(({ add }) => { console.log(add(1, 2)); }); |
3、a.js代码
1 2 3 | export function add(x, y) { return x + y; } |
4、config.js代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | 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代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | 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文件
1 2 3 | export function add(x, y) { return x - y; } |
9、再重新打包。发现变化的只有我们的715.js文件和存放哈希值的文件。
10、最后还有一个对js和css文件修改压缩方案的功能,修改config.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | 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实战课程
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)