目录一. 概念1. 入口1.1 基础概念1.2 单文件入口1.3 多文件入口2. 出口2.1 基础概念2.2 使用占位符来为每个文件命名,保证名称唯一2.3 使用CDN和资源hash
需要理解四个核心概念:
通过配置 entry
属性,指定一个或多个起点,默认值 ./src
:
module.exports = {
entry: './path/leo/file.js'
};
用法:entry: string|Array
当 entry
中没有配置入口的文件对象的名称,默认使用的是 main
名称,输出就是 main.js
,即:
// 默认情况
module.exports = {
entry: './path/leo/file.js'
};
// 配置单个入口
const config = {
entry: {
main: './path/leo/file.js'
}
};
可以看出,实际上 默认情况 只是 配置单个入口 的简写形式。
另外,文件路径我们也可以传入一个数组,就会将多个依赖文件一起注入:
const config = {
entry: {
main: ['./path/leo/file.js', './path/leo/index.js', './path/leo/server.js']
}
};
用法:entry: {[entryChunkName: string]: string|Array}
多个文件完全分离,互相独立(每个 bundle 中都有一个 WEBpack 引导(bootstrap)),常见于只有一个入口的单页面应用。
const config = {
entry: {
app: './src/app.js',
vendors: './src/vendors.js'
}
};
指定 webpack 最终输出的文件输出位置和文件名等信息。
通过配置 output
属性,指定输出位置和文件名,默认输出位置为 ./dist
:
两个属性:
path
:输出的目录绝对路径;filename
:输出的文件名称;const path = require('path');
module.exports = {
entry: './path/leo/file.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'leo-webpack.bundle.js'
}
};
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].js'
}
output: {
path: "/home/proj/cdn/assets/[hash]",
publicPath: "Http://cdn.example.com/assets/[hash]/"
}
如果编译时不知道最终文件的 publicPath ,可以留空,并在入口文件中动态设置。或者在入口起点设置 __webpack_public_path__ 来忽略它。
__webpack_public_path__ = myRuntimePublicPath
让 webpack 能够处理非 JS 文件,在 import
或 “加载”模块时预处理文件。
通过配置 loader 两个属性来实现:
test
属性,用来标识出应该被对应的 loader 进行转换的某个或多个文件;use
属性,表示转换时要用哪个 loader;const path = require('path');
const config = {
output: {
filename: 'leo-webpack.bundle.js'
},
module: {
rules: [
{ test: /\.txt$/, use: 'raw-loader' }
]
}
};
module.exports = config;
如安装一个 CSS-loader
和 ts-loader
使得 webpack 可以加载 CSS 文件,或者将 TypeScript
转换成 javascript
:
npm install --save-dev css-loader ts-loader
使用:
// webpack.config.js
module.exports = {
module: {
rules: [
{ test: /\.css$/, use: 'css-loader' },
{ test: /\.ts$/, use: 'ts-loader' }
]
}
};
指定多个loader:
module: {
rules: [
{
test: /\.css$/,
use: [
{ loader: 'style-loader' },
{
loader: 'css-loader',
options: {
modules: true
}
}
]
}
]
}
可以在 import
语句或任何等效于 import
的方式中指定 loader,使用 !
将多个 loader 分开,每个部分都是相对于当前目录的解析。
import Styles from 'style-loader!css-loader?modules!./styles.css';
尽可能使用 module.rules,减少代码量,并且在出错时,更快地调试和定位 loader 中的问题。
webpack --module-bind jade-loader --module-bind 'css=style-loader!css-loader'
loader 会从数组最后一个开始,往前一个一个加载:
// webpack.config.js
module.exports = {
module: {
rules: [
{ test: /\.css$/, use: ['style-loader', 'css-loader'] },
]
}
};
让 webpack 能够执行更多任务,从优化和压缩,到重新定义环境中的变量,非常强大。
插件目的在于解决 loader 无法实现的其他事。
使用时,只需要 require
它,并添加到 plugins
数组,通过 new
实例化即可:
const htmlWebpackPlugin = require('html-webpack-plugin'); // 通过 npm 安装 const webpack = require('webpack'); // 用于访问内置插件
const config = {
module: {
rules: [
{ test: /\.txt$/, use: 'raw-loader' }
]
},
plugins: [
new HtmlWebpackPlugin({template: './src/index.html'})
]};
module.exports = config;
原理剖析:
webpack 插件是一个具有 apply
属性的 JavaScript 对象。apply
属性会被 webpack compiler
调用,并且 compiler
对象可在整个编译生命周期访问。
用法:
由于插件可以携带参数/选项,你必须在 webpack
配置中,向 plugins
属性传入 new
实例。
配置:
// webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin'); //通过 npm 安装
const webpack = require('webpack'); //访问内置的插件
const path = require('path');
const config = {
entry: './path/leo/file.js',
output: {
filename: 'my-first-webpack.bundle.js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
use: 'babel-loader'
}
]
},
plugins: [
new webpack.optimize.UglifyJsPlugin(),
new HtmlWebpackPlugin({template: './src/index.html'})
]
};
module.exports = config;
通过配置 mode
参数,指定当前的开发模式,有 development
和 production
两个值:
module.exports = {
mode: 'production'
};
也可以通过 CLI 参数传递:
webpack --mode=production
参数描述:
选项 | 描述 |
---|---|
development | 会将 process.env.node_ENV 的值设为development。启用 NamedChunksPlugin和 NamedModulesPlugin。 |
production | 会将 process.env.NODE_ENV 的值设为 production。启用 FlagDependencyUsagePlugin, FlagIncludedChunksPlugin, ModuleConcatenationPlugin, NoEmitOnErrorsPlugin,OccurrenceOrderPlugin, SideEffectsFlagPlugin 和 UglifyJsPlugin。 |
记住,只设置 NODE_ENV,则不会自动设置 mode。
webpack 的配置文件,是导出一个对象的 JavaScript 文件,由 webpack 根据对象定义的属性进行解析。
因为 webpack 配置是标准的 Node.js CommonJS 模块,你可以做到以下事情:
require(...)
导入其他文件;require(...)
使用 npm
的工具函数;?:
操作符;但应避免以下做法:
--env
)时,访问命令行接口(CLI)参数;// webpack.config.js
var path = require('path');
module.exports = {
mode: 'development',
entry: './foo.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'foo.bundle.js'
}
};
除了到处单个配置对象,我们也可以有一些其他方式:
我们可能需要同时考虑到开发环境和生产环境,在 webpack.config.js
中实现,我们会有至少两种方式:
传入两个参数:环境变量(查看 CLI 文档的环境选项)和 map 对象(argv
)参数。
module.exports = function(env, argv) {
return {
mode: env.production ? 'production' : 'development',
devtool: env.production ? 'source-maps' : 'eval',
plugins: [
new webpack.optimize.UglifyJsPlugin({
compress: argv['optimize-minimize'] // 只有传入 -p 或 --optimize-minimize
})
]
};
};
webpack 将运行由配置文件导出的函数,并且等待 Promise
返回。便于需要异步地加载所需的配置变量。
module.exports = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve({
entry: './app.js',
})
}, 5000)
})
}
我们把导出对象设置成一个数组,webpack 运行时,会将所有配置对象都构建,这对于针对多个构建目标(例如 AMD 和 CommonJS)打包一个 library非常有用。
module.exports = [{
output: {
filename: './dist-amd.js',
libraryTarget: 'amd'
},
entry: './app.js',
mode: 'production',
}, {
output: {
filename: './dist-commonjs.js',
libraryTarget: 'commonjs'
},
entry: './app.js',
mode: 'production',
}]
webpack 接受以多种编程和数据语言编写的配置文件。支持的文件扩展名列表,可以在 node-interpret 包中找到。使用 node-interpret,webpack 可以处理许多不同类型的配置文件。
文档介绍:《使用不同语言进行配置(configuration languages)》
为了用 TypeScript 书写 webpack 的配置文件,必须先安装相关依赖:
npm install --save-dev typescript ts-node @types/node @types/webpack
使用 TypeScript 书写 webpack 的配置文件:
// webpack.config.ts
import path from 'path';
import webpack from 'webpack';
const config: webpack.Configuration = {
mode: 'production',
entry: './foo.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'foo.bundle.js'
}
};
export default config;
在以下的例子中,使用了 JSX
(React
形式的 javascript)以及 Babel
来创建 JSON
形式的 webpack 配置文件:
首先安装依赖:
npm install --save-dev babel-reGISter jsxobj babel-preset-es2015
设置配置:
// .babelrc
{
"presets": [ "es2015" ]
}
// webpack.config.babel.js
import jsxobj from 'jsxobj';
// example of an imported plugin
const CustomPlugin = config => ({
...config,
name: 'custom-plugin'
});
export default (
);
开发中将程序分解成离散功能块,成为模块。
而 webpack 模块能够以各种形式表达他们的依赖关系:
import
语句;require()
语句;define
和 require
语句;css/sass/less
文件中的 @import
语句;url(...)
)或 HTML 文件中的图片链接(image url
);查看更多 模块方法。
使用 resolver
库来找到模块的绝对路径,帮助 webpack 找到 bundle 中需要引入的模块代码,这些代码包含在每个 require
/ import
语句中,在模块打包中,webpack 使用 enhanced-resolve 来解析文件路径
webpack 解析规则: 使用 enhanced-resolve
,webpack
支持解析三种文件路径:
import "/home/me/file";
import "C:\\Users\\me\\file";
import "../src/file1";
import "./file2";
import "module";
import "module/lib/file";
模块将在 resolve.modules
中指定的所有目录中搜索,另外可以使用 resolve.alias
做初始化模块路径。
解析器(resolver)检查路径是否指向文件或目录,如果是指向文件:
resolve.extensions
] 选项作为文件扩展名来解析,配置解析器在解析中能够接受哪些扩展名(例如 .js
, .jsx
)。如果是指向文件夹,则按照步骤找到正确拓展名的文件:
package.json
文件,则按照顺序查找 resolve.mainFields 配置选项中指定的字段。并且 package.json
中的第一个这样的字段确定文件路径。package.json
文件或者 package.json
文件中的 main
字段没有返回一个有效路径,则按照顺序查找 resolve.mainFiles
配置选项中指定的文件名,看是否能在 import/require
目录下匹配到一个存在的文件名。resolve.extensions
选项采用类似的方法进行解析。Loader 解析遵循与文件解析器指定的规则相同的规则。但是 resolveLoader
配置选项可以用来为 Loader 提供独立的解析规则。
每个文件系统访问都被缓存,以便更快触发对同一文件的多个并行或串行请求。在观察模式下,只有修改过的文件会从缓存中摘出。如果关闭观察模式,在每次编译前清理缓存。
注意:webpack 的 target
属性不要和output.libraryTarget
属性混淆。
在你的 webpack 配置中设置 target
的值:
module.exports = {
target: 'node'
};
在上面例子中,使用 node
webpack 会编译为用于「类 Node.js」环境(使用 Node.js 的 require
,而不是使用任意内置模块(如 fs
或 path
)来加载 chunk)。
更多详细的值,可以参考 构建目标(targets)
尽管 webpack 不支持向 target
传入多个字符串,你可以通过打包两份分离的配置来创建同构的库:
var path = require('path');
var serverConfig = {
target: 'node',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'lib.node.js'
}
//…
};
var clientConfig = {
target: 'web', // <=== 默认是 'web',可省略
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'lib.js'
}
//…
};
module.exports = [ serverConfig, clientConfig ];
到此这篇关于Webpack核心概念的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持编程网。
--结束END--
本文标题: Webpack4.x的四个核心概念介绍
本文链接: https://www.lsjlt.com/news/150950.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
下载Word文档到电脑,方便收藏和打印~
2024-01-12
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0