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
模块,它也提供了相应的解析器选项,如javascript
、javascript/auto
、javascript/dynamic
和javascript/esm
。 - 每个模块类型的解析器选项可以根据具体需求进行配置,例如启用解析特定语法的功能(如
requireEnsure
)。 - 除了上述模块类型外,还可以添加其他模块类型的解析器选项。
module.rules
创建模块时,匹配请求的规则数组,每个数组中的对象为一个rule,用于定义特定类型文件的处理规则。
在 Webpack 中,module.rule
和module.rules
是两个不同的配置项,用于定义模块的处理规则,但是module.rules
允许你在 webpack 配置中指定多个 loader。
同时,rules
和 oneOf
两者都是嵌套规则,每个嵌套规则包含它自己的条件,值得注意的是 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 标签上
},
],
},
};
-
test
属性用于指定匹配的文件类型,这里使用了正则表达式/.less$/
来匹配以.less
结尾的文件。 -
use
属性用于指定处理该文件类型的加载器,这里使用了style-loader
、css-loader
、less-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'),
],
},
],
},
};
-
test
属性用于指定匹配的文件类型,这里使用了正则表达式/.css$/
来匹配以.css
结尾的文件。 -
use
属性用于指定处理该文件类型的加载器,这里使用了style-loader
和css-loader
来处理 CSS 文件。 -
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、安装 less
和 less-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');
},
}