一切皆模块

在 Webpack 中,一切皆模块!

在 Webpack 编译的过程中,Webpack 会要对整个代码进行静态分析,分析出各个模块的类型和它们依赖关系,然后将不同类型的模块提交给对应的加载器(loader)来处理。比如一个用 Less 写的样式,可以先用 less-loader 将它转成一个 CSS 模块,然后再通过 css-loader 把他插入到页面的 <style> 标签中执行,甚至还可以通过插件将这部分 CSS 导出为 CSS 文件,使用link标签引入到页面中。

对不同规范的支持

支持目前的所有模块规范。

import的增强和注释功能

import不但支持es6的模块支持,还支持require的功能 ,这其实是es2015的的支持。

不同于import from 的写法,import()返回的是一个promise对象,经过这个方法引入的代码会单独打包一个文件。

并且 ,你可以用过注释执行这部分chunk的名字

  1. import('path/to/module').then(mod => {
  2. console.log(mod);
  3. });
  4. import hello from './hello';
  5. import(
  6. /*
  7. webpackChunkName: 'lazy-name'
  8. */
  9. './lazy'
  10. ).then(lazy => {
  11. console.log(lazy);
  12. });

目前支持的注释有:

  • webpackInclude:如果是 import 的一个目录,则可以指定需要引入的文件特性,例如只加载 json 文件:/\.json$/
  • webpackExclude:如果是 import 的一个目录,则可以指定需要过滤的文件,例如 /\.noimport\.json$/
  • webpackChunkName:这是 chunk 文件的名称,例如 lazy-name
  • webpackPrefetch: 是否预取模块,及其优先级,可选值true、或者整数优先级别,0 相当于 true,webpack 4.6+支持;
  • webpackPreload: 是否预加载模块,及其优先级,可选值true、或者整数优先级别,0 相当于 true,webpack 4.6+支持;
  • webpackMode: 可选值lazy/lazy-once/eager/weak

这里最复杂的是webpackMode

  • lazy:是默认的模式,为每个 import() 导入的模块,生成一个可延迟加载 chunk;
  • lazy-once:生成一个可以满足所有 import() 调用的单个可延迟加载 chunk,此 chunk 将在第一次 import() 调用时获取,随后的 import() 调用将使用相同的网络响应;注意,这种模式仅在部分动态语句中有意义,例如 import(./locales/${language}.json),其中可能含有多个被请求的模块路径;
  • eager:不会生成额外的 chunk,所有模块都被当前 chunk 引入,并且没有额外的网络请求。仍然会返回 Promise,但是是 resolved 状态。和静态导入相对比,在调用 import() 完成之前,该模块不会被执行。
  • weak:尝试加载模块,如果该模块函数已经以其他方式加载(即,另一个 chunk 导入过此模块,或包含模块的脚本被加载)。仍然会返回 Promise,但是只有在客户端上已经有该 chunk 时才成功解析。如果该模块不可用,Promise 将会是 rejected 状态,并且网络请求永远不会执行。当需要的 chunks 始终在(嵌入在页面中的)初始请求中手动提供,而不是在应用程序导航在最初没有提供的模块导入的情况触发,这对于 Server 端渲染(SSR,Server-Side Render)是非常有用的。

打包资源文件夹:

import(/* webpackChunkName: "image", webpackInclude: /\.(png|jpg|gif)/ */ './assets/img');

require context

require.context(directory, includeSubdirs, filter)可以批量将directory内的文件全部引入进文件,并且返回一个具有resolve的 context 对象,使用context.resolve(moduleId)则返回对应的模块。

directory:目录 string;
includeSubdirs:是否包含子目录,可选,默认值是 true;
filter:过滤正则规则,可选项。

缺点:会把所有文件放到bundle

require include

require.include(dependency)顾名思义为引入某个依赖,但是并不执行它,可以用于优化 chunk,例如下面示例代码:

require.include('./hello.js');
require.ensure(['./hello.js', './weak.js'], function(require) {
   /* ... */
});
require.ensure(['./hello.js', './lazy.js'], function(require) {
   /* ... */
});

这实际上使用了require.include()直接优化了代码分割,如果不用require.include('./hello.js');hello.js会分别和weaklazy打包

对node中模块的使用

Webpack 还对一些常用的 Node.js 模块和属性进行了 mock,例如在 web 的 js 文件中可以直接引入 Node.js 的querystring模块,这个模块实际引入的是node-libs-browser来对 Node.js 核心库 polyfill,详细在 web 页面中可以用的 Node.js 模块,可以参考node-libs-browser Readme 文件的表格

更多

补充中,,,