webpack官网
powershell使用教程
在cmd中输入powershell即可直接进入,或者通过vscode进入。
发现一个网页的小技巧,即可修改内容
1
| document.body.contentEditable=true
|
关于js的加载顺序理解,script脚本async和defer的区别
今天看极限挑战,慢步人生路,太有感触了。
严敏一句话,“我们少年时期呢,兜里没有很多钱,但是,另一半的生活很精彩”,很真实了。
我大致在知乎上看了一眼极限挑战的前世今生,文章一看就是个写热文蹭流量那种,不过事实也八九不离十。不仅有很多感慨,或许这就是现实吧。
比方说我现在周末想看个电影,一般都是追忆老电影了,像李连杰、吴京、周星驰系列,漫威系列,以及其他一些老电影,现在新出的电影基本不看,电视剧更不看了。现在整个影视行业的流向就是只要能吸引来流量,干啥都行,无底线。
比方说之前翻拍动漫的魔道祖师、斗破苍穹,以及现在正在拍的斗罗大陆,我看了几眼,说实话,真的恶心。但是网上还有大片大片的狂热女粉,或许她们眼里只要人长得好看,拍得烂不烂都无所谓了。
资本决定了影视行业的流向,资本同样影响了大部分人的价值观,在这个纷扰的社会里,做真自己,太难了。
一、webpack初体验
npm i 跟 npm install 类似又不类似,百度即可
1 2 3 4
| npm install webpack webpack-cli npm install webpack webpack-cli -g npm install webpack webpack-cli -D npm install webpack webpack-cli -S
|
卸载的话,只需要将install换成uninstall即可,用法如上
开发环境命令:
1
| webpack ./src/index.js -o ./build/build.js --mode=development
|
webpack会以.src/index.js 为入口文件开始打包,打包后输出到./build/build.js
整体打包环境,是开发环境
生产环境命令:
1
| webpack ./src/index.js -o ./build/build.js --mode=production
|
webpack会以.src/index.js 为入口文件开始打包,打包后输出到./build/build.js
整体打包环境,是生产环境
结论
- webpack能处理js/json,不能处理css/img等资源
- 生产环境和开发环境将es6模块化编译成浏览器能识别的模块化
- 生产环境比开发环境多一个压缩js代码
二、webpack开发环境
2.1 打包样式资源
下载需要用到的包
- css-loader
- style-loader
- less-loader
- less
webpack.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
|
const { resolve } = require("path"); module.exports = {
entry: "./src/index.js", output: { filename: "built.js", path: resolve(__dirname, "build") }, module: { rules: [
{ test:/\.css$/, use:[ "style-loader", "css-loader" ]
}, { test:/\.less$/, use:[ "style-loader", "css-loader", "less-loader" ] } ]
}, plugins: [ ], mode: "development", }
|
2.2 打包HTML资源
下载需要用到的包
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
|
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:[
], }, plugins:[ new HtmlWebpackPlugin({ template:"./src/index.html" }) ], mode:"development" }
|
2.3 打包图片资源
下载需要用到的包
- url-loader
- file-loader
- html-loader
webpack.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
| 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: [ { test: /\.less$/, use: [ 'style-loader', 'css-loader', 'less-loader',
] }, { test:/\.(jpg|png|gif)$/, loader:"url-loader", options:{ limit:8*1024,
esModule:false, name:"[hash:5].[ext]" } }, { test:/\.html$/, loader:"html-loader"
} ] }, plugins: [ new HtmlWebpackPlugin({ template: "./src/index.html" }) ], mode:"development" }
|
2.4 打包其他资源
webpack.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
| 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: [ { test: /\.less$/, use: [ "style-loader", "css-loader", "less-loader" ] }, { exclude: /\.(css|js|html|less)$/, loader: "file-loader", options:{ name:'[hash:5].[ext]' } } ] }, plugins: [ new HtmlWebpackPlugin({ template: "./src/index.html" }) ], mode: "development" }
|
2.5 devServer
修改配置文件
webpack.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
| 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: [ { test: /\.less$/, use: [ "style-loader", "css-loader", "less-loader" ] }, { exclude: /\.(css|js|html|less)$/, loader: "file-loader", options: { name: '[hash:5].[ext]' } } ] }, plugins: [ new HtmlWebpackPlugin({ template: "./src/index.html" }) ], mode: "development", devServer: { disableHostCheck: true,
open:true, contentBase: resolve(__dirname, "build"), compress: true, port: 8080 } }
|
运行命令,即可自动打开浏览器执行
2.6 开发环境基本配置
webpack.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 76 77 78 79 80 81
|
const { resolve } = require("path"); const HtmlWebpackPlugin = require("html-webpack-plugin"); module.exports = { entry: "./src/js/index.js", output: { filename: 'js/built.js', path: resolve(__dirname, "build") }, module: { rules: [ { test: /\.less$/, use: [ 'style-loader', 'css-loader', 'less-loader' ] }, { test: /\.css$/, use: [ 'style-loader', 'css-loader' ] }, { test: /\.(jpg||png||gif)$/, loader: "url-loader", options: { limit: 8 * 1024, name: "[hash:10].[ext]", esModule: false, outputPath:"imgs" } }, { test: /\.html$/, loader: "html-loader", }, { exclude: /\.(html|css|js|less|jpg|png|gif)$/, loader: "file-loader", options: { name: "[hash:10].[ext]", outputPath:"media" } } ] }, plugins: [ new HtmlWebpackPlugin({ template: "./src/index.html" }) ], mode:"development", devServer: { contentBase: resolve(__dirname, "build"), compress: true, port: 8080, open: true } }
|
三、webpack生产环境
3.1 css提取
webpack.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
| const {resolve}=require("path"); const HtmlWebpackPlugin = require("html-webpack-plugin");
const miniCssExtractPlugin=require("mini-css-extract-plugin"); module.exports={ entry:"./src/js/index.js", output:{ filename:"./js/built.js", path:resolve(__dirname,"build"), }, module:{ rules:[ { test:/\.css$/, use:[ miniCssExtractPlugin.loader, "css-loader" ] } ] }, plugins:[ new HtmlWebpackPlugin({ template:"./src/index.html" }), new miniCssExtractPlugin({ filename:"./css/built.css" }) ], mode:"development" }
|
3.2 css兼容性处理
需要安装的插件
1
| npm install postcss-loader postcss-preset-env -D
|
webpack.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
| const { resolve } = require("path"); const HtmlWebpackPlugin = require("html-webpack-plugin");
const miniCssExtractPlugin = require("mini-css-extract-plugin"); module.exports = { entry: "./src/js/index.js", output: { filename: "./js/built.js", path: resolve(__dirname, "build"), }, module: { rules: [ { test: /\.css$/, use: [ miniCssExtractPlugin.loader, "css-loader",
{ loader: "postcss-loader", options: { ident: "postcss", plugins: () => [ require("postcss-preset-env") ] } } ] } ] }, plugins: [ new HtmlWebpackPlugin({ template: "./src/index.html" }), new miniCssExtractPlugin({ filename: "./css/built.css" }) ], mode: "development" }
|
关于browserslist的配置,可以在github搜索获得
3.3 压缩css
安装插件
1
| npm install optimize-css-assets-webpack-plugin -D
|
webpack.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 76 77 78
| const { resolve } = require("path"); const HtmlWebpackPlugin = require("html-webpack-plugin");
process.env.NODE_ENV="development";
const optimizeCssAssetsWebpack=require("optimize-css-assets-webpack-plugin");
const miniCssExtractPlugin = require("mini-css-extract-plugin"); module.exports = { entry: "./src/js/index.js", output: { filename: "./js/built.js", path: resolve(__dirname, "build"), }, module: { rules: [ { test: /\.css$/, use: [ miniCssExtractPlugin.loader, "css-loader",
{ loader: "postcss-loader", options: { ident: "postcss", plugins: () => [ require("postcss-preset-env") ] } } ] } ] }, plugins: [ new HtmlWebpackPlugin({ template: "./src/index.html" }), new miniCssExtractPlugin({ filename: "./css/built.css" }), new optimizeCssAssetsWebpack() ], mode: "development" }
|
3.4 js语法检查
可以参照js规则
1
| npm install eslint-config-airbnb-base eslint eslint-plugin-import eslint-loader -D
|
webpack.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 HtmlWebpackPlugin = require("html-webpack-plugin"); const {resolve}=require("path"); module.exports={ entry:"./src/js/index.js", output:{ filename:"js/built.js", path:resolve(__dirname,"build") }, module:{ rules:[
{ test:/\.js$/, exclude:/node-modules/, loader:"eslint-loader", options:{ fix:true } } ] }, plugins:[ new HtmlWebpackPlugin({ template:"./src/index.html" }), ], mode:"development" }
|
3.5 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
| const HtmlWebpackPlugin = require("html-webpack-plugin"); const {resolve}=require("path"); module.exports={ entry:"./src/js/index.js", output:{ filename:"js/built.js", path:resolve(__dirname,"build") }, module:{ rules:[
{ test:/\.js$/, exclude:/node_modules/, loader:"babel-loader", options:{ presets:[ [ "@babel/preset-env", { useBuiltIns:"usage", corejs:{ version:3 }, targets:{ chrome:"60", firefox:"50", ie:"9", safari:"10", edge:"17" } } ] ], } } ] }, plugins:[ new HtmlWebpackPlugin({ template:"./src/index.html" }), ], mode:"development" }
|
3.6 压缩html与js
webpack.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
| const HtmlWebpackPlugin = require("html-webpack-plugin"); const {resolve}=require("path"); module.exports={ entry:"./src/js/index.js", output:{ filename:"js/built.js", path:resolve(__dirname,"build") }, plugins:[ new HtmlWebpackPlugin({ template:"./src/index.html", minify:{ collapseWhitespace:true, removeComments:true } }), ], mode:"production" }
|
3.7 生产环境基本配置
webpack.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 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
| const { resolve } = require("path"); const miniCssExtractPlugin = require("mini-css-extract-plugin"); const optimizeCssAssetsWebpackPlugin=require("optimize-css-assets-webpack-plugin"); const HtmlWebpackPlugin = require("html-webpack-plugin");
process.env.NODE_ENV = "production";
const commonCssLoader = [ miniCssExtractPlugin.loader, "css-loader", { loader: "postcss-loader", options: { ident: "postcss", plugins: () => [ require("postcss-preset-env")() ] } } ]; module.exports = { entry: "./src/js/index.js", output: { filename: "js/built.js", path: resolve(__dirname, "build") }, module: { rules: [ { test: /\.css$/, use: [ ...commonCssLoader ] }, { test: /\.less$/, use: [ ...commonCssLoader, "less-loader" ] },
{ test:/\.js$/, exclude:/node_modules/, loader:"eslint-loader", options:{ fix:true }, enforce:"pre" }, { test:/\.js$/, exclude:/node_modules/, loader:"babel-loader", options:{ presets:[ [ "@babel/preset-env", { useBuiltIns:"usage", corejs:{version:3}, targets:{ chrome:"60", firefox:"50", ie:"9", safari:"10", edge:"17" } } ], ] } }, { test:/\.(jpg|png|gif)$/, loader:"url-loader", options:{ limit:8*1024, name:"[hash:10].[ext]", outputPath:"imgs", esModule:false } }, { test:/\.html$/, loader:"html-loader", }, { exclude:/\.(js|css|less|html|jpg|png|gif)$/, loader:"file-loader", options:{ outputPath:"media" } }
] }, plugins: [ new miniCssExtractPlugin({ filename: "css/built.css" }), new optimizeCssAssetsWebpackPlugin(), new HtmlWebpackPlugin({ template:"./src/index.html", minify:{ collapseWhitespace:true, removeComments:true } })
], mode: "production", devServer: { disableHostCheck: true,
open:true, contentBase: resolve(__dirname, "build"), compress: true, port: 8080 } }
|
四、webpack优化配置
4.1 HMR
webpack.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 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
|
const { resolve } = require("path"); const HtmlWebpackPlugin = require("html-webpack-plugin"); module.exports = { entry: ["./src/js/index.js","./src/index.html"], output: { filename: 'js/built.js', path: resolve(__dirname, "build") }, module: { rules: [ { test: /\.less$/, use: [ 'style-loader', 'css-loader', 'less-loader' ] }, { test: /\.css$/, use: [ 'style-loader', 'css-loader' ] }, { test: /\.(jpg||png||gif)$/, loader: "url-loader", options: { limit: 8 * 1024, name: "[hash:10].[ext]", esModule: false, outputPath:"imgs" } }, { test: /\.html$/, loader: "html-loader", }, { exclude: /\.(html|css|js|less|jpg|png|gif)$/, loader: "file-loader", options: { name: "[hash:10].[ext]", outputPath:"media" } } ] }, plugins: [ new HtmlWebpackPlugin({ template: "./src/index.html" }) ], mode:"development", devServer: { disableHostCheck: true, contentBase: resolve(__dirname, "build"), compress: true, port: 8080, open: true, hot:true } }
|
index.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| import "../css/index.less"; import print from "./print.js"
console.log("index.js被加载了"+new Date().toLocaleString()); function add(x,y){ return x+y; } print(); console.log(add(1,2));
if(module.hot){ module.hot.accept("./print.js",function (){ print(); }) }
|
4.2 source-map
webpack.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 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
| const { resolve } = require("path"); const HtmlWebpackPlugin = require("html-webpack-plugin"); module.exports = { entry: ["./src/js/index.js", "./src/index.html"], output: { filename: 'js/built.js', path: resolve(__dirname, "build") }, module: { rules: [ { test: /\.less$/, use: [ 'style-loader', 'css-loader', 'less-loader' ] }, { test: /\.css$/, use: [ 'style-loader', 'css-loader' ] }, { test: /\.(jpg||png||gif)$/, loader: "url-loader", options: { limit: 8 * 1024, name: "[hash:10].[ext]", esModule: false, outputPath: "imgs" } }, { test: /\.html$/, loader: "html-loader", }, { exclude: /\.(html|css|js|less|jpg|png|gif)$/, loader: "file-loader", options: { name: "[hash:10].[ext]", outputPath: "media" } } ] }, plugins: [ new HtmlWebpackPlugin({ template: "./src/index.html" }) ], mode: "development", devServer: { disableHostCheck: true, contentBase: resolve(__dirname, "build"), compress: true, port: 8080, open: true, hot: true },
devtool: "inline-source-map" };
|
4.3 oneOf
webpack.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 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
| const { resolve } = require("path"); const miniCssExtractPlugin = require("mini-css-extract-plugin"); const optimizeCssAssetsWebpackPlugin = require("optimize-css-assets-webpack-plugin"); const HtmlWebpackPlugin = require("html-webpack-plugin");
process.env.NODE_ENV = "production";
const commonCssLoader = [ miniCssExtractPlugin.loader, "css-loader", { loader: "postcss-loader", options: { ident: "postcss", plugins: () => [ require("postcss-preset-env")() ] } } ]; module.exports = { entry: "./src/js/index.js", output: { filename: "js/built.js", path: resolve(__dirname, "build") }, module: { rules: [
{ test: /\.js$/, exclude: /node_modules/, loader: "eslint-loader", options: { fix: true }, enforce: "pre" }, { oneOf: [ { test: /\.css$/, use: [ ...commonCssLoader ] }, { test: /\.less$/, use: [ ...commonCssLoader, "less-loader" ] }, { test: /\.js$/, exclude: /node_modules/, loader: "babel-loader", options: { presets: [ [ "@babel/preset-env", { useBuiltIns: "usage", corejs: { version: 3 }, targets: { chrome: "60", firefox: "50", ie: "9", safari: "10", edge: "17" } } ], ] } }, { test: /\.(jpg|png|gif)$/, loader: "url-loader", options: { limit: 8 * 1024, name: "[hash:10].[ext]", outputPath: "imgs", esModule: false } }, { test: /\.html$/, loader: "html-loader", }, { exclude: /\.(js|css|less|html|jpg|png|gif)$/, loader: "file-loader", options: { outputPath: "media" } }
] } ] }, plugins: [ new miniCssExtractPlugin({ filename: "css/built.css" }), new optimizeCssAssetsWebpackPlugin(), new HtmlWebpackPlugin({ template: "./src/index.html", minify: { collapseWhitespace: true, removeComments: true } })
], mode: "production", devServer: { disableHostCheck: true,
open: true, contentBase: resolve(__dirname, "build"), compress: true, port: 8080 } }
|
4.4 缓存
server.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
const express=require("express"); const app=express();
app.use(express.static("build",{ maxAge:1000*3600 })); app.listen(8080);
|
webpack.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 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
|
const { resolve } = require("path"); const miniCssExtractPlugin = require("mini-css-extract-plugin"); const optimizeCssAssetsWebpackPlugin = require("optimize-css-assets-webpack-plugin"); const HtmlWebpackPlugin = require("html-webpack-plugin");
process.env.NODE_ENV = "production";
const commonCssLoader = [ miniCssExtractPlugin.loader, "css-loader", { loader: "postcss-loader", options: { ident: "postcss", plugins: () => [ require("postcss-preset-env")() ] } } ];
module.exports = { entry: ["./src/js/index.js", "./src/index.html"], output: { filename: 'js/built.[contenthash:10].js', path: resolve(__dirname, "build") }, module: { rules: [
{ test: /\.js$/, exclude: /node_modules/, loader: "eslint-loader", options: { fix: true }, enforce: "pre" }, { oneOf: [ { test: /\.css$/, use: [ ...commonCssLoader ] }, { test: /\.less$/, use: [ ...commonCssLoader, "less-loader" ] }, { test: /\.js$/, exclude: /node_modules/, loader: "babel-loader", options: { presets: [ [ "@babel/preset-env", { useBuiltIns: "usage", corejs: { version: 3 }, targets: { chrome: "60", firefox: "50", ie: "9", safari: "10", edge: "17" } } ], ], cacheDirectory:true } }, { test: /\.(jpg|png|gif)$/, loader: "url-loader", options: { limit: 8 * 1024, name: "[hash:10].[ext]", outputPath: "/imgs", esModule: false } }, { test: /\.html$/, loader: "html-loader", }, { exclude: /\.(js|css|less|html|jpg|png|gif)$/, loader: "file-loader", options: { outputPath: "/media" } }
] } ] }, plugins: [ new miniCssExtractPlugin({ filename: "css/built.[contenthash:10].css" }), new optimizeCssAssetsWebpackPlugin(), new HtmlWebpackPlugin({ template: "./src/index.html", minify: { collapseWhitespace: true, removeComments: true } }) ], mode: "development", devServer: { disableHostCheck: true, contentBase: resolve(__dirname, "build"), compress: true, port: 8080, open: true, hot: true }, devtool: "inline-source-map" };
|
4.5 tree shaking
目的:去掉无用的代码
webpack.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 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
|
const { resolve } = require("path"); const miniCssExtractPlugin = require("mini-css-extract-plugin"); const optimizeCssAssetsWebpackPlugin = require("optimize-css-assets-webpack-plugin"); const HtmlWebpackPlugin = require("html-webpack-plugin");
process.env.NODE_ENV = "production";
const commonCssLoader = [ miniCssExtractPlugin.loader, "css-loader", { loader: "postcss-loader", options: { ident: "postcss", plugins: () => [ require("postcss-preset-env")() ] } } ];
module.exports = { entry: ["./src/js/index.js", "./src/index.html"], output: { filename: 'js/built.[contenthash:10].js', path: resolve(__dirname, "build") }, module: { rules: [
{ test: /\.js$/, exclude: /node_modules/, loader: "eslint-loader", options: { fix: true }, enforce: "pre" }, { oneOf: [ { test: /\.css$/, use: [ ...commonCssLoader ] }, { test: /\.less$/, use: [ ...commonCssLoader, "less-loader" ] }, { test: /\.js$/, exclude: /node_modules/, loader: "babel-loader", options: { presets: [ [ "@babel/preset-env", { useBuiltIns: "usage", corejs: { version: 3 }, targets: { chrome: "60", firefox: "50", ie: "9", safari: "10", edge: "17" } } ], ], cacheDirectory:true } }, { test: /\.(jpg|png|gif)$/, loader: "url-loader", options: { limit: 8 * 1024, name: "[hash:10].[ext]", outputPath: "/imgs", esModule: false } }, { test: /\.html$/, loader: "html-loader", }, { exclude: /\.(js|css|less|html|jpg|png|gif)$/, loader: "file-loader", options: { outputPath: "/media" } }
] } ] }, plugins: [ new miniCssExtractPlugin({ filename: "css/built.[contenthash:10].css" }), new optimizeCssAssetsWebpackPlugin(), new HtmlWebpackPlugin({ template: "./src/index.html", minify: { collapseWhitespace: true, removeComments: true } }) ], mode: "production", devServer: { disableHostCheck: true, contentBase: resolve(__dirname, "build"), compress: true, port: 8080, open: true, hot: true }, devtool: "inline-source-map" };
|
4.6 code split
- 单入口、多入口输出。单入口输出一个bundle;多入口输出多个bundle
- 通过optimization
- 通过js动态导入语法
index.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
| import $ from "jquery"; function sum(...args) { return args.reduce((p, c) => p + c, 0); }
console.log(sum(1, 2, 3, 4, 5));
console.log($);
import("./test") .then(({ mul, count }) => { console.log(mul(2, 3)); }) .catch(() => { console.log("文件加载失败"); });
|
test.js
1 2 3 4 5 6
| export function mul(x, y) { return x * y; } export function count(x, y) { return x - y; }
|
webpack.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 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
| const { resolve } = require("path"); const HtmlWebpackPlugin = require("html-webpack-plugin");
process.env.NODE_ENV = "production";
module.exports = { entry: { index: "./src/js/index.js", test: "./src/js/test.js" }, output: { filename: 'js/[name].[contenthash:10].js', path: resolve(__dirname, "build") }, module: { rules: [ { test: /\.less$/, use: [ 'style-loader', 'css-loader', 'less-loader' ] }, { test: /\.css$/, use: [ 'style-loader', 'css-loader' ] }, { test: /\.(jpg||png||gif)$/, loader: "url-loader", options: { limit: 8 * 1024, name: "[hash:10].[ext]", esModule: false, outputPath: "imgs" } }, { test: /\.html$/, loader: "html-loader", }, { exclude: /\.(html|css|js|less|jpg|png|gif)$/, loader: "file-loader", options: { name: "[hash:10].[ext]", outputPath: "media" } } ] }, plugins: [ new HtmlWebpackPlugin({ template: "./src/index.html", minify: { collapseWhitespace: true, removeComments: true } }) ],
optimization:{ splitChunks:{ chunks:"all" } }, mode: "production", devServer: { disableHostCheck: true, contentBase: resolve(__dirname, "build"), compress: true, port: 8080, open: true, hot: true } };
|
4.7 js文件懒加载与预加载
关于html的dom加载顺序,可以参照本文最上面的defer与async
webpack.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 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
| const { resolve } = require("path"); const HtmlWebpackPlugin = require("html-webpack-plugin");
process.env.NODE_ENV = "production";
module.exports = { entry: "./src/js/index.js", output: { filename: 'js/[name].[contenthash:10].js', path: resolve(__dirname, "build") }, module: { rules: [ { test: /\.less$/, use: [ 'style-loader', 'css-loader', 'less-loader' ] }, { test: /\.css$/, use: [ 'style-loader', 'css-loader' ] }, { test: /\.(jpg||png||gif)$/, loader: "url-loader", options: { limit: 8 * 1024, name: "[hash:10].[ext]", esModule: false, outputPath: "imgs" } }, { test: /\.html$/, loader: "html-loader", }, { exclude: /\.(html|css|js|less|jpg|png|gif)$/, loader: "file-loader", options: { name: "[hash:10].[ext]", outputPath: "media" } } ] }, plugins: [ new HtmlWebpackPlugin({ template: "./src/index.html", minify: { collapseWhitespace: true, removeComments: true } }) ],
optimization:{ splitChunks:{ chunks:"all" } }, mode: "production", devServer: { disableHostCheck: true, contentBase: resolve(__dirname, "build"), compress: true, port: 8080, open: true, hot: true } };
|
index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>开发环境配置</title> </head> <body> <h1 id="title">测试</h1> <button id="btn">按钮</button> <div id="box1"></div> <div id="box2"></div> <img src="./media/img3.jpg" alt=""> <a href="https://meethigher.obs.cn-north-4.myhuaweicloud.com:443/OBSBrowserPlus-HEC-win64.zip?AccessKeyId=MJXE1SVRAHUR4INU2JVX&Expires=1594782807&Signature=mAW9elrLaTdqoxFk%2BDJDOs42gMg%3D" download="下载.zip">点击下载</a> </body> </html>
|
index.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| console.log("indexjs文件被加载了");
document.getElementById("btn").onclick = function () {
import("./test").then(({ mul }) => { console.log(mul(2, 3)); }).catch(() => { console.log("失败"); }); }
|
test.js
1 2 3 4
| console.log("testjs被加载") export function mul(x,y){ return x*y; }
|
4.8 PWA
参考资料:
- Hexo博客部署PWA
- Service Workers 实现网站加速和离线缓存
安装
1
| npm install workbox-webpack-plugin -D
|
webpack.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 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
|
const { resolve } = require("path"); const HtmlWebpackPlugin = require("html-webpack-plugin"); const workboxWebpackPlugin=require("workbox-webpack-plugin"); const miniCssExtractPlugin=require("mini-css-extract-plugin"); const optimizeCssAssetsWebpackPlugin=require("optimize-css-assets-webpack-plugin");
process.env.NODE_ENV = "production";
const commonCssLoader = [ miniCssExtractPlugin.loader, "css-loader", { loader: "postcss-loader", options: { ident: "postcss", plugins: () => [ require("postcss-preset-env")() ] } } ]; module.exports = { entry: "./src/js/index.js", output: { filename: 'js/[name].[contenthash:10].js', path: resolve(__dirname, "build") }, module: { rules: [ { test: /\.css$/, use: [ ...commonCssLoader ] }, { test: /\.less$/, use: [ ...commonCssLoader, "less-loader" ] }, { test:/\.js$/, exclude:/node_modules/, loader:"babel-loader", options:{ presets:[ [ "@babel/preset-env", { useBuiltIns:"usage", corejs:{version:3}, targets:{ chrome:"60", firefox:"50", ie:"9", safari:"10", edge:"17" } } ], ] } }, { test:/\.(jpg|png|gif)$/, loader:"url-loader", options:{ limit:8*1024, name:"[hash:10].[ext]", outputPath:"/imgs", esModule:false } }, { test:/\.html$/, loader:"html-loader", }, { exclude:/\.(js|css|less|html|jpg|png|gif)$/, loader:"file-loader", options:{ outputPath:"/media" } }
] }, plugins: [ new miniCssExtractPlugin({ filename: "css/built.css" }), new optimizeCssAssetsWebpackPlugin(), new HtmlWebpackPlugin({ template: "./src/index.html", minify: { collapseWhitespace: true, removeComments: true } }),
new workboxWebpackPlugin.GenerateSW({ clientsClaim:true, skipWaiting:true }) ],
optimization:{ splitChunks:{ chunks:"all" } }, mode: "production", devServer: { disableHostCheck: true, contentBase: resolve(__dirname, "build"), compress: true, port: 8080, open: true, hot: true } };
|
index.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
| import "../css/index.less"; console.log("indexjs文件被加载了");
document.getElementById("btn").onclick = function () {
import("./test").then(({ mul }) => { console.log(mul(2, 3)); }).catch(() => { console.log("失败"); }); }
if("serviceWorker" in navigator){ window.addEventListener("load",()=>{ navigator.serviceWorker.register("/service-worker.js").then(()=>{ alert("sw注册成功"); }).catch(()=>{ alert("sw注册失败"); }); }) }
|
问题:
在eslint语法检测时,出现import和export必须放在顶部的错误,该错误暂未解决。
4.9 多进程打包
安装
1
| npm install thread-loader -D
|
将某个loader放到thread-loader的后面,就会对该loader进行多进程打包
下面,以多进程打包js兼容性处理为例
webpack.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 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
| const { resolve } = require("path"); const HtmlWebpackPlugin = require("html-webpack-plugin"); const workboxWebpackPlugin = require("workbox-webpack-plugin"); const miniCssExtractPlugin = require("mini-css-extract-plugin"); const optimizeCssAssetsWebpackPlugin = require("optimize-css-assets-webpack-plugin");
process.env.NODE_ENV = "production";
const commonCssLoader = [ miniCssExtractPlugin.loader, "css-loader", { loader: "postcss-loader", options: { ident: "postcss", plugins: () => [ require("postcss-preset-env")() ] } } ]; module.exports = { entry: "./src/js/index.js", output: { filename: 'js/[name].[contenthash:10].js', path: resolve(__dirname, "build") }, module: { rules: [ { test: /\.css$/, use: [ ...commonCssLoader ] }, { test: /\.less$/, use: [ ...commonCssLoader, "less-loader" ] }, { test: /\.js$/, exclude: /node_modules/, use: [
{ loader:"thread-loader", options:{ workers:2 } }, { loader: "babel-loader", options: { presets: [ [ "@babel/preset-env", { useBuiltIns: "usage", corejs: { version: 3 }, targets: { chrome: "60", firefox: "50", ie: "9", safari: "10", edge: "17" } } ], ] } } ] }, { test: /\.(jpg|png|gif)$/, loader: "url-loader", options: { limit: 8 * 1024, name: "[hash:10].[ext]", outputPath: "/imgs", esModule: false } }, { test: /\.html$/, loader: "html-loader", }, { exclude: /\.(js|css|less|html|jpg|png|gif)$/, loader: "file-loader", options: { outputPath: "/media" } }
] }, plugins: [ new miniCssExtractPlugin({ filename: "css/built.css" }), new optimizeCssAssetsWebpackPlugin(), new HtmlWebpackPlugin({ template: "./src/index.html", minify: { collapseWhitespace: true, removeComments: true } }),
new workboxWebpackPlugin.GenerateSW({ clientsClaim: true, skipWaiting: true }) ],
optimization: { splitChunks: { chunks: "all" } }, mode: "production", devServer: { disableHostCheck: true, contentBase: resolve(__dirname, "build"), compress: true, port: 8080, open: true, hot: true } };
|
4.10 externals
可以用来拒绝某些库的打包进入(某些情况下,通过cdn来引入库会更快一点)
webpack.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
| const {resolve}=require("path"); const HtmlWebpackPlugin=require("html-webpack-plugin"); module.exports={ entry:"./src/js/index.js", output:{ filename:"js/build.js", path:resolve(__dirname,"build"),
}, module:{ rules:[
], }, plugins:[ new HtmlWebpackPlugin({ template:"./src/index.html" }) ], mode:"production", externals:{ jquery:"jQuery" } }
|
4.11 dll
dll:动态连接库
对某些库进行打包,并自动添加到html中。可以理解成跟externals相反。
安装
1
| npm install add-asset-html-webpack-plugin -D
|
webpack.dll.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
|
const {resolve}=require("path"); const webpack=require("webpack"); module.exports={ entry:{ jquery:["jquery"] }, output:{ filename:"[name].js", path:resolve(__dirname,"dll"), library:"[name]_[hash]", }, plugins:[ new webpack.DllPlugin({ name:"[name]_[hash]", path:resolve(__dirname,"dll/manifest.json"), }) ], mode:"production" }
|
运行命令
1
| webpack --config webpack.dll.js
|
4.12 总结
- 开发环境性能优化
- 优化打包构建速度
- HMR:针对css、js文件进行热替换。一个模块发生变化,只会重新打包这一个模块,而不是打包所有
- 优化代码调试
- source-map:一种提供源代码到构建后代码映射技术(如果构建后代码出错了,通过映射关系可以追踪到源代码错误)
- 生产环境性能优化
- 优化打包构建速度
- oneOf:其中loader只会匹配一个,用来优化打包速度。就好比搜索内容时,搜索到第一个内容,后面的就不会再考虑了。所以在oneOf中,重复的内容需要单独提取出去。
- babel缓存
- 多进程打包
- 优化代码运行性能
- 文件缓存:hash->chunkhash->contenthash
- treeshaking:去除无用代码
- code split:代码分割
- 懒加载/预加载
- pwa:离线可访问技术
- externals
- dll
五、webpack配置详解
5.1 entry
webpack.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
| const { resolve } = require("path"); const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports={ entry:{ index:["./src/index.js","./src/sub.js"], add:"./src/add.js" }, output:{ filename:"[name].js", path:resolve(__dirname,"build") }, plugins:[ new HtmlWebpackPlugin() ], mode:"development" };
|
5.2 output
webpack.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
| const { resolve } = require("path"); const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports={ entry:"./src/index.js", output:{ filename:"[name].js", path:resolve(__dirname,"build"), publicPath:"/", chunkFilename:"[name]_chunk.js", }, plugins:[ new HtmlWebpackPlugin() ], mode:"development" };
|
5.3 module
webpack.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
| const { resolve } = require("path"); const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports={ entry:"./src/index.js", output:{ filename:"[name].js", path:resolve(__dirname,"build"), }, module:{ rules:[ { test:/\.css$/, use:["style-loader","css-loader"],
}, { test:/\.js$/, exclude:/node_modules/, include:resolve(__dirname,"src"), enforce:"pre", loader:"eslint-loader", options:{} }, { oneOf:[] } ] }, plugins:[ new HtmlWebpackPlugin() ], mode:"development" };
|
5.4 resolve
webpack.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
| const { resolve } = require("path"); const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports={ entry:"./src/js/index.js", output:{ filename:"[name].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:[".json",".css"], modules:[resolve(__dirname,"../../node_modules"),"node_modules"] } };
|
5.5 devServer
webpack.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
| const { resolve } = require("path"); const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = { entry: "./src/js/index.js", output: { filename: "[name].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: [".json", ".css"], modules: [resolve(__dirname, "../../node_modules"), "node_modules"] }, devServer:{ contentBase:resolve(__dirname,"build"), watchContentBase:true, watchOptions:{ ignored:/node_modules/ }, compress:true, port:8080, host:"localhost", open:true, hot:true, clientLogLevel:"none", quiet:true, overlay:false, proxy:{ "/api":{ target:"http://localhost:8000", pathRewrite:{ "^/api":"" } } } } };
|
5.7 optimization
webpack.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 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
| const { resolve } = require("path"); const HtmlWebpackPlugin = require("html-webpack-plugin"); const terserWebpackPlugin=require("terser-webpack-plugin");
module.exports = { entry: "./src/js/index.js", output: { filename: "js/[name].[contenthash].js", path: resolve(__dirname, "build"), chunkFilename:"js/[name].[contenthash].chunk.js" }, module: { rules: [ { test: /\.css$/, use: ["style-loader", "css-loader"],
}, ] }, plugins: [ new HtmlWebpackPlugin() ], mode: "development", resolve: { alias: { $css: resolve(__dirname, "src/css"), }, extensions: [".json", ".css"], modules: [resolve(__dirname, "../../node_modules"), "node_modules"] }, optimization:{ splitChunks:{ chunks:"all", minSize:30*1024, maxSize:0, minChunks:1, maxAsyncRequests:5, maxInitialRequests:3, automaticNameDelimiter:"~", name:true, cacheGroups:{ vendors:{ test:/[\\/]node_modules[\\/]/, priority:-10 }, default:{ minChunks:2, priority:-20, reuseExistingChunk:true } } },
runtimeChunk:{ name:entrypoint=>`runtime-${entrypoint.name}` }, minimizer:[ new terserWebpackPlugin({ cache:true, parallel:true, sourceMap:true, }) ] } };
|
六、webpack5
虽然目前还没发布,先了解
安装webpack5测试版
1
| npm install webpack@next webpack-cli -D
|
此版本重点关注以下内容:
- 通过持久缓存提高构建性能.
- 使用更好的算法和默认值来改善长期缓存.
- 通过更好的树摇和代码生成来改善捆绑包大小.
- 清除处于怪异状态的内部结构,同时在 v4 中实现功能而不引入任何重大更改.
- 通过引入重大更改来为将来的功能做准备,以使我们能够尽可能长时间地使用 v5.
6.1 下载
- npm i webpack@next webpack-cli -D
6.2 自动删除 Node.js Polyfills
早期,webpack 的目标是允许在浏览器中运行大多数 node.js 模块,但是模块格局发生了变化,许多模块用途现在主要是为前端目的而编写的。webpack <= 4 附带了许多 node.js 核心模块的 polyfill,一旦模块使用任何核心模块(即 crypto 模块),这些模块就会自动应用。
尽管这使使用为 node.js 编写的模块变得容易,但它会将这些巨大的 polyfill 添加到包中。在许多情况下,这些 polyfill 是不必要的。
webpack 5 会自动停止填充这些核心模块,并专注于与前端兼容的模块。
迁移:
- 尽可能尝试使用与前端兼容的模块。
- 可以为 node.js 核心模块手动添加一个 polyfill。错误消息将提示如何实现该目标。
6.3 Chunk 和模块 ID
添加了用于长期缓存的新算法。在生产模式下默认情况下启用这些功能。
chunkIds: "deterministic", moduleIds: "deterministic"
6.4 Chunk ID
你可以不用使用 import(/* webpackChunkName: "name" */ "module")
在开发环境来为 chunk 命名,生产环境还是有必要的
webpack 内部有 chunk 命名规则,不再是以 id(0, 1, 2)命名了
6.5 Tree Shaking
- webpack 现在能够处理对嵌套模块的 tree shaking
1 2 3 4 5 6 7 8 9 10 11
| export const a = 1; export const b = 2;
import * as inner from './inner'; export { inner };
import * as module from './module'; console.log(module.inner.a);
|
在生产环境中, inner 模块暴露的 b
会被删除
- webpack 现在能够多个模块之前的关系
1 2 3 4 5 6 7 8 9
| import { something } from './something';
function usingSomething() { return something; }
export function test() { return usingSomething(); }
|
当设置了"sideEffects": false
时,一旦发现test
方法没有使用,不但删除test
,还会删除"./something"
- webpack 现在能处理对 Commonjs 的 tree shaking
6.6 Output
webpack 4 默认只能输出 ES5 代码
webpack 5 开始新增一个属性 output.ecmaVersion, 可以生成 ES5 和 ES6 / ES2015 代码.
如:output.ecmaVersion: 2015
6.7 SplitChunk
webpack4中
webpack5中
1 2 3 4 5
| minSize: { javascript: 30000, style: 50000, }
|
6.8 Caching
1 2 3 4 5 6 7 8 9
| cache: { type: "filesystem", buildDependencies: { config: [__filename] } }
|
缓存将存储到 node_modules/.cache/webpack
6.9 监视输出文件
之前 webpack 总是在第一次构建时输出全部文件,但是监视重新构建时会只更新修改的文件。
此次更新在第一次构建时会找到输出文件看是否有变化,从而决定要不要输出全部文件。
6.10 默认值
entry: "./src/index.js
output.path: path.resolve(__dirname, "dist")
output.filename: "[name].js"
6.11 更多内容
https://github.com/webpack/changelog-v5
七、总结
7.1 参考
npm打包那些事
我想上传代码到github,但是其中node_modules数据太大了,所以需要在git中忽略掉。
git忽略某个目录或文件不上传
7.2 小结