这些选项决定了如何处理项目中的不同类型的模块

官方解释

这些选项决定了如何处理项目中的不同类型的模块

对比 Node.js 模块,webpack 模块能够以各种方式表达它们的依赖关系,几个例子如下:

  • ES2015 import 语句
  • CommonJS require() 语句
  • AMD define 和 require 语句
  • css/sass/less 文件中的 @import 语句。
  • 样式(url(…))或 HTML 文件([9-19] Module - 图1)中的图片链接(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 中。

image.png

webpack所有的文件都会归纳与模块当中去,也就是chunk。js模块,css模块,图片模块。这个图左侧的类别是项目开发中用到的语法超集。右侧是浏览器可以支持的语法集合。

例如:ES6语法,Ts,JSX,AMD这些模块最终都会转换成js模块。所以module就是要将各种浏览器还不支持的语法进行编译处理。

loader字面意思:加载。加载模块,非常重要。

属性介绍

1. rules

创建模块时,匹配请求的规则数组。这些规则能够修改模块的创建方式。这些规则能够对模块(module)应用 loader,或者修改解析器(parser)

先看一个例子:

  1. module: {
  2. // loader
  3. rules: [
  4. {
  5. test: /\.css$/,
  6. use: [MiniCssExtractPlugin.loader, 'css-loader'],
  7. },
  8. {
  9. test: /\.js$/,
  10. exclude: /(node_modules|bower_components)/, // node_modules 目录或者其他不需要编译的源代码
  11. use: {
  12. loader: 'babel-loader',
  13. options: {
  14. presets: [['@babel/preset-env', { // 预设环境进行编译js,可以加入参数 https://www.jianshu.com/p/000c2670672b
  15. "targets": {
  16. "browsers": [
  17. "Firefox > 86"
  18. ]
  19. }
  20. }]]
  21. }
  22. }
  23. },
  24. {
  25. test: /\.js$/,
  26. exclude: /node_modules/,
  27. loader: 'eslint-loader',
  28. include: [path.resolve(__dirname, 'src')], // 指定检查的目录
  29. options: { // 这里的配置项参数将会被传递到 eslint 的 CLIEngine
  30. formatter: require('eslint-friendly-formatter') // 指定错误报告的格式规范,formatter默认是stylish,如果想用第三方的要另外安装
  31. }
  32. },
  33. {
  34. test: /\.(png|svg|jpg|gif)$/,
  35. use: [
  36. 'file-loader'
  37. ]
  38. },
  39. {
  40. test: /\.(woff|woff2|eot|ttf|otf)$/,
  41. use: [
  42. 'file-loader'
  43. ]
  44. },
  45. {
  46. test: /\.(csv|tsv)$/,
  47. use: [
  48. 'csv-loader'
  49. ]
  50. },
  51. {
  52. test: /\.xml$/,
  53. use: [
  54. 'xml-loader'
  55. ]
  56. }
  57. ]
  58. },

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写法

  1. {
  2. test: /\.js$/, // 文件匹配规则
  3. exclude: /node_modules/, // 排除检查的目录
  4. loader: 'eslint-loader', // 文件匹配之后对应编译的laoder
  5. include: [path.resolve(__dirname, 'src')], // 指定检查的目录
  6. options: { // 这里的配置项参数将会被传递到 eslint 的 CLIEngine
  7. formatter: require('eslint-friendly-formatter') // 指定错误报告的格式规范,formatter默认是stylish,如果想用第三方的要另外安装
  8. }
  9. }

use.loader写法

  1. {
  2. test: /\.js$/, // 文件匹配规则
  3. use: {
  4. loader: 'eslint-loader', // 文件匹配之后对应编译的laoder
  5. options: { // 这里的配置项参数将会被传递到 eslint 的 CLIEngine
  6. formatter: require('eslint-friendly-formatter') // 指定错误报告的格式规范,formatter默认是stylish,如果想用第三方的要另外安装
  7. }
  8. },
  9. exclude: /node_modules/, // 排除检查的目录
  10. include: [path.resolve(__dirname, 'src')], // 指定检查的目录
  11. },

use数组 + **enforce**
enforce使用的时候不可以loader的在一起,打包的时候会抱错。

  1. {
  2. test: /\.js$/,
  3. exclude: /(node_modules|bower_components)/, // node_modules 目录或者其他不需要编译的源代码
  4. use: [
  5. {
  6. loader: 'babel-loader',
  7. options: {
  8. presets: [['@babel/preset-env', { // 预设环境进行编译js,可以加入参数 https://www.jianshu.com/p/000c2670672b
  9. "targets": {
  10. "browsers": [
  11. "Firefox > 86"
  12. ]
  13. }
  14. }]]
  15. },
  16. enforce: 'pre'
  17. },
  18. {
  19. loader: 'eslint-loader', // 文件匹配之后对应编译的laoder
  20. options: { // 这里的配置项参数将会被传递到 eslint 的 CLIEngine
  21. formatter: require('eslint-friendly-formatter') // 指定错误报告的格式规范,formatter默认是stylish,如果想用第三方的要另外安装
  22. },
  23. enforce: 'pre'
  24. }
  25. ]
  26. },

要写成下面这样的

  1. {
  2. test: /\.js$/,
  3. exclude: /(node_modules|bower_components)/, // node_modules 目录或者其他不需要编译的源代码
  4. use: {
  5. loader: 'babel-loader',
  6. options: {
  7. presets: [['@babel/preset-env', { // 预设环境进行编译js,可以加入参数 https://www.jianshu.com/p/000c2670672b
  8. "targets": {
  9. "browsers": [
  10. "Firefox > 86"
  11. ]
  12. }
  13. }]]
  14. }
  15. },
  16. enforce: 'post'
  17. },
  18. {
  19. test: /\.js$/, // 文件匹配规则
  20. use: {
  21. loader: 'eslint-loader', // 文件匹配之后对应编译的laoder
  22. options: { // 这里的配置项参数将会被传递到 eslint 的 CLIEngine
  23. formatter: require('eslint-friendly-formatter') // 指定错误报告的格式规范,formatter默认是stylish,如果想用第三方的要另外安装
  24. }
  25. },
  26. enforce: 'pre',
  27. exclude: /node_modules/, // 排除检查的目录
  28. include: [path.resolve(__dirname, 'src')], // 指定检查的目录
  29. },

2. noparse

  1. 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 可以提高构建性能。

  1. module: {
  2. noParse: /lodash/
  3. }

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默认的设置选项:

  1. parser: {
  2. amd: false, // 禁用 AMD
  3. commonjs: false, // 禁用 CommonJS
  4. system: false, // 禁用 SystemJS
  5. harmony: false, // 禁用 ES2015 Harmony import/export
  6. requireInclude: false, // 禁用 require.include
  7. requireEnsure: false, // 禁用 require.ensure
  8. requireContext: false, // 禁用 require.context
  9. browserify: false, // 禁用特殊处理的 browserify bundle
  10. requireJs: false, // 禁用 requirejs.*
  11. node: false, // 禁用 __dirname, __filename, module, require.extensions, require.main 等。
  12. node: {...} // 在模块级别(module level)上重新配置 node 层(layer)
  13. }

我测试的例子当中,如果:commonjs这是为false的情况下,ES6的important会抱错

  1. {
  2. test: /\.js$/,
  3. exclude: /(node_modules|bower_components)/, // node_modules 目录或者其他不需要编译的源代码
  4. use: {
  5. loader: 'babel-loader',
  6. options: {
  7. presets: [['@babel/preset-env', { // 预设环境进行编译js,可以加入参数 https://www.jianshu.com/p/000c2670672b
  8. "targets": {
  9. "browsers": [
  10. "Firefox > 86"
  11. ]
  12. }
  13. }]]
  14. }
  15. },
  16. enforce: 'post',
  17. parser: {
  18. amd: false, // 禁用 AMD
  19. commonjs: false, // 禁用 CommonJS
  20. system: false, // 禁用 SystemJS
  21. harmony: false, // 禁用 ES2015 Harmony import/export
  22. requireInclude: false, // 禁用 require.include
  23. requireEnsure: false, // 禁用 require.ensure
  24. requireContext: false, // 禁用 require.context
  25. browserify: false, // 禁用特殊处理的 browserify bundle
  26. requireJs: false, // 禁用 requirejs.*
  27. },
  28. },

image.png

Demo地址

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

问题遗留:

module parse的用法