作为一个大前端开发,离不开webpack打包,熟悉甚至精通webpack打包是必须的。由于webpack比较重要,内容比较多,我准备写一个webpack系列的文章进行解读,本篇主要是解读常用的基础配置,其他系列文章:
安装 webpack
### 安装最新版本
npm install --save-dev webpack
### 安装指定版本
npm install --save-dev webpack@<version>
如果使用 webpack 4+ 版本,还需要安装webpack-cli
npm install --save-dev webpack-cli
在 package.json
添加一个 npm 脚本(npm script)
"scripts": {
"build": "webpack"
}
常用配置项
1. mode
设置打包环境,production
为生产环境,development
为开发环境。可以在不同环境配置不同打包需求,如在生产环境中,尽量提升打包速度,减少包体积等,在开发环境增加必要的调试信息。
module.exports = {
mode: process.env.NODE_ENV === 'production' ? 'production' : 'development',
};
2. devtool
-
为了更容易地追踪错误和警告,JavaScript 提供了 source map 功能,将编译后的代码映射回原始源代码。
-
根据不同环境配置不同的source map。对于开发环境,通常希望更快速的 source map,需要添加到 bundle 中以增加体积为代价,但是对于生产环境,则希望更精准的 source map,需要从 bundle 中分离并独立存在。具体可以参看 devtool
3. entry
打包的入口文件,可以是字符串/对象/数组
- 字符串形式,项目中只有一个打包入口文件时,使用这种形式,如:
module.exports = {
entry: './src/index.js',
};
- 对象形式,项目中有多个打包入口文件时,使用这种形式,入口文件随意命名,如:
module.exports = {
entry: {
a: './src/entry-a',
b: ['./src/entry-b1', './src/entry-b2'],
},
};
- 数组形式
module.exports = {
entry: ['./src/entry1', './src/entry2'],
};
4. output
- path
path.resolve(__dirname, 'dist')
表示绝对路径
- fileName
出口文件动态变化: [name].bundle.js
module.exports = {
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].bundle.js',
},
};
5. module
webpack 可以使用 loader
来预处理文件。这允许你打包除 JavaScript 之外的任何静态资源。可以使用 Node.js 来很简单地编写自己的 loader。
5.1 加载 js 资源
- 使用
babel-loader
加载 ES2015+ 代码,然后使用 Babel 转译为 ES5,React 项目中,还需要安装@babel/preset-react
npm install --save-dev babel-loader @babel/core @babel/preset-env @babel/preset-react
在 webpack 配置对象中,需要添加 babel-loader 到 module 的 loaders 列表中,像下面这样:
module.exports = {
module: {
rules: [
{
test: /\.js$/,
exclude: /(node_modules)/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env', '@babel/preset-react'],
plugins: ['@babel/plugin-proposal-class-properties'],
},
},
},
],
},
};
5.2 加载样式
为了从 JavaScript 模块中 import 一个 CSS 文件,你需要在 module
配置中 安装并添加 style-loader
和 css-loader
、postcss-loader
(css 自动加上兼容性前缀)
- 安装
style-loader
、css-loader
、postcss-loader
、px2rem-loader
npm install --save-dev style-loader css-loader postcss-loader px2rem-loader
在webpack.config.js
中添加配置
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: [
'style-loader',
'css-loader',
'postcss-loader',
{
loader: 'px2rem-loader', // 进行移动端适配
options: {
remUni: 75, // 按设计稿750的十分之一计算
remPrecision: 8, // 计算的精确度到小数点后8位
},
},
],
},
],
},
};
webpack 根据正则表达式,来确定应该查找哪些文件,并将其提供给指定的 loader。在这种情况下,以 .css 结尾的全部文件,都将被提供给 style-loader 和 css-loader。
关于打包css样式的,可以详见我的另一片文章: Webpack打包配置解读- CSS 样式篇
5.3 加载图片
假想,现在我们正在下载 CSS,但是我们的背景和图标这些图片,要如何处理呢?使用 file-loader
或者url-loader
(url-loader 在文件大小(单位 byte)低于指定的限制时,可以返回一个 DataURL) ,我们可以轻松地将这些内容混合到 CSS 中:
npm install --save-dev file-loader
在webpack.config.js
中配置file-loader
module.exports = {
module: {
rules: [
{
test: /\.(png|svg|jpg|gif)$/,
use: ['file-loader'],
},
],
},
};
- 当你
import MyImage from './my-image.png'
,该图像将被处理并添加到 output 目录,并且 MyImage 变量将包含该图像在处理后的最终 url。 - 当使用
css-loader
时,如上所示,你的 CSS 中的url('./my-image.png')
会使用类似的过程去处理。loader 会识别这是一个本地文件,并将 './my-image.png' 路径,替换为输出目录中图像的最终路径。 html-loader
以相同的方式处理<img src="./my-image.png" />
。
5.4 加载字体
file-loader
和 url-loader
可以接收并加载任何文件,然后将其输出到构建目录
调整webpack.config.js
文件
module.exports = {
module: {
rules: [
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
use: ['file-loader'],
},
],
},
};
5.5 按需加载 js 资源
bundle-loader
参考 React-router4 使用 bundle-loader 实现按需加载(code-splitting)
6. plugins
plugins 选项用于以各种方式自定义 webpack 构建过程。webpack 附带了各种内置插件,可以通过 webpack.[plugin-name] 访问这些插件。请查看这个页面获取插件列表和对应文档,但请注意这只是其中一部分,社区中还有许多插件。
6.1 设定 HtmlWebpackPlugin
HtmlWebpackPlugin
简化了 HTML 文件的创建,以便为你的 webpack 包提供服务。这对于在文件名中包含每次会随着编译而发生变化哈希的 webpack bundle 尤其有用。
安装:
npm install --save-dev html-webpack-plugin
调整webpack.config.js
文件
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
plugins: [
new HtmlWebpackPlugin({
template: path.join(__dirname, './public/index.html'),
projectName: require('./package.json').name, // 项目名
}),
];
}
HtmlWebpackPlugin
会默认生成 index.html 文件,把我们的原来的替换
6.2 清理 /dist 文件夹
通常,在每次构建前清理 /dist
文件夹,是比较推荐的做法,因此只会生成用到的文件。clean-webpack-plugin
安装clean-webpack-plugin
npm install --save-dev clean-webpack-plugin
const CleanWebpackPlugin = require('clean-webpack-plugin');
module.exports = {
plugins: [
new CleanWebpackPlugin(path.resolve(__dirname,'dist')),
];
}
6.3 Split CSS
MiniCssExtractPlugin
将 CSS 提取为独立的文件的插件,对每个包含 css 的 js 文件都会创建一个 CSS 文件,支持按需加载 css 和 sourceMap
只能用在 webpack4 中,对比另一个插件 ExtractTextPlugin
优点:
- 异步加载
- 不重复编译,性能更好
- 更容易使用
- 只针对 CSS
安装
npm install --save-dev mini-css-extract-plugin
修改webpack.config.js
的配置
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
plugins: [
new MiniCssExtractPlugin({
// 类似 webpackOptions.output里面的配置 可以忽略
filename: '[name].css',
chunkFilename: '[id].css',
}),
],
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
// 这里可以指定一个 publicPath
// 默认使用 webpackOptions.output中的publicPath
publicPath: '../',
},
},
'css-loader',
],
},
],
},
};
7. devServer
配置地本服务器,webpack-dev-server
是一个轻量级的服务器,开发环境中使用,可以实现热重载
安装webpack-dev-server
npm install webpack-dev-server --save-dev
启动webpack-dev-server
npm run webpack-dev-server
修改webpack.config.js
的配置
module.exports = {
devServer: {
open: true,
port: 5168, // 设置端口号,默认8080
},
};
结语
如果你也是一个对投资理财感兴趣的程序员,欢迎关注我的公众号「谷底飞龙」,一起成为技术界的投资大佬吧。