es6 modules
commonjs
amd
如果 require 中含有表达式,由于编译时并不清楚 具体 导入了哪个模块,因此会创建一个上下文。
参考接下来的例子:假设现在有包含 .ejs
文件的如下目录结构:
example_directory
│
└───template
│ │ table.ejs
│ │ table-row.ejs
│ │
│ └───directory
│ │ another.ejs
当下面的 require()
调用被评估解析时:
require('./template/' + name + '.ejs');
webpack 解析会 require()
调用,然后提取出如下一些信息:
Directory: ./template
Regular expression: /^.*\.ejs$/
上下文模块
并且会创建一个上下文模块。它包含 对该目录下所有模块 的引用,可以使用匹配正则表达式的请求来导入这些模块。上下文模块中存在一个映射,该映射用于将请求转换为模块 ID。
示例映射:
{
"./table.ejs": 42,
"./table-row.ejs": 43,
"./directory/another.ejs": 44
}
此上下文模块还包含一些访问此映射对象的运行时逻辑。
这意味着 webpack 能够支持动态导入,但会导致所有可能用到的模块都包含在 bundle 中。
可以通过 require.context()
函数实现自定义上下文。
可以给这个函数传入三个参数:要搜索的目录、是否还搜索其子目录,匹配文件的正则表达式。
webpack 会在构建中解析代码中的 require.context()
。
语法如下:
require.context(
directory,
(useSubdirectories = true),
(regExp = /^\.\/.*$/),
(mode = 'sync')
);
示例:
require.context('./test', false, /\.test\.js$/);
// 创建一个上下文,其中文件直接来自 test 目录,require 包含的表达式以 `.test.js` 结尾。
require.context('../', true, /\.stories\.js$/);
// 创建一个上下文,其中文件来自父文件夹及其所有子级文件夹,require 包含的表达式以 `.stories.js` 结尾。
上下文模块会导出一个接收一个参数 request 的 require 函数。
此导出函数有三个属性:resolve
,keys
与 id
。
resolve
是一个函数,它返回 request 被解析后得到的模块 id。keys
也是一个函数,它返回一个数组,由所有可能被此上下文模块处理的请求组成。如果想引入一个文件夹下面的所有文件,或者引入能匹配一个正则表达式的所有文件,这个功能就会很有帮助,例如:
function importAll(r) {
r.keys().forEach(r);
}
importAll(require.context('../components/', true, /\.js$/));
const cache = {};
function importAll(r) {
r.keys().forEach((key) => (cache[key] = r(key)));
}
importAll(require.context('../components/', true, /\.js$/));
// 构建时所有被导入的模块都会被填充到缓存对象中。
id
是上下文模块的模块 id. 它可能在使用 module.hot.accept
时会用到。