使用 import
函数引入的代码,在 Webpack 中会被编译到一个异步模块中。import
函数返回一个 Promise,会在异步模块
加载完毕后 resolve。
Webpack 允许在调用 import
的时候加入注释来对异步加载进行配置。最常见的是指定新文件的 chunk name:
import('module-path-here' /* webpackChunkName: "name" */);
如果在 Webpack 的配置中指定了输出的文件名格式,比如 [name].js
,那么最终输出的结果的文件名就会是 name.js
。
当然,import
输入的参数字符串可以不是一个固定值。比如:
import('module-parent-path' + moduleName);
在这种情况下,Webpack 会尝试将 module-parent-path 下所有的文件都各自打包成一个异步模块。在这种情况下,显然 webpackChunkName 没法直接写死一个字符串了。Webpack 提供了 index
和 request
两个参数,可以用于动态生成的这些异步加载模块的命名。比如:
import(
'module-parent-path' + moduleName
/* webpackChunkName: "name-[index]-[request]" */
);
其中,index
表示当前引用的文件的序号,request
则表示当前引用的模块中动态的部分。举例俩说,上面这里如果 moduleName
是 example
,且配置生成的文件名是 [name].js
,那么最终这个模块的文件名就是 name-0-example.js
。
当然,一次性将 module-parent-path 下所有的文件都打包成独立的异步模块可能会太多了,Webpack 提供了一些裁剪的方案:
webpackInclude
,允许配置一个正则表达式,匹配的部分才打包成异步模块,忽略其他的webpackExclude
,允许配置一个正则表达式,匹配的部分会被忽略,打包其他剩下的模块webpackMode
,默认的模式是lazy
,每一个文件都会打包成一个异步模块;lazy-once
则会要求 Webpack 将所有的文件打包到一个模块中;eager
会把模块打包到当前的 chunk 中,但是不执行,等到真正执行了import
命令之后,才执行里面的代码(省去了网络请求),依然返回的是 promise;weak
不会产生网络请求,默认模块会由其他途径加载完成,如果其他途径没有事先加载过,那么此处调用就会造成 promise 的 reject。
如果有多个配置,可以叠加写在一起。一个例子:
import(
'module-parent-path' + moduleName
/* webpackChunkName: "name-[index]-[request]" */
/* webpackInclude: /include\.js$/ */
/* webpackExclude: /exclude\.js$/ */
/* webpackMode: "lazy" */
);
除了上述之外,Webpack 还支持一些模块加载相关的配置,比如:
import('module-path-here' /* webpackPrefetch: true */);
可以指定当前的异步加载模块需要 prefetch 的支持。运行时,Webpack 会向 head
中插入一个 <link rel=prefetch />
。
import('module-path-here' /* webpackPreload: true */);
可以指定当前的异步加载模块需要 preload 的支持。运行时,Webpack 会向 head
中插入一个 <link rel=preload />
。
一个例子:
import(
/* webpackPreload: true */
/* webpackChunkName: "name" */
'module-path-here'
);
注意到,这里配置注释写在前面还是写在后面都是不影响的。