概念
webpack 是一个现代 JavaScript 应用程序的*静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph)*,其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。
入口 Entry
指示webpack应该使用哪个模块,来作为构建其内部依赖图的开始。进入入口起点后,webpack会找出有哪些模块和库是入口起点依赖的;
1 | module.exports = { |
可以向entry传入一个数组,将会创建多个主入口。在想要将多个依赖文件一起注入,并且将依赖导向到一个chunk时就很有用,比如分离应用程序和第三方库入口。
1 | const config = { |
多页面应用程序
1 | const config = { |
出口 output
output属性告诉webpack在哪里输出所创建的bundles,以及如何命名这些文件,默认值为”./dist”。基本上,整个应用程序结构,都会被编译到指定的输出路径的文件夹中;
1 | const path = require('path'); |
CDN和资源hash的复杂示例
1 | output: { |
这里hash代表文件名为hash值,每次部署会比对hash值,当值不同时,会加载最新的文件。
加载器 loader
loader让webpack处理非JavaScript文件。loader可以将所有类型的文件转换为webpack能够处理的有效模版。
1 | const path = require('path'); |
loader有两个属性:
- test 属性,用于表示应该被对应loader进行转换的某个或某些文件,可以模糊匹配;
- use 属性,表示进行转换时,应该使用哪个loader。
配置
1 |
|
特性
- loader 支持链式传递。能够对资源使用流水线(pipeline)。一组链式的 loader 将按照相反的顺序执行。loader 链中的第一个 loader 返回值给下一个 loader。在最后一个 loader,返回 webpack 所预期的 JavaScript。
- loader 可以是同步的,也可以是异步的。
- loader 运行在 Node.js 中,并且能够执行任何可能的操作。
- loader 接收查询参数。用于对 loader 传递配置。
- loader 也能够使用
options
对象进行配置。 - 除了使用
package.json
常见的main
属性,还可以将普通的 npm 模块导出为 loader,做法是在package.json
里定义一个loader
字段。 - 插件(plugin)可以为 loader 带来更多特性。
- loader 能够产生额外的任意文件。
插件 Plugins
插件可以用于执行范围更广的任务。插件范围包括,从打包优化和压缩,一直到重新定义环境中的变量。想要使用插件,需要require()它,然后添加到plugins数组中,多数插件可以通过选项(option)自定义。可以通过使用new操作符来创建它的实例。
1 | const HtmlWebpackPlugin = require('html-webpack-plugin'); // 通过 npm 安装 |
模式 module
通过选择development或production之中的一个,来设置mode参数,可以启用相应模式下的内置优化。
1 | module.exports = { |
配置
使用不同语言进行配置
TypeScript
首先使用相关依赖:
1 | npm install --save-dev typescript ts-node @types/node @types/webpack |
使用的webpack.config.ts:
1 | import path from 'path'; |
Webpack中的解析规则
使用enhanced-resolve
,webpack能够解析三种文件路径:
绝对路径
1 | import "/home/me/file"; |
绝对路径不需要进一步解析。
相对路径
1 | import "../src/file1"; |
使用import
或require
的资源文件所在的目录会认为是上下文目录,在其中给定的相对路径会添加此上下文路径,产生模块的绝对路径。
模块路径
1 | import "module"; |
模块会在resolve.modules
中指定的所有目录中搜索。
多种配置类型
导出为一个函数
作为导出一个配置对象的替代,可以从webpack配置文件中导出一个函数。该函数在调用时,可以传入两个参数:
环境对象作为第一个参数。一个选项map对象(argv)作为第二个参数,这个对象描述了传递给webpack的选项,并且具有output-filename
和optimize-minimize
等key。
1 | -module.exports = { |
导出一个Promise
webpack将运行由配置文件导出的函数,并且Promise返回。便于需要一部加载所需的配置变量。
1 | module.exports = () => { |
导出多个配置对象
对于针对多个构建目标,打包一个library非常有用。
1 | module.exports = [{ |
DefinePlugin插件
允许创建一个在编译时可以配置的全局常量。这可能会对开发模式和发布模式的构建允许不同的行为非常有用。
用法
每个传进 DefinePlugin
的键值都是一个标志符或者多个用 .
连接起来的标志符。
- 如果这个值是一个字符串,它会被当作一个代码片段来使用。
- 如果这个值不是字符串,它会被转化为字符串(包括函数)。
- 如果这个值是一个对象,它所有的 key 会被同样的方式定义。
- 如果在一个 key 前面加了
typeof
,它会被定义为 typeof 调用
如:
1 | new webpack.DefinePlugin({ |
Feature Flags(Feature Toggle)
用来标记启用/禁用 生产/开发 构建中的功能。
1 | new webpack.DefinePlugin({ |
Process-进程
该对象是一个全局变量,它提供当前Node.js 进程的有关信息,以及控制当前 Node.js 进程。 因为是全局变量,所以无需使用 require()
。process.env
属性返回一个包含用户环境信息的对象,可以对这个对象进行操作。