五个核心概念
| 概念 | 说明 |
|---|---|
| Entry | 代码打包的入口 |
| Output | 代码产物输出 |
| Loader | 处理 js 中引入的各种资源 |
| Plugins | 处理额外各种的事情,比如压缩代码等等,可以扩展各种强大的能力 |
| Mode | 区别开发模式生产模式 |
基本使用
| 目的 | 方法 |
|---|---|
| 处理样式文件 | 使用 style-loader/css-loader,如果是 less 还需要 less-loader |
| 处理 html | 使用 HtmlWebpackPlugin |
| 处理图片 | css 中引用了图片使用 url-loader,html 中引用了图片使用 html-loader |
| 处理其他资源 | file-loader |
loader
| loader | options |
|---|---|
| url-loader | /.(jpg|png|gif)$/ limit: base64 处理的大小限制 esModule: 是否以 ES 模块方式处理 name: 图片产物命名方法 |
| file-loader |
devServer
方便开发,监听文件变更,自动编译,自动打开刷新页面
npx webpack-dev-server
Mode
development production
process.env.NODE_ENV
提取 CSS 成单独文件
使用插件 mini-css-extract-plugin 并使用 MiniCssExtractPlugin.loader 替换 style-loader
CSS 兼容性处理
使用 postcss-loader、postcss-preset-env
postcss-preset-env 的作用是帮助 postcss-loader 根据 package.json 中的 browerslist 配置转换成具有兼容性的 css 代码
postcss-loader 示例
{
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: () => [
require('postcss-preset-env')()
]
}
}
browserslist 示例
{
"browserslist": {
"production":[
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
],
"development": [
">0.2%",
"not dead",
"not op_mini all"
]
}
}
压缩 css
使用插件 optimize-css-assets-webpack-plugin
new OptimizeCssAssetsWebpackPlugin()
js 语法检查
使用 eslint eslint-loader eslint-config-arbnb-base eslint-plugin-import
package.json 配置
{
"eslintConfig": {
"extends": "airbnb-base"
}
}
loader 配置
test: /\.js$/,
exclude: /node_modules/,
loader: 'eslint-loader',
options: {
fix: true
}
使规则失效
// eslint-disable-next-line
js 兼容性处理
使用 babel-loader babel @babel/core @babel/preset-env
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
一: @babel/preset-env 基本的语法转换 二: @babel/polyfill 全量兼容语法
import '@babel/polyfill'
三: core-js 按需使用兼用处理
presets: [
'@babel/preset-env',
{
useBuileIns: 'usage',
corejs: {
version: 3
},
targets: {
chrome: '60',
firefox: '60',
ie: '9',
safari: '10',
edge: '17'
}
}
]
html 和 js 代码压缩
mode: production 生产环境下自动压缩 js 代码,原理是生产环境会自动加载一些 plugins
html 压缩
new HtmlWebpackPlugin({
template: 'xxx.html',
// 压缩配置
minify: {
// 移除空格
collapseWhitespace: true,
// 移除注释
removeComments: true
}
})
完整配置示例
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const OptimizeCssAssetsWebpackPlugin = require("optimize-css-assets-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const commonCssLoader = [
MiniCssExtractPlugin.loader,
"css-loader",
{
loader: "postcss-loader",
options: {
ident: "postcss",
plugins: () => [require("postcss-preset-env")()],
},
},
];
module.exports = {
entry: "./src/index.js",
output: {
filename: "bundle.js",
path: resolve(__dirname, "build"),
},
module: {
rules: [
{
test: /\.css$/,
use: [...commonCssLoader],
},
{
test: /\.less$/,
use: [...commonCssLoader, "less-loader"],
},
{
test: /\.js$/,
exclude: /node_modules/,
enforce: "pre", // 优先执行
loader: "eslint-loader",
options: {
fix: true,
},
},
{
test: /\.js$/,
exclude: /node_modules/,
loader: "babel-loader",
options: {
presets: [
[
"@babel/preset-env",
{
useBuiltIns: "usage",
corejs: { version: 3 },
targets: {
chrome: "60",
},
},
],
],
},
},
{
test: /\.(jpg|png|gif)$/,
loader: "url-loader",
options: {
limit: 8 * 1024,
name: "[hash:10].[ext]",
outputPath: "image",
esModule: false,
},
},
{
test: /\.html$/,
loader: "html-loader",
},
{
exclude: /\.(js|css|less|html|jpg|png|gif)/,
loader: "file-loader",
options: {
outputPath: "assets",
},
},
],
},
plugins: [
new MiniCssExtractPlugin({
filename: "css/build.css",
}),
new OptimizeCssAssetsWebpackPlugin(),
new HtmlWebpackPlugin({
template: "./src/index.html",
minify: {
collapseWhitespace: true,
removeComments: true,
},
}),
],
devServer: {
contentBase: resolve(__dirname, 'build'),
compress: true,
port: 3000,
open: true,
}
};