从0到1:webpack5 搭建 Vue3 项目
theme: juejin
本文从0到1,使用 webpack5 搭建一个 Vue3 项目,一步一步完善,并对其中使用到的 plugin、loader 做出一些解释,让你对 webpack 有一个整体的认识。
本文使用的 NodeJS 版本为
16.15.1
起步
1、package.json
文件初始化
在项目文件夹下直接执行下面命令,创建 package.json
文件:
npm init -y
复制代码
对于 package.json
文件中各个字段的解释,可直接查看 npm官方文档。
2、安装 webpack、webpack-cli、webpack-dev-server
npm i webpack webpack-cli webpack-dev-server -D
复制代码
webpack
是真正执行打包工作的程序;webpack-cli
是webpack
的命令行接口,如果你想使用npx
来运行webpack
,请确保你已经安装了webpack-cli
。webpack-dev-server
是在本地开发阶段,用来在本地起一个 server。
3、在根目录创建 webpack.config.js
文件,配置内容:
const path = require('path');
const { resolve } = path;
const config = {
mode: 'production',
entry: {
main: './src/main.js'
},
output: {
path: resolve(__dirname, 'dist'), // 打包后的文件输出的目录
filename: `js/[name]_[chunkhash:8].js`, // 设置打包后的 js 文件名,如果在文件名前增加文件路径,会将打包后的 js 文件放在指定的文件夹下
}
};
module.exports = config;
复制代码
4、创建对应的 main.js
文件
5、在 package.json
文件中添加 build
脚本:
"scripts": {
"build": "webpack --config webpack.prod.js"
},
复制代码
这个时候就已经可以执行 npm run build
指令了,会将 main.js
文件打包到 dist/js
文件夹下。
6、安装 @babel/core、@babel/cli、@babel/preset-env、babel-loader
在开发过程中,我们会使用到一些 js 的新语法,但是并不是所有浏览器都支持这些语法(有些用户的浏览器可能已经很多年没更新过了),这个时候就需要把新语法转化成ES5 语法,而完成这个工作的就是 babel
。
详细了解 babel 可访问这里。
npm install --save-dev @babel/core @babel/cli @babel/preset-env babel-loader
复制代码
@babel/cli
是一个命令行接口,如果不需要,可以不安装。
在项目的根目录下创建一个命名为 babel.config.json
的配置文件(需要 v7.8.0 或更高版本),并将以下内容复制到此文件中:
{
"presets": [
[
"@babel/preset-env",
{
"targets": {
"edge": "17",
"firefox": "60",
"chrome": "67",
"safari": "11.1"
},
"useBuiltIns": "usage",
"corejs": "3.23.5"
}
]
]
}
复制代码
注意:preset-env
后面的配置参数是从 babel 官网的示例中复制的,使用时需要根据自己项目需要来设置。
babel
在进行转换时,需要知道要转换成哪个目标语法,而 targets
就是告诉 babel
以这些浏览器的版本为目标进行转换,转换后的 js 代码,至少要能在这些浏览器的这些版本上运行。 当然,大部分项目里面不会在这里设置目标浏览器,更多的是使用 browserslist
来设置,后面我们也会使用到。
另外在使用
useBuiltIns
时,需要指定corejs
,所以,也需要安装对应版本的依赖:npm i core-js@3
在 webpack.config.js 中配置 babel-loader
module: {
rules: [
// 它会应用到普通的 `.js` 文件
// 以及 `.vue` 文件中的 `<script>` 块
{
test: /\.js$/,
use: ['babel-loader'],
exclude: /node_modules/
}
]
},
复制代码
配置 babel-loader
时要注意,需要排除 node_modules
下面的文件,因为这里面的 js 文件,大多数情况下都是已经被编译过的,如果不排除,会导致它们又被 babel 编译,会报错;
7、安装 vue、vue-loader
使用 Vue3 时,不需要再安装 vue-template-compiler
,Vue3 的包里面已经依赖了 @vue/compiler-sfc
,而 vue-loader
里面就是用它来处理 .vue
文件的。
npm i vue vue-loader -D
复制代码
配置 vue-loader
const { VueLoaderPlugin } = require('vue-loader')
module.exports = {
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader'
}
]
},
plugins: [
// 请确保引入这个插件!
new VueLoaderPlugin()
]
};
复制代码
8、html-webpack-plugin
npm i html-webpack-plugin -D
复制代码
这个插件是用来生成 index.html
文件的,我们可以指定一个模板文件,在打包的时候,会以这个模板文件为基础,生成项目的入口文件index.html
,同时把打包后的 js 文件,以 <script>
标签的形式添加进这个 index.html
文件中。
配置
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
plugins: [
new HtmlWebpackPlugin({
template: path.resolve(__dirname, 'index.html'),
filename: 'index.html',
chunks: ['main'],
inject: true,
minify: {
html5: true,
collapseWhitespace: true,
preserveLineBreaks: false,
minifyCSS: true,
minifyJS: true,
removeComments: false
}
})
]
};
复制代码
以上配置完成之后,已经可以启动一个 Vue 项目了,后面继续增加其它配置。
9、安装 style-loader、css-loader、sass、sass-loader
项目开发时,如果使用了 sass/less 这些预处理语言,就需要安装对应的预处理器和 loader,这里以 sass 为例。
npm i sass sass-loader css-loader style-loader -D
复制代码
sass-loader
- 加载.scss/.sass
文件并把它们编译成 CSS ;sass
- sass 预处理器,sass 语法是由它来处理的;css-loader
- 处理 css 文件;style-loader
- 将 css 样式,以style
标签的形式插入到当前页面中。
配置:
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
{
test: /\.scss$/,
use: ['style-loader', 'css-loader', 'sass-loader']
}
]
},
复制代码
10、安装 vue-router
npm i vue-router
复制代码
创建 router/index.js
文件
import { createRouter, createWebHashHistory } from 'vue-router';
const Page1 = () => import('../views/Page1.vue');
const routes = [
{
path: '/',
name: 'home',
component: Page1
}
];
const router = createRouter({
history: createWebHashHistory(),
routes
});
export default router;
复制代码
需要修改 App.vue
文件,在里面添加一个 router-view
标签:
<div class="page">
<router-view></router-view>
</div>
复制代码
最后在 main.js
中将 router 对象添加到 app 实例上,
import { createApp } from 'vue';
import App from './App.vue';
import router from './router/index.js';
const app = createApp(App);
// 挂载路由
app.use(router);
app.mount('#app');
复制代码
11、图片等资源的处理
在 webpack4 中,我们使用的是 url-loader
来处理页面中用到的图片资源,但在 webpack5 中,已经有内置的资源模块(asset module),所以我们不需要再去安装url-loader
,直接使用内置的功能即可。 资源模块类型(asset module type),通过添加 4 种新的模块类型,来替换所有这些 loader:
asset/resource
发送一个单独的文件并导出 URL。之前通过使用file-loader
实现。asset/inline
导出一个资源的 data URI。之前通过使用url-loader
实现。asset/source
导出资源的源代码。之前通过使用raw-loader
实现。asset
在导出一个 data URI 和发送一个单独的文件之间自动选择。之前通过使用url-loader
,并且配置资源体积限制实现。
const config = {
module: {
rules: [
// 使用 webpack 内置的资源模块,对图片资源的处理
{
test: /\.(jpg|png|gif|jpeg)$/,
type: 'asset',
generator: {
// 设置图片被处理之后的名称,可以通过在名字前面加路径,将图片都放置在一个文件夹下,也可以通过 output.assetModuleFilename 来设置;
// 注意这里的 [ext],它已经包含了 . ,所以不能再在[has:8] 和 [ext] 之间加上点了
filename: 'img/[name]_[hash:8][ext][query]'
},
parser: {
dataUrlCondition: {
maxSize: 4 * 1024 // 4kb,设置阈值,小于这个大小的,会被处理成 base 64 的字符串,默认是8kb
}
}
},
// 参考上面图片的处理方式,可以设置其它资源的处理方式
// 视频、音频等
{
test: /\.(mp3|mp4|mov)$/,
type: 'asset',
generator: {
filename: 'media/[name]_[hash:8][ext][query]'
},
parser: {
dataUrlCondition: {
maxSize: 4 * 1024 // 4kb,设置阈值,小于这个大小的,会被处理成 base 64 的字符串,默认是8kb
}
}
}
]
},
};
复制代码
12、postcss
在编写 css 样式时,针对不同的浏览器,需要在一些属性前添加对应的前缀,这个可以交给 postcss 来处理。
PostCSS 是一个允许使用 JS 插件转换样式的工具。 这些插件可以检查(lint)你的 CSS,支持 CSS Variables 和 Mixins, 编译尚未被浏览器广泛支持的先进的 CSS 语法,内联图片,以及其它很多优秀的功能。 PostCSS 的 Autoprefixer 插件是最流行的 CSS 处理工具之一。
安装 postcss-loader
和 autoprefixer
npm i postcss-loader autoprefixer -D
复制代码
修改 css、scss 的相关配置,添加 postcss-loader
:
{
test: /\.css$/,
use: ['style-loader', 'css-loader', 'postcss-loader']
},
// 应用到 scss 文件
{
test: /\.scss$/,
use: ['style-loader', 'css-loader', 'postcss-loader', 'sass-loader']
},
复制代码
在根目录下创建 postcss.config.js
文件,配置 postcss 使用到的插件:
module.exports = {
plugins: [require('autoprefixer')]
};
复制代码
也可以直接使用 [postcss-preset-env](https://github.com/csstools/postcss-plugins/tree/main/plugin-packs/postcss-preset-env)
,使用这个时,不需要再去安装 autoprefixer
,因为这个预设里面已经依赖了它,在安装预设时,autoprefixer 就会被安装。
这里需要注意,给 css 添加前缀的是 autoprefixer
。
13、统一配置 browserslist
browserslist 文档:github.com/browserslis…
在前面我们使用 babel 时,需要指定我们打包时的目标浏览器,而在使用 autoprefixer
时,也需要指定目标浏览器,我们可以在根目录下创建.browserslistrc
配置文件,并配置目标浏览器,这样 babel 和 autoprefixer 都会使用这里的配置进行各自的处理。
也可以直接在 package.json
文件中,配置 browserslist
字段。
Browserslist 其实使用的是 Can I Use 来查询我们使用的语法是否在目标浏览器上可以使用。 在 node_modules/browserslist/package.json
文件中,可以在 dependencies
中看到,它依赖了一个叫caniuse-lite
的库。