本文详细介绍了 Webpack 的基本使用方法,包括配置 JS、TypeScript、CSS 及预处理器、静态资源和 Vue 文件的处理,还讲解了 Loader 与 Plugin 的区别及用法。
webpack 是前端构建工具,主要用于打包 js、css、图片等资源。
webpack 主要分为四个阶段:
首先安装必要的 loader
pnpm install babel-loader @babel/preset-env -D
module.exports = {
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader'
options: {
presets: ['@babel/preset-env']
}
}
]
}
]
}
};
处理 ts 可以利用 babel 也可以利用 ts-loader
pnpm install ts-loader -D
module.exports = {
module: {
rules: [
{
test: /\.ts$/,
use: ['babel-loader', 'ts-loader']
}
]
}
};
pnpm install @babel/preset-typescript -D
module.exports = {
module: {
rules: [
{
test: /\.ts$/,
use: [
{
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env', '@babel/preset-typescript']
}
}
]
}
]
}
};
需要使用到的 loader
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
]
}
};
这里 loader 的顺序是从右到左,从后往前执行,所以先执行 css-loader,然后执行 style-loader。
css-loader 的作用是将 css 文件转化为 js 模块,然后通过 style-loader 将 js 模块插入到 head 标签中。
只需要安装对应的 loader 即可
以 less 为例
module.exports = {
module: {
rules: [
{
test: /\.less$/,
use: ['style-loader', 'css-loader', 'less-loader']
}
]
}
};
PostCSS 是一款强大的 css 预处理器,它可以帮助我们实现很多功能,比如:
Tip
预处理器之于 CSS,就像 TypeScript 与 JavaScript 的关系;而 PostCSS 之于 CSS,则更像 Babel 与 JavaScript。
安装
npm install postcss postcss-loader -D
# 安装插件
npm install autoprefixer -D
使用
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
importLoaders: 1
}
},
{
loader: 'postcss-loader',
options: {
// 添加 autoprefixer 插件
plugins: [require('autoprefixer')]
}
}
]
}
]
}
};
PostCSS 也支持单独配置
// webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
importLoaders: 1
}
},
'postcss-loader'
]
}
]
}
};
// postcss.config.js
module.exports = {
plugins: [require('autoprefixer')]
};
常用的插件
postcss 与 预处理器是可以同时使用的
module.exports = {
module: {
rules: [
{
test: /\.less$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
importLoaders: 1
}
},
{
loader: 'postcss-loader',
options: {
plugins: [require('autoprefixer')]
}
}
'less-loader'
]
}
]
}
};
首先安装必要的 npm 包
pnpm i -D url-loader file-loader
然后在 webpack 配置中添加如下配置
module.exports = {
module: {
rules: [
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
use: [
{
loader: 'url-loader',
options: {
limit: 1024 * 10, // 10kb 以下的图片会被转为 base64 格式
name: 'images/[name].[hash:8].[ext]',
fallback: 'file-loader'
}
}
]
}
]
}
};
字体文件文件需要借助 file-loader 来处理,因为字体文件本身是无法被 webpack 处理的。
module.exports = {
module: {
rules: [
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
// 指定字体文件的目录
include: [path.resolve(__dirname, 'src/assets/fonts')],
use: [
{
loader: 'file-loader',
options: {
name: 'fonts/[name].[hash:8].[ext]',
esModule: false
},
type: 'javascript/auto'
}
]
}
]
}
};
在 vue 项目中编写的代码都是.vue 后缀结尾的文件
<script lang="ts" setup>
import { ref } from 'vue';
const msg = ref('hello');
</script>
<template>
<h1 class="hello">{{ msg }}</h1>
</template>
<style>
.hello {
color: red;
}
</style>
原生 Webpack 并不能处理这种内容格式的文件,为此我们需要引入专用于 Vue SFC 的加载器
npm install vue-loader -D
使用
const { VueLoaderPlugin } = require('vue-loader');
module.exports = {
module: {
rules: [
{
test: /\.vue$/,
use: ['vue-loader']
}
]
},
plugins: [new VueLoaderPlugin()]
};
Warning
vue-loader 库同时提供用于处理 SFC 代码转译的 Loader 组件,与用于处理上下文兼容性的 Plugin 组件,两者需要同时配置才能正常运行。
经过 vue-loader 处理后,SFC 各个模块会被等价转换为普通的 Javascript 模块
其中<template>内容会被转换为用于构造 Virtual DOM 结构的 render 函数;
<script>标签导出的对象会被转译成 Javascript 对象字面量形式。
vue-loader让 webpack 可以处理 vue 文件,我们需要将页面真正运行起来的话还需要以下插件
html-webpack-plugin 自动生成 htmlwebpack-dev-server 让页面真正运行起来,并具备热更新能力npm install html-webpack-plugin webpack-dev-server -D
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
// ...省略其他配置
plugins: [new HtmlWebpackPlugin()]
};
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
plugins: [new HtmlWebpackPlugin()]
};
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader']
}
]
}
};