webpack概念
本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包工具。当 webpack 处理应用程序时,它会在内部构建一个 依赖图(dependency graph),此依赖图会映射项目所需的每个模块,并生成一个或多个 bundle。
依赖图
任何时候,一个文件依赖于另一个文件,webpack 就把此视为文件之间有 依赖关系。这使得 webpack 可以接收非代码资源(non-code asset)(例如 images 或 web fonts),并且可以把它们作为 依赖 提供给你的应用程序。
webpack 从命令行或配置文件中定义的一个模块列表开始,处理你的应用程序。 从这些 入口起点 开始,webpack 递归地构建一个依赖图,这个依赖图包含着应用程序所需的每个模块,然后将所有这些模块打包为少量的 bundle - 通常只有一个 - 可由浏览器加载。
核⼼概念之 Entry
入口起点(entry point)指示 webpack 应该使用哪个模块,来作为构建其内部 依赖图开始。进入入口起点后,webpack 会找出有哪些模块和库是入口起点(直接和间接)依赖的。
默认值是 ./src/index.js,但你可以通过在 webpack configuration 中配置 entry 属性,来指定一个(或多个)不同的入口起点。
依赖图的⼊⼝是 entry,对于⾮代码⽐如图⽚、字体依赖也会不断加⼊到依赖图中。
Entry配置规则
string | [string] | object { : string | [string] } | (function: () => string | [string] | object { : string | [string] })
单个或多个入口打包程序,如果传递一个数组,那么数组的每一项都会是入口。动态加载的模块不是入口起点。
单⼊⼝:entry 是⼀个字符串
module.exports = {
entry: './path/to/my/entry/file.js'
};
多⼊⼝:entry 是⼀个对象
module.exports = {
entry: {
app: './src/app.js',
adminApp: './src/adminApp.js'
}
};
简单规则:每个 HTML 页面都有一个入口起点。单页应用(SPA):一个入口起点,多页应用(MPA):多个入口起点。
如果传入一个字符串或字符串数组,chunk 会被命名为 main。如果传入一个对象,则每个键(key)会是 chunk 的名称,该值描述了 chunk 的入口起点。
核⼼概念之 Output
output 位于对象最顶级键(key),包括了一组选项,指示 webpack 如何去输出、以及在哪里输出你的「bundle、asset 和其他你所打包或使用 webpack 载入的任何内容」。
output 属性告诉 webpack 在哪里输出它所创建的 bundle,以及如何命名这些文件。主要输出文件的默认值是 ./dist/main.js,其他生成文件默认放置在 ./dist 文件夹中。
output.chunkFilename
string
此选项决定了非入口(non-entry) chunk 文件的名称。有关可取的值的详细信息,请查看 output.filename 选项。
注意,这些文件名需要在 runtime 根据 chunk 发送的请求去生成。因此,需要在 webpack runtime 输出 bundle 值时,将 chunk id 的值对应映射到占位符(如 [name] 和 [chunkhash])。这会增加文件大小,并且在任何 chunk 的占位符值修改后,都会使 bundle 失效。
默认使用 [id].js 或从 output.filename 中推断出的值([name] 会被预先替换为 [id] 或 [id].)。
output.filename
string | function
此选项决定了每个输出 bundle 的名称。这些 bundle 将写入到 output.path 选项指定的目录下。
对于单个入口起点,filename 会是一个静态名称。
当通过多个入口起点(entry point)、代码拆分(code splitting)或各种插件(plugin)创建多个 bundle,应该使用以下一种替换方式,来赋予每个 bundle 一个唯一的名称。
模板 | 描述 |
---|---|
[hash] | 模块标识符(module identifier)的 hash |
[chunkhash] | chunk 内容的 hash |
[name] | 模块名称 |
[id] | 模块标识符(module identifier) |
[query] | 模块的 query,例如,文件名 ? 后面的字符串 |
[function] | The function, which can return filename [string] |
[hash] 和 [chunkhash] 的长度可以使用 [hash:16](默认为20)来指定。或者,通过指定output.hashDigestLength 在全局配置长度。
如果将这个选项设为一个函数,函数将返回一个包含上面表格中替换信息的对象。
Output 的⽤法:单⼊⼝配置
module.exports = {
entry: './path/to/my/entry/file.js'
output: {
filename: 'bundle.js’,
path: __dirname + '/dist'
}
};
Output 的⽤法:多⼊⼝配置
module.exports = {
entry: {
app: './src/app.js',
search: './src/search.js'
},
output: {
filename: '[name].js',
path: __dirname + '/dist'
}
};
核⼼概念之 Loaders
webpack 开箱即用只支持 JS 和 JSON 两种文件类型,通过 Loaders 去支持其它文
件类型并且把它们转化成有效的模块,并且可以添加到依赖图中。
本身是一个函数,接受源文件作为参数,返回转换的结果。
常⻅的 Loaders 有哪些?
名称 | 描述 |
---|---|
babel-loader | 转换ES6/ES7等JS新特性语法 |
css-loader | 支持。css文件的加载和解析 |
less-loader | 将less文件转换成css |
ts-loader | 将TS转换成JS |
file-loader | 进行图片、字体等的打包 |
raw-loader | 将文件以字符串的形式导入 |
Loaders 的⽤法
首先安装相对应的 loader:
npm install --save-dev css-loader
npm install --save-dev ts-loader
在你的应用程序中,有三种使用 loader 的方式:
- 配置(推荐):在 webpack.config.js 文件中指定 loader。
- 内联:在每个 import 语句中显式指定
loader。 - CLI:在 shell 命令中指定它们。
配置(configuration)
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: [
{ loader: 'style-loader' },
{
loader: 'css-loader',
options: {
modules: true
}
},
{ loader: 'sass-loader' }
]
}
]
}
};
可以在 import 语句或任何 等同于 “import” 的方法 中指定 loader。使用 ! 将资源中的 loader 分开。每个部分都会相对于当前目录解析。
import Styles from 'style-loader!css-loader?modules!./styles.css';
CLI
还可以通过 CLI 使用 loader:
webpack --module-bind jade-loader --module-bind 'css=style-loader!css-loader'
核⼼概念之 Plugins
插件⽤于 bundle ⽂件的优化,资源管理和环境变量注⼊
作⽤于整个构建过程,插件目的在于解决 loader 无法实现的其他事。
常⻅的 Plugins 有哪些?
名称 | 描述 |
---|---|
CommonsChunkPlugin | 将chunks相同的模块代码提取成公共js |
CleanWebpackPlugin | 清理构建目录 |
ExtractTextWebpackPlugin | 将css从bundle文件里提取成一个独立的CSS文件 |
CopyWebpackPlugin | 将文件或者文件夹拷贝到构建的输出目录 |
HtmlWebpackPlugin | 创建html文件去承载输出的bundle |
UglifyjsWebpackPlugin | 压缩JS |
ZipWebpackPlugin | 将打包出的资源生成一个zip包 |
Plugins的用法
const path = require('path');
module.exports = {
output: {
filename: 'bundle.js'
},
plugins: [
new HtmlWebpackPlugin({template:
'./src/index.html'})
]
};
核⼼概念之 Mode
Mode ⽤来指定当前的构建环境是:production、development 还是 none
设置 mode 可以使⽤ webpack 内置的函数,默认值为 production
名称 | 描述 |
---|---|
development | 设置process.env.NODE_ENV的值为development。开区NameChunksPlugin和NamedModulesPlugin |
production | 会将 DefinePlugin 中 process.env.NODE_ENV 的值设置为 production。启用 FlagDependencyUsagePlugin, FlagIncludedChunksPlugin, ModuleConcatenationPlugin, NoEmitOnErrorsPlugin, OccurrenceOrderPlugin, SideEffectsFlagPlugin 和 TerserPlugin。 |
none | 退出任何默认优化选项 |
module.exports = {
mode: 'production'
};