这些选项决定了如何处理项目中的不同类型的模块
官方解释
这些选项决定了如何处理项目中的不同类型的模块。
对比 Node.js 模块,webpack 模块能够以各种方式表达它们的依赖关系,几个例子如下:
- ES2015 import 语句
- CommonJS require() 语句
- AMD define 和 require 语句
- css/sass/less 文件中的 @import 语句。
- 样式(url(…))或 HTML 文件(
)中的图片链接(image url)
webpack 通过 loader 可以支持各种语言和预处理器编写模块。loader 描述了 webpack 如何处理 非 JavaScript(non-JavaScript) 模块,并且在 bundle 中引入这些依赖。 webpack 社区已经为各种流行语言和语言处理器构建了 loader,包括:
- CoffeeScript
- TypeScript
- ESNext (Babel)
- Sass
- Less
- Stylus
总的来说,webpack 提供了可定制的、强大和丰富的 API,允许任何技术栈使用 webpack,保持了在你的开发、测试和生成流程中无侵入性(non-opinionated)。
解析理解
https://www.yuque.com/robinson/fe-pro/db87f7 在 Webpack 编译的过程中,Webpack 会要对整个代码进行静态分析,分析出各个模块的类型和它们依赖关系,然后将不同类型的模块提交给对应的加载器(loader)来处理。比如一个用 Less 写的样式,可以先用 less-loader 将它转成一个 CSS 模块,然后再通过 css-loader 把他插入到页面的
<style>标签中执行,甚至还可以通过插件将这部分 CSS 导出为 CSS 文件,使用link标签引入到页面中。
https://www.yuque.com/fe9/basic/fnvdeu#l7emso 我们知道webpack 是一个模块打包器,它不仅仅能处理js文件,还能处理css、图片。而且也能将ES6的代码、甚至是TypeScript的代码引用并打包输出成当下可执行的js文件。而webpack自身不可能穷举处理所有的相关文件。于是就采用了 loader 方式。
loader 用于对模块的源代码进行转换。loader 可以使你在 import 或 “加载” 模块时预处理文件。
不同的文件类型可能需要匹配不同的loader,做不同的文件转化。而有的模块可能需要处理,有的模块可能需要忽略,这一切相关的配置就在 module 中。

webpack所有的文件都会归纳与模块当中去,也就是chunk。js模块,css模块,图片模块。这个图左侧的类别是项目开发中用到的语法超集。右侧是浏览器可以支持的语法集合。
例如:ES6语法,Ts,JSX,AMD这些模块最终都会转换成js模块。所以module就是要将各种浏览器还不支持的语法进行编译处理。
loader字面意思:加载。加载模块,非常重要。
属性介绍
1. rules
创建模块时,匹配请求的规则数组。这些规则能够修改模块的创建方式。这些规则能够对模块(module)应用 loader,或者修改解析器(parser)
先看一个例子:
module: {// loaderrules: [{test: /\.css$/,use: [MiniCssExtractPlugin.loader, 'css-loader'],},{test: /\.js$/,exclude: /(node_modules|bower_components)/, // node_modules 目录或者其他不需要编译的源代码use: {loader: 'babel-loader',options: {presets: [['@babel/preset-env', { // 预设环境进行编译js,可以加入参数 https://www.jianshu.com/p/000c2670672b"targets": {"browsers": ["Firefox > 86"]}}]]}}},{test: /\.js$/,exclude: /node_modules/,loader: 'eslint-loader',include: [path.resolve(__dirname, 'src')], // 指定检查的目录options: { // 这里的配置项参数将会被传递到 eslint 的 CLIEngineformatter: require('eslint-friendly-formatter') // 指定错误报告的格式规范,formatter默认是stylish,如果想用第三方的要另外安装}},{test: /\.(png|svg|jpg|gif)$/,use: ['file-loader']},{test: /\.(woff|woff2|eot|ttf|otf)$/,use: ['file-loader']},{test: /\.(csv|tsv)$/,use: ['csv-loader']},{test: /\.xml$/,use: ['xml-loader']}]},
http://site.damobing.com/webpack/2%E9%85%8D%E7%BD%AE/2-3Module.html
- 条件匹配:通过 test 、 include 、 exclude 三个配置项来命中 Loader 要应用规则的文件。
- 应用规则:对选中后的文件通过 use 配置项来应用 Loader,可以只应用一个 Loader 或者按照从后往前的顺序应用一组 Loader,同时还可以分别给 Loader 传入参数。
- 重置顺序:一组 Loader 的执行顺序默认是从右到左执行,通过 enforce 选项可以让其中一个 Loader 的执行顺序放到最前或者最后。
| 属性名称 | 描述 | 是否必须 |
|---|---|---|
| test | 匹配文件规则 | 必填项 |
| loader / use.loader | 使用对应loader进行解析 | 必填项 |
| enforce | loader执行顺序 | 非必填项 |
| include | 匹配特定条件 | 非必填项 |
| exclude | 排除特定条件 | 非必填项 |
loader写法
{test: /\.js$/, // 文件匹配规则exclude: /node_modules/, // 排除检查的目录loader: 'eslint-loader', // 文件匹配之后对应编译的laoderinclude: [path.resolve(__dirname, 'src')], // 指定检查的目录options: { // 这里的配置项参数将会被传递到 eslint 的 CLIEngineformatter: require('eslint-friendly-formatter') // 指定错误报告的格式规范,formatter默认是stylish,如果想用第三方的要另外安装}}
use.loader写法
{test: /\.js$/, // 文件匹配规则use: {loader: 'eslint-loader', // 文件匹配之后对应编译的laoderoptions: { // 这里的配置项参数将会被传递到 eslint 的 CLIEngineformatter: require('eslint-friendly-formatter') // 指定错误报告的格式规范,formatter默认是stylish,如果想用第三方的要另外安装}},exclude: /node_modules/, // 排除检查的目录include: [path.resolve(__dirname, 'src')], // 指定检查的目录},
use数组 + **enforce**
enforce使用的时候不可以loader的在一起,打包的时候会抱错。
{test: /\.js$/,exclude: /(node_modules|bower_components)/, // node_modules 目录或者其他不需要编译的源代码use: [{loader: 'babel-loader',options: {presets: [['@babel/preset-env', { // 预设环境进行编译js,可以加入参数 https://www.jianshu.com/p/000c2670672b"targets": {"browsers": ["Firefox > 86"]}}]]},enforce: 'pre'},{loader: 'eslint-loader', // 文件匹配之后对应编译的laoderoptions: { // 这里的配置项参数将会被传递到 eslint 的 CLIEngineformatter: require('eslint-friendly-formatter') // 指定错误报告的格式规范,formatter默认是stylish,如果想用第三方的要另外安装},enforce: 'pre'}]},
要写成下面这样的
{test: /\.js$/,exclude: /(node_modules|bower_components)/, // node_modules 目录或者其他不需要编译的源代码use: {loader: 'babel-loader',options: {presets: [['@babel/preset-env', { // 预设环境进行编译js,可以加入参数 https://www.jianshu.com/p/000c2670672b"targets": {"browsers": ["Firefox > 86"]}}]]}},enforce: 'post'},{test: /\.js$/, // 文件匹配规则use: {loader: 'eslint-loader', // 文件匹配之后对应编译的laoderoptions: { // 这里的配置项参数将会被传递到 eslint 的 CLIEngineformatter: require('eslint-friendly-formatter') // 指定错误报告的格式规范,formatter默认是stylish,如果想用第三方的要另外安装}},enforce: 'pre',exclude: /node_modules/, // 排除检查的目录include: [path.resolve(__dirname, 'src')], // 指定检查的目录},
2. noparse
RegExp | [RegExp] | function(从 webpack 3.0.0 开始)
http://site.damobing.com/webpack/2%E9%85%8D%E7%BD%AE/2-3Module.html noParse 配置项可以让 Webpack 忽略对部分没采用模块化的文件的递归解析和处理,这样做的好处是能提高构建性能。 原因是一些库例如 jQuery 、ChartJS 它们庞大又没有采用模块化标准,让 Webpack 去解析这些文件耗时又没有意义。
https://www.webpackjs.com/configuration/module/#module-noparse 防止 webpack 解析那些任何与给定正则表达式相匹配的文件。忽略的文件中不应该含有 import, require, define 的调用,或任何其他导入机制。忽略大型的 library 可以提高构建性能。
module: {noParse: /lodash/}
3. parse
https://www.webpackjs.com/configuration/module/#rule-parser 解析选项对象。所有应用的解析选项都将合并。
解析器(parser)可以查阅这些选项,并相应地禁用或重新配置。大多数默认插件,会如下解释值: 将选项设置为 false,将禁用解析器。 将选项设置为 true,或不修改将其保留为 undefined,可以启用解析器。 然而,一些解析器(parser)插件可能不光只接收一个布尔值。例如,内部的 NodeStuffPlugin 差距,可以接收一个对象,而不是 true,来为特定的规则添加额外的选项。
http://site.damobing.com/webpack/2%E9%85%8D%E7%BD%AE/2-3Module.html 因为 Webpack 是以模块化的 JavaScript 文件为入口,所以内置了对模块化 JavaScript 的解析功能,支持 AMD、CommonJS、SystemJS、ES6。 parser 属性可以更细粒度的配置哪些模块语法要解析哪些不解析,和 noParse 配置项的区别在于 parser 可以精确到语法层面, 而 noParse 只能控制哪些文件不被解析。
parse默认的设置选项:
parser: {amd: false, // 禁用 AMDcommonjs: false, // 禁用 CommonJSsystem: false, // 禁用 SystemJSharmony: false, // 禁用 ES2015 Harmony import/exportrequireInclude: false, // 禁用 require.includerequireEnsure: false, // 禁用 require.ensurerequireContext: false, // 禁用 require.contextbrowserify: false, // 禁用特殊处理的 browserify bundlerequireJs: false, // 禁用 requirejs.*node: false, // 禁用 __dirname, __filename, module, require.extensions, require.main 等。node: {...} // 在模块级别(module level)上重新配置 node 层(layer)}
我测试的例子当中,如果:commonjs这是为false的情况下,ES6的important会抱错
{test: /\.js$/,exclude: /(node_modules|bower_components)/, // node_modules 目录或者其他不需要编译的源代码use: {loader: 'babel-loader',options: {presets: [['@babel/preset-env', { // 预设环境进行编译js,可以加入参数 https://www.jianshu.com/p/000c2670672b"targets": {"browsers": ["Firefox > 86"]}}]]}},enforce: 'post',parser: {amd: false, // 禁用 AMDcommonjs: false, // 禁用 CommonJSsystem: false, // 禁用 SystemJSharmony: false, // 禁用 ES2015 Harmony import/exportrequireInclude: false, // 禁用 require.includerequireEnsure: false, // 禁用 require.ensurerequireContext: false, // 禁用 require.contextbrowserify: false, // 禁用特殊处理的 browserify bundlerequireJs: false, // 禁用 requirejs.*},},

Demo地址
https://github.com/rodchen-king/wepack-learn/commit/4add7a60b3aeac1c84a851e746064b908c52f6e7
