云驹博客

路漫漫其修远兮,吾将上下而求索。

0%

Webpack配置项

运行指令:

开发环境:

1
webpack ./src/index.js -o ./build/built.js --mode=development

生产环境

1
webpack ./src/index.js -o ./build/built.js --mode=production

webpack会以./src/index.js为入口文件开始打包,打包后输出到./build/built.js整体打包环境

  1. webpack能处理js/json资源,不能处理css/img等其他资源

  2. 生产环境和开发环境将ES6模块化编译成浏览器能识别的模块化

  3. 生产环境比开发环境多一个压缩js代码。

配置文件

根目录新建**package.json**

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
"browserslist": {
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
],
"production": [
">0.2%",
"not dead",
"not op_mini all"
]
},
"eslintConfig": {
"extends": "airbnb-base"
},
"sideEffects"["*.css"],
}

根目录新建**webpack.config.js**

webpack的配置文件作用:指示webpack干哪些活(当你运行webpack指令时,会加载里面的配置)
所有构建工具都是基于nodejs平台运行的~模块化默认采用commonjs.

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
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
/*
* 开发环境配置:能让代码运行
* 运行项目指令:
* webpack 会将打包结果输出出去
* npx webpack-dev-server 只会在内存中编译打包,没有输出
*/

// resolve用来拼接绝对路径
const { resolve } = require("path");
// 处理html
const HtmlWebpackPlugin = require("html-webpack-plugin");
// css兼容
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
// 压缩css
const OptimizeCssAssetsWebpackPlugin = require("optimize-css-assets-webpack-plugin");

// 设置node环境变量
proces.env.NODE_ENV = "developement";

/*
* 缓存:
* babel缓存 --> 让二次打包构建速度更快
* cacheDirectory: true
* 文件资源缓存 --> 让代码上线运行缓存更好使用
* hash:每次webpack构建时会生成一个唯一的hash值。
* 问题:因为js和css同时使用一个hash值。
* 如果重新打包,会导致所有缓存失效。(可能我却只改动一个文件)
* chunkhash:根据chunk生成的hash值。如果打包来源于同一个chunk,那么hash值就一样
* 问题:js和css的hash值还是一样的
* 因为css是在js中被引入的,所以同属于一个chunk
* contenthash:根据文件的内容生成hash值。不同文件hash值一定不一样
*
* tree shaking:去除无用代码
* 前提:1.必须使用ES6模块化 2.开启production环境
* 作用:减少代码体积
*
* 在package.json中配置
* "sideEffects":false所有代码都没有副作用(都可以进行tree shaking)
* 问题:可能会把css/@babel/polyfil1(副作用)文件干掉
* "sideEffects":["*.css","*.less"]
*/

const commonCssLoader = [
// 创建style标签,将js中的样式资源插入进行,添加到head中生效
// 'style-loader',
// 这个loader取代style-loader,作用:提取js中的css成单独文件
MiniCssExtractPlugin.loader,
// 将css文件变成commonjs模块加载js中,里面内容是样式字符串
"css-loader",
/* css兼容性处理:postcss --> postcss-loader postcss-preset-env
* 帮postcss找到package.json中browserslist里的配置,通过配置加载css兼容性样式
* "browserslist": {
* // 开发环境:设置node环境变量:proces.env.NODE_ENV = 'developement'
* "development": [
* "last 1 chrome version",
* "last 1 firefox version",
* "last 1 safari version"
* ],
* // 生产环境:默认是看生产环境(与mode配置无关)
* "production": [
* ">0.2%",
* "not dead",
* "not op_mini all"
* ]
* }
*/
// 使用loader的默认配置
// 'postcss-loader',
// 修改loader的配置
{
loader: "postcss-loader",
options: {
ident: "poctcss",
plugins: () => [
// postcss的插件
require("postcss-preset-env")(),
],
},
},
];

module.exports = {
// webpack配置
// 模式(生产环境时会压缩js代码)
mode: "development",
// mode: 'production',

// 入口起点
entry: ["./src/js/index.js", "./src/index.html"],
output: {
// 输出文件名
filename: "js/built.[contenthash:10].js",
// 输出路径
// __dirname nodejs的变量,代表 当前文件目录的绝对路径
path: resolve(_dirname, "build"),
},
// 开发服务器 devServer:用来自动化(自动编译,自动打开浏览器,自动刷新浏览器)
// 特点:只会在内存中编译打包,不会有任何输出
// 启动derServer指令为:npx webpack-dev-server
devServer: {
// 项目构建后路径
contentBase: resolve(__dirname, "build"),
// 启动gzip压缩
compress: true,
// 端口号
port: 8080,
// 自动打开浏览器
open: true,
/*
* 开启HMR热更新功能
* HMR:hot module replacement热模块替换/模块热替换作用:一个模块发生变化,只会重新打包这一个模块(而不是打包所有模块),极大提升构建速度
*
* 样式文件:可以使用HMR功能:因为style-loader内部实现了~
* js文件:默认不能使用HMR功能-->需要修改js代码,添加支持HMR功能的代码
* 注意:HMR功能对js的处理,只能处理非入口js文件的其他文件。
* if (module.hot) {
* // 一旦 module.hot 为 true,说明开启了HMR功能。--> 让HMR功能代码生效
* module.hot.accept('./print.js', function () {
* // 方法会监听print.js文件的变化,一旦发生变化,其他模块不会重新打包构建。
* // 会执行后面的回调函数
* print()
* })
* }
*
* html文件:默认不能使用HMR功能,同时会导致问题:html文件不能热更新了~(不用做HMR功能)
* 解决:修改entry入口,将html文件引入
*/
hot: true,
},
// loader的配置
module: {
rules: [
// 详细loader配置
// 不同文件必须配置不同loader处理,
{
/*
* 语法检查:eslint-loader eslint
* 注意:只检查自己写的源代码,第三方的库是不用检查的
* 设置检查规则:package.json中eslintkonfig中设置
* "eslintConfig": {
* "extends": "airbnb-base"
* }
* airbnb--> eslint-config-airbnb-base eslint-plugin-import eslint
*/
test: /\.js$/,
exclude: /node_modules/,
loader: "eslint-loader",
// 优先执行,需要优先于js代码兼容性处理执行,避免冲突
enforce: "pre",
options: {
// 自动修复eslint的错误
fix: true,
},
},
{
/*
* 正常来讲,一个文件只能被一个loader处理。
* 当一个文件要被多个loader处理,那么一定要指定loader执行的先后顺序:先执行eslint在执行babel
* 注意:不能有两个配置处理一种类型
*/
oneOf: [
{
// 匹配css文件
test: /\.css$/,
// 使用那些loader进行处理
// 要使用多个loader处理使用use
// use数组中loader执行顺序:从右到左、从下到上,依次执行
use: [...commonCssLoader],
},
{
test: /\.less$/,
use: [...commonCssLoader, "less-loader"],
},
{
/*
* js兼容性处理:babel-loader @babel/core
* 使用1、3方法,2体积太大不考虑
* 1. 基本js兼容性处理 --> @babel/preset-env
* 问题:只能转换基本语法,如promise高级语法不能转换
* 2. 全部js兼容性处理 --> @babel/polyfill
* 使用方法:在需要处理代码兼容性的js文件import引入@babel/polyfill
* 问题:我只要解决部分兼容性问题,但是将所有兼容性代码全部引入,代码体积变大了
* 3. 需要做兼容性处理的代码就做按需加载 --> core-js
*/
test: /\.js$/,
exclude: /node_modules/,
loader: "babel-loader",
options: {
// 预设:指示babel做怎么样的兼容性处理
presets: [
[
"@babel/preset-env",
{
// 按需加载
useBuiltIns: "usage",
// 指定core-js的版本
corejs: {
version: 3,
},
// 指定兼容性做到那个版本的浏览器
targets: {
chrome: "60",
firefox: "60",
ie: "9",
safari: "10",
edge: "17",
},
},
],
],
// 开启babel缓存
// 第二次构建时,会读取之前的缓存
cacheDirectory: true,
},
},
{
// 处理图片资源
// 不会处理html内的图片
test: /\.(jpg|png|gif)$/,
// 使用一个loader
// url-loader依赖file-loader
loader: "url-loader",
options: {
// 图片大小小于8kb,就会被base64处理
// 优点:减少请求数量(减轻服务器压力)
// 缺点:图片体积会更大(文件请求速度更慢)
limit: 8 * 1024,
// 问题:因为url-loader默认使用es6模块化解析,而html-loader引入图片是commonjs
// 解析时会出问题:[object Module]
// 解决:关闭ur1-loader的es6模块化,使用commonjs解析
esModule: false,
// 给图片进行重命名
// [contenthash:10]取图片的hash的前10位
// [ext]取文件原来扩展名
name: "[contenthash:10].[ext]",
// 输出目录
outputPath: "img",
},
},
{
// 处理html文件内的img图片(负责引入img,从而能够被url-loader进行处理)
test: /\.html$/,
loader: "html-loader",
},
{
// 打包其他资源
exclude: /\.(html|css|js|less|scss|jpg|png|gif)$/,
loader: "file-loader",
options: {
name: "[contenthash:10].[ext]",
outputPath: "media",
},
},
],
},
],
},
// plugins的配置
plugins: [
// 详细plugins的配置
// html-webpack-plugin
// 功能:自动引入打包输出的所有资源(js/css)
new HtmlWebpackPlugin({
template: "./src/index.html",
// 代码压缩
minify: {
// 移除空格
collapseWhitespace: true,
// 移除注释
removeComments: true,
},
}),
new MiniCssExtractPlugin({
// 指定输出文件
filename: "css/built.[contenthash:10].css",
}),
// 压缩css
new OptimizeCssAssetsWebpackPlugin(),
],
/*
* source-map:一种提供源代码构建后代码映射的技术(生成代码到原始代码的映射方法)
* [inline-|hidden-leval-][nosources-][cheap-[module-]]source-map
* source-map:外部
* 错误代码的准确信息 和 源代码的错误位置
* inline-source-map:内联
* 只生成一个内联source-map
* 错误代码的准确信息 和 源代码的错误位置
* hidden-source-map:外部
* 错误代码错误原因,但是没有错误位置
* 不能追踪源代码错误位置,只能提示到构建后代码的错误位置
* eval-source-map:内联
* 每一个文件都生成对应的source-map,都在eval
* 错误代码的准确信息 和 源代码的错误位置
* nosources-source-map:外部
* 错误代码的准确信息,但是没有任何源代码信息
* cheap-source-map:外部
* 错误代码的准确信息 和 源代码的错误位置
* 只能精确到行
* cheap-module-source-map:外部
* 错误代码的准确信息 和 源代码的错误位置
* module会将loader的source map加入
*
* 开发环境:eval-source-map
* 生产环境:hidden-source-map / nosources-source-map
*
* 内联和外部的区别:1,外部生成了文件,内联没有2,内联构建速度更快
*/
devtool: "eval-source-map",
};