Webpack中最主要的核心模块(moudules、loader、resolve)

webpack最重要的四大模块:入口起点、出口文件、加载器loader、插件plugin

上一篇文章详细介绍过了入口起点、出口文件,不清楚的可以前往查看。

模块(moudules)

webpack模块 能以各种方式表达它们的依赖关系,解析任何模块的源码。

模块有很多配置项,下面介绍几个常用的,其他的可以进入官网查看。这些选项决定了如何处理项目中的不同类型的模块。

module.parser

module.parser 是用于指定模块解析器选项的配置项。

例如:

js 复制代码
module.exports = {
  module: {
    parser: {
      javascript: {
        // javascript 模块的解析器选项
        // 例如,启用解析 require.ensure 语法的功能
        requireEnsure: true,
      },
      'javascript/auto': {
        // 同上
      },
      'javascript/dynamic': {
        // 同上
      },
      'javascript/esm': {
        // 同上
      },
      // 其他...
    },
  },
};
  • 对于 javascript 模块,它也提供了相应的解析器选项,如 javascriptjavascript/autojavascript/dynamicjavascript/esm
  • 每个模块类型的解析器选项可以根据具体需求进行配置,例如启用解析特定语法的功能(如 requireEnsure)。
  • 除了上述模块类型外,还可以添加其他模块类型的解析器选项。

module.rules

创建模块时,匹配请求的规则数组,每个数组中的对象为一个rule,用于定义特定类型文件的处理规则。

在 Webpack 中,module.rulemodule.rules是两个不同的配置项,用于定义模块的处理规则,但是module.rules允许你在 webpack 配置中指定多个 loader。

同时,rulesoneOf两者都是嵌套规则,每个嵌套规则包含它自己的条件,值得注意的是 oneof 又可以嵌套在 rules 规则内

rule属性有着许许多多的配置项,用于修改特定类型文件的处理规则,下面说一下这些规则配置项。

test 属性用于指定匹配的文件类型

js 复制代码
module.exports = { 
    module: { 
        rules: [ 
            { 
                test: /\.js$/, 
                // 使用了正则表达式 `/.js$/` 来匹配以 `.js` 结尾的文件
            }, 
        ], 
    }, 
};

use 属性用于指定处理该文件类型的加载器

js 复制代码
// 使用了 `babel-loader` 来处理 JavaScript 文件
module.exports = { 
    module: { 
        rules: [ 
            { 
                test: /\.js$/, 
                // 使用了正则表达式 `/.js$/` 来匹配以 `.js` 结尾的文件
                use: ['babel-loader'], 
                // 使用了 `babel-loader` 来处理 JavaScript 文件
            }, 
        ], 
    }, 
};

装载器use执行顺序是从右向左

js 复制代码
module.exports = { 
    module: { 
        rules: [ 
                { 
                    test: /.less$/,
                    use: ['style-loader', 'css-loader','less-loader'],
                    // 现将less文件装载到less-loader转化成css ,然后再装载到css 里,最后渲染到style 标签上
            }, 
        ], 
    }, 
};
  1. test 属性用于指定匹配的文件类型,这里使用了正则表达式 /.less$/ 来匹配以 .less 结尾的文件。

  2. use 属性用于指定处理该文件类型的加载器,这里使用了 style-loadercss-loaderless-loader来处理 less 文件。

include 属性用于指定应该包含在构建中的文件夹路径

js 复制代码
// 使用了 `path.resolve(__dirname, 'src')` 来指定包含 JavaScript 文件的 `src` 文件夹
module.exports = { 
    module: { 
        rules: [ 
            { 
                test: /\.js$/, 
                // 使用了正则表达式 `/.js$/` 来匹配以 `.js` 结尾的文件
                use: ['babel-loader'], 
                // 使用了 `babel-loader` 来处理 JavaScript 文件
                include: path.resolve(__dirname, 'src'), 
                // 使用了 `path.resolve(__dirname, 'src')` 来指定包含 JavaScript 文件的 `src` 文件夹
            }, 
        ], 
    }, 
};
js 复制代码
module.exports = { 
    module: { 
        rules: [ 
            { 
                test: /.css$/,
                use: ['style-loader', 'css-loader'],
                include: [
                          path.resolve(__dirname, 'styles'),
                          path.join(__dirname, 'css'),
                ],
            }, 
        ], 
    }, 
};
  1. test 属性用于指定匹配的文件类型,这里使用了正则表达式 /.css$/ 来匹配以 .css 结尾的文件。

  2. use 属性用于指定处理该文件类型的加载器,这里使用了 style-loadercss-loader 来处理 CSS 文件。

  3. include 属性用于指定应该包含在构建中的文件夹路径。这里使用了 path.resolve(__dirname, 'styles') 来指定包含 CSS 文件的 styles 文件夹。

exclude 属性用于指定应该排除在构建过程之外的文件或文件夹

js 复制代码
module.exports = { 
    module: { 
        rules: [ 
            { 
                test: /\.js$/, 
                // 使用了正则表达式 `/.js$/` 来匹配以 `.js` 结尾的文件
                use: ['babel-loader'], 
                // 使用了 `babel-loader` 来处理 JavaScript 文件
                exclude: path.resolve(__dirname, 'node_modules') ,
                // 在构建中,排除以目录中 node_modules 文件夹
                exclude: /.min.css$/,
                // 如果指定匹配的文件类型为 css 类型,使用了正则表达式 `/.min.css$/` 来排除以 `.min.css` 结尾的 CSS 文件
            }, 
        ], 
    }, 
};

oneOf 属性,当规则匹配成功时,只使用第一个匹配规则

js 复制代码
module.exports = {
  //...
  module: {
    rules: [
      {
        test: /.css$/,
        oneOf: [
          {
            resourceQuery: /inline/, // foo.css?inline
            use: 'url-loader',
          },
          {
            resourceQuery: /external/, // foo.css?external
            use: 'file-loader',
          },
        ],
      },
    ],
  },
};

oneOf 是一个数组,用于提供多个处理规则的选择。

  • 第一个处理规则使用了 resourceQuery: /inline/ 来匹配具有 inline 查询参数的 CSS 文件。对于这类文件,使用了 url-loader 来处理。
  • 第二个处理规则使用了 resourceQuery: /external/ 来匹配具有 external 查询参数的 CSS 文件。对于这类文件,使用了 file-loader 来处理。

loader 属性指定了要使用的加载器

loader属性使用较多,下面在详细介绍

js 复制代码
module.exports = {
  //...
  module: {
    rules: [
      //...
      {
        test: /.js$/,
        use:{
            loader: 'babel-loader', 
            // 使用 `babel-loader` 来处理以 `.js` 结尾的文件
        },
      },
    ],
  },
};

Webpack 会使用 babel-loader 来处理以 .js 结尾的文件

type 属性用于匹配模块

防止了 defaultRules 和它们的默认导入行为发生。

例如,如果你想通过自定义 loader 加载一个 .json 文件,你会需要将 type 设置为 javascript/auto 以绕过 webpack 内置的 json 导入。

type 属性一般和 test 属性一起使用(用 type 的解释器来处理 test 匹配到的文件)

js 复制代码
module.exports = {
  //...
  module: {
    rules: [
      //...
      {
        test: /.json$/,
        type: 'javascript/auto', 
        // 表示使用 JavaScript 解释器来处理 JSON 文件
        loader: 'custom-json-loader',
      },
    ],
  },
};

Webpack 会使用 custom-json-loader 来处理以 .json 结尾的文件。custom-json-loader 是一个加载器,用于处理 JSON 文件并将其转换为 JavaScript 模块。

resolve属性用于指定 Webpack 如何解析模块

resolve属性使用较多,点击官网查看更多配置属性

例如:其中一个 alias 属性

js 复制代码
module.exports = {
  resolve: {
    alias: { // 用于指定模块别名
      footer: './footer/default.js',
    },
  },
};

通过这样的配置,在代码中使用 footer 作为模块名时,Webpack 会自动解析为 ./footer/default.js 文件。这可以方便地在代码中引用文件,而不必使用冗长的绝对路径。

loader(转换各种源码)

loader 用于对模块的源代码进行转换(对文件进行预处理)

通过 loader 可以使 webpack 支持多种语言和预处理器语法编写的模块,loader只能在模块的匹配请求的规则属性(rule和rules)中进行配置。

用法:

在 webpack 配置对象中,需要将具体使用的(loader)加载器添加到 module 列表中

js 复制代码
module: {
  rules: [ //用于指定不同类型文件的处理规则
    {
      test: /.m?js$/, // 使用了 `test` 属性来匹配以`.m?js`结尾的文件
      exclude: /(node_modules)/, // 排除了 `node_modules` 文件夹,不进行处理
      use: { // 指定要使用的加载器
        loader: 'babel-loader', // 指定了要使用的加载器,这里使用了 `babel-loader`
        options: { // 用于指定 `babel-loader` 的配置选项
          presets: ['@babel/preset-env'], 
          // 使用了 `@babel/preset-env` 预设,用于转换现代 JavaScript 语法
          plugins: ['@babel/plugin-proposal-object-rest-spread'] 
          // 指定了要使用的 Babel 插件
        }
      }
    }
  ]
}

这样的配置,Webpack 会使用 babel-loader 来处理以.m?js结尾的文件,并使用指定的 Babel 预设和插件进行转换。

注意: 每种类型的加载器的配置项不一样,具体要查看官方文档

配置多个加载器

装载器use执行顺序为:从右向左或者从后向前

js 复制代码
module.exports = {
  //...
  module: {
    rules: [
      {
        //...
        test: /\.less$/i,
        exclude:[ // 排除,执行 Babel 转码会发生错误是文件
            /node_modules[\/]core-js/,
            /node_modules[\/]webpack[\/]buildin/,
        ],
        use: [
          'style-loader', // 使用 `style-loader` 将 CSS 内容嵌入到 HTML 页面中
          {
            loader: 'css-loader', // 使用 `css-loader` 将 CSS 文件解析成 CommonJS 模块
            options: {
              importLoaders: 1,
            },
          },
          {
            loader: 'less-loader', // 使用 `less-loader` 处理 Less 文件
            options: {
              noIeCompat: true,
            },
          }
        ],
      },
    ],
  },
};

webpack提供的加载器非常多,每个加载器的配置项也很多,下面用 less-loader 加载器,做一个介绍,更多更详细的加载器可以点击进入官网中查看

1、安装 lessless-loader

js 复制代码
$ npm install less less-loader --save-dev

2、将该 less-loader 添加到 webpack 的配置中去

js 复制代码
module.exports = {
  module: {
    rules: [
      {
        test: /.less$/i,
        use: [
          // compiles Less to CSS
          'style-loader',
          'css-loader',
          'less-loader',
        ],
      },
    ],
  },
};

3、根据可选项配置less-loader

名称 类型 默认值 描述
lessOptions {Object、Function} { relativeUrls: true } Less 的可选项。
additionalData {String、Function} undefined 在入口文件起始或末尾添加 Less 代码。
sourceMap {Boolean} compiler.devtool 是否生成 source map。
webpackImporter {Boolean} true 是否启用默认的 webpack importer。
implementation {Object、String} less 配置 Less 使用的实现库

additionalData 可选项的 String写法

js 复制代码
module.exports = {
  module: {
    rules: [
      {
        test: /.less$/i,
        use: [
          'style-loader',
          'css-loader',
          {
            loader: 'less-loader',
            options: {
              additionalData: `@env: ${process.env.NODE_ENV};`,
            },
          },
        ],
      },
    ],
  },
};

additionalData 可选项的 Funtion写法

js 复制代码
module.exports = {
  module: {
    rules: [
      {
        test: /.less$/i,
        use: [
          'style-loader',
          'css-loader',
          {
            loader: 'less-loader',
            options: {
              additionalData: async (content, loaderContext) => {
                // More information about available properties https://webpack.js.org/api/loaders/
                const { resourcePath, rootContext } = loaderContext;
                const relativePath = path.relative(rootContext, resourcePath);

                if (relativePath === 'styles/foo.less') {
                  return '@value: 100px;' + content;
                }

                return '@value: 200px;' + content;
              },
            },
          },
        ],
      },
    ],
  },
};

在vue项目中运用

需求:过滤掉项目中,源码的版本号

js 复制代码
// vue.config.js
const path = require('path'); 
function resolve(dir) { 
    // 地址格式化 
    return path.join(__dirname, dir) 
}

module.exports = { 
    publicPath: '/', // 指定构建后的资源的根路径,默认为"/" 
    outputDir: 'dist', // 指定构建后的资源的输出目录,默认为"dist"
    chainWebpack: (config) => {
    config.module
      .rule('string-replace')
      .test(/.js$/) // 匹配需要处理的js文件
      .include.add(path.resolve(__dirname, 'node_modules/vue')) // 包括Vue源码
      .add(path.resolve(__dirname, 'node_modules/jquery')) // 包括jQuery源码
      .add(path.resolve(__dirname, 'node_modules/vuex')) // 包括jQuery源码
      // 可以继续添加其他需要处理的第三方库的路径
      .end() // 结束将模块添加都包含列表
      .use('string-replace-loader') // 使用 string-replace-loader 加载器
      .loader('string-replace-loader')
      .tap(() => { // 使用 `tap` 方法来修改加载器的配置
        return {
          search: /v\d+.\d+.\d+/g, // 匹配版本号的格式
          replace: '', // 替换内容
        };
      });
      // 使用 `@web` 可以引用到 `./src` 目录下的文件
      config.resolve.alias.set('@web', path.resolve('./src'))
      // 解析项目中 ts 结尾的文件
      config.resolve.extensions.push('.ts');
    },
}
相关推荐
陈随易1 小时前
农村程序员-关于小孩教育的思考
前端·后端·程序员
云深时现月1 小时前
jenkins使用cli发行uni-app到h5
前端·uni-app·jenkins
昨天今天明天好多天1 小时前
【Node.js]
前端·node.js
亿牛云爬虫专家1 小时前
Puppeteer教程:使用CSS选择器点击和爬取动态数据
javascript·css·爬虫·爬虫代理·puppeteer·代理ip
2401_857610031 小时前
深入探索React合成事件(SyntheticEvent):跨浏览器的事件处理利器
前端·javascript·react.js
_xaboy1 小时前
开源项目低代码表单设计器FcDesigner扩展自定义的容器组件.例如col
vue.js·低代码·开源·动态表单·formcreate·低代码表单·可视化表单设计器
_xaboy1 小时前
开源项目低代码表单设计器FcDesigner扩展自定义组件
vue.js·低代码·开源·动态表单·formcreate·可视化表单设计器
雾散声声慢2 小时前
前端开发中怎么把链接转为二维码并展示?
前端
熊的猫2 小时前
DOM 规范 — MutationObserver 接口
前端·javascript·chrome·webpack·前端框架·node.js·ecmascript
天农学子2 小时前
Easyui ComboBox 数据加载完成之后过滤数据
前端·javascript·easyui