Webpack 结构与说明

   Develop  Javascript  WebPack    Javascript  WebPack

简介

_ webpack 是一个现代 JavaScript 应用程序的模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成少量的 bundle - 通常只有一个,由浏览器加载。 _

WebPack 的四个核心要素

入口(Entry)

webpack 创建应用程序所有依赖的关系图(dependency graph)。图的起点被称之为入口起点(entry point)。入口起点告诉 webpack 从哪里开始,并根据依赖关系图确定需要打包的内容。可以将应用程序的入口起点认为是根上下文(contextual root) 或 app 第一个启动文件。


输出(output)

将所有的资源(assets)归拢在一起后,还需要告诉 webpack 在哪里打包应用程序。webpack 的 output 属性描述了如何处理归拢在一起的代码(bundled code)。


loader

webpack 的目标是,让 webpack 聚焦于项目中的所有资源(asset),而浏览器不需要关注考虑这些(明确的说,这并不意味着所有资源(asset)都必须打包在一起)。webpack 把每个文件(.css, .html, .scss, .jpg, etc.) 都作为模块处理。然而 webpack 自身只理解 JavaScript。
webpack loader 在文件被添加到依赖图中时,其转换为模块。

在更高层面,在 webpack 的配置中 loader 有两个目标。

识别出(identify)应该被对应的 loader 进行转换(transform)的那些文件。(test 属性)
转换这些文件,从而使其能够被添加到依赖图中(并且最终添加到 bundle 中)(use 属性)


插件(plugins)

然而由于 loader 仅在每个文件的基础上执行转换,而 插件(plugins) 更常用于(但不限于)在打包模块的 “compilation” 和 “chunk” 生命周期执行操作和自定义功能(查看更多)。


WebPack Option

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
module.exports = {
entry: # string | object | array
// 这里应用程序开始执行
// webpack 开始打包

output: {
// webpack 如何输出结果的相关选项

path: # string
// 所有输出文件的目标路径
// 必须是绝对路径(使用 Node.js 的 path 模块)

filename: # string
// 「入口分块(entry chunk)」的文件名模板(出口分块?)

publicPath: # string
// 输出解析文件的目录,url 相对于 HTML 页面

library: # string,
// 导出库(exported library)的名称

libraryTarget: # 通用模块定义
/* 可选值: "umd" // 这是一种可以将你的 library 能够在所有的模块定义下都可运行的方式(并且导出的完全不是模块)。
// 它将在 CommonJS, AMD 环境下运行,或将模块导出到 global 下的变量
"var" // (默认值)当 library 加载完成,入口起点的返回值将分配给一个变量
"window" // 当 library 加载完成,入口起点的返回值将分配给 window 对象。
"global" // 当 library 加载完成,入口起点的返回值将分配给 global 对象。
"commonjs" // 当 library 加载完成,入口起点的返回值将分配给 exports 对象。
"commonjs2" // 当 library 加载完成,入口起点的返回值将分配给 exports 对象。
"this" // 当 library 加载完成,入口起点的返回值将分配给 this,this 的含义取决于你
"amd" // webpack 将你的 library 转为 AMD 模块
"assign" // 这里 webpack 会轻率地产生隐含的全局变量。
"jsonp" // 这将把入口起点的返回值,包裹到一个 jsonp 包装容器中
// 导出库(exported library)的类型
},
module: {
// 关于模块配置
rules: [
// 模块规则(配置 loader、解析器等选项)
{
test: /\.jsx?$/,
include: [
path.resolve(__dirname, "app")
],
exclude: [
path.resolve(__dirname, "app/demo-files")
],
// 这里是匹配条件,每个选项都接收一个正则表达式或字符串
// test 和 include 具有相同的作用,都是必须匹配选项
// exclude 是必不匹配选项(优先于 test 和 include)
// 最佳实践:
// - 只在 test 和 文件名匹配 中使用正则表达式
// - 在 include 和 exclude 中使用绝对路径数组
// - 尽量避免 exclude,更倾向于使用 include

issuer: { test, include, exclude },
// issuer 条件(导入源)

enforce: "pre",
enforce: "post",
// 标识应用这些规则,即使规则覆盖(高级选项)

loader: "babel-loader",
// 应该应用的 loader,它相对上下文解析
// 为了更清晰,`-loader` 后缀在 webpack 2 中不再是可选的
// 查看 webpack 1 升级指南。

options: {
presets: ["es2015"]
},
// loader 的可选项
},

{
test: /\.html$/,
test: "\.html$"

use: [
// 应用多个 loader 和选项
"htmllint-loader",
{
loader: "html-loader",
options: {
/* ... */
}
}
]
},

{ oneOf: [ /* rules */ ] },
// 只使用这些嵌套规则之一

{ rules: [ /* rules */ ] },
// 使用所有这些嵌套规则(合并可用条件)

{ resource: { and: [ /* 条件 */ ] } },
// 仅当所有条件都匹配时才匹配

{ resource: { or: [ /* 条件 */ ] } },
{ resource: [ /* 条件 */ ] },
// 任意条件匹配时匹配(默认为数组)

{ resource: { not: /* 条件 */ } }
// 条件不匹配时匹配
],

},

resolve: {
// 解析模块请求的选项
// (不适用于对 loader 解析)

modules: [
"node_modules",
path.resolve(__dirname, "app")
],
// 用于查找模块的目录

extensions: [".js", ".json", ".jsx", ".css"],
// 使用的扩展名

alias: {
// 模块别名列表

"module": "new-module",
// 起别名:"module" -> "new-module""module/path/file" -> "new-module/path/file"

"only-module$": "new-module",
// 起别名 "only-module" -> "new-module",但不匹配 "only-module/path/file" -> "new-module/path/file"

"module": path.resolve(__dirname, "app/third/module.js"),
// 起别名 "module" -> "./app/third/module.js""module/file" 会导致错误
// 模块别名相对于当前上下文导入
},

},

performance: {
hints: "warning", // 枚举
maxAssetSize: 200000, // 整数类型(以字节为单位)
maxEntrypointSize: 400000, // 整数类型(以字节为单位)
assetFilter: function(assetFilename) {
// 提供资源文件名的断言函数
return assetFilename.endsWith('.css') || assetFilename.endsWith('.js');
}
},

devtool: "source-map", // enum
// 通过在浏览器调试工具(browser devtools)中添加元信息(meta info)增强调试
// 牺牲了构建速度的 `source-map' 是最详细的。

context: __dirname, // string(绝对路径!)
// webpack 的主目录
// entry 和 module.rules.loader 选项
// 相对于此目录解析

target: "web", // 枚举
// 包(bundle)应该运行的环境
// 更改 块加载行为(chunk loading behavior) 和 可用模块(available module)

externals: ["react", /^@angular\//],
// 不要遵循/打包这些模块,而是在运行时从环境中请求他们

stats: "errors-only",
// 精确控制要显示的 bundle 信息

devServer: {
proxy: { // proxy URLs to backend development server
'/api': 'http://localhost:3000'
},
contentBase: path.join(__dirname, 'public'), // boolean | string | array, static file location
compress: true, // enable gzip compression
historyApiFallback: true, // true for index.html upon 404, object for multiple paths
hot: true, // hot module replacement. Depends on HotModuleReplacementPlugin
https: false, // true for self-signed, object for cert authority
noInfo: true, // only errors & warns on hot reload
// ...
},

plugins: [
// ...
],
// 附加插件列表

resolveLoader: { /* 等同于 resolve */ }
// 独立解析选项的 loader

parallelism: 1, // number
// 限制并行处理模块的数量

profile: true, // boolean
// 捕获时机信息

bail: true, //boolean
// 在第一个错误出错时抛出,而不是无视错误。

cache: false, // boolean
// 禁用/启用缓存

watch: true, // boolean
// 启用观察

watchOptions: {
aggregateTimeout: 1000, // in ms
// 将多个更改聚合到单个重构建(rebuild)

poll: true,
poll: 500, // 间隔单位 ms
// 启用轮询观察模式
// 必须用在不通知更改的文件系统中
// 即 nfs shares(译者注:Network FileSystem,最大的功能就是可以透過網路,讓不同的機器、不同的作業系統、可以彼此分享個別的檔案 ( share file ))
},

node: {
// Polyfills and mocks to run Node.js-
// environment code in non-Node environments.

console: false, // boolean | "mock"
global: true, // boolean | "mock"
process: true, // boolean
__filename: "mock", // boolean | "mock"
__dirname: "mock", // boolean | "mock"
Buffer: true, // boolean | "mock"
setImmediate: true // boolean | "mock" | "empty"
},

recordsPath: path.resolve(__dirname, "build/records.json"),
recordsInputPath: path.resolve(__dirname, "build/records.json"),
recordsOutputPath: path.resolve(__dirname, "build/records.json"),
// TODO
}
  1. WebPack 的四个核心要素
    1. 入口(Entry)
    2. 输出(output)
    3. loader
    4. 插件(plugins)
  2. WebPack Option
.Net Core 安装项目模板
命令行中创建使用.Net Core