前言
虽然在实际项目当中很少会从 0 到 1 配置一个项目,毕竟很多重复工作是没有必要的,脚手架将这些重复性的工作进行了整合,方便开发者使用。也正因如此,导致部分开发者过于依赖脚手架,却不清楚其内部的实现流程,因此通过从 0 到 1 去配置和搭建项目可以更好的理解开发中使用的脚手架都帮我们做了哪些事情。
准备工作
创建目录结构
这里直接使用 npm init vite@latest
命令生成 vue3
最新的目录结构:
当然,需要对这个目录进行一些调整:
- 将
vite.config.js
换成webpack.config.js
:因为我们要基于webpack5
对项目进行编译构建 - 初始化新的
package.json
:原本的package.json
依赖了一些我们不需要的内容,因此直接删除重新初始化 - 去除
index.html
中的<script type="module" src="/src/main.js"></script>
,因为这是vite
需要的,但webpack
并不需要
下面是调整后的目录结构:
安装基本依赖
下面列出了需要的一些基本依赖,其他的依赖在后面需要的时候在进行安装:
npm install vue@next
npm install webpack webpack-cli webpack-dev-server -D
对 webpack
进行基本配置
// webpack.config.js
const path = require('path')
module.exports = {
entry: {
path: './src/main.js'
},
output: {
filename: 'assets/js/[name].[contenthash:6].js',
path: path.resolve(__dirname, './dist')
}
}
在 package.json
中创建脚本
// package.json
"scripts": {
"dev": "webpack server --mode=development",
"build": "webpack --mode=production"
}
针对不同文件类型进行配置 webpack
启动项目
完后以上准备工作之后,我们就可以通过 npm run dev
命令来启动项目,但是你会发现这样的错误:
其实就是 webpack
不能认识 .vue
文件,它需要我们提供一个 loader
对其进行处理,这个 loader 就是官方文档中提到的:
其中 @vitejs/plugin-vue
这个是 vite
才需要的,因此我们只需要 vue-loader@next
、@vue/compiler-sfc
注意:vue-loader 默认是处理 vue2 的,这里使用的是 vue3,所以要安装 vue-loader@next
在 webpack
中处理 .vue
文件
首先通过 npm install vue-loader@next @vue/compiler-sfc -D
安装需要的依赖,然后在 webpack.config.js
中进行配置:
// webpack.config.js
const path = require('path')
const { VueLoaderPlugin } = require('vue-loader')
module.exports = {
entry: {
path: './src/main.js'
},
module: {
rules: [
{
test: /\.vue$/,
use: 'vue-loader'
}
]
},
output: {
filename: 'assets/js/[name].[contenthash:6].js',
path: path.resolve(__dirname, './dist')
},
plugins: [
new VueLoaderPlugin(),
]
}
配置完成之后,我们在通过 npm run dev
启动项目,不出意外的你将得到下面的错误:
显然 webpack
也不认识 <style></style>
中样式相关的内容,这一点大家都知道,那肯定是要使用 style-loader
和 css-loader
在 webpack
中处理 <style></style>
样式相关的内容
首先通过 npm install style-loader css-loader -D
安装需要的依赖,然后在 webpack.config.js
中进行配置:
// webpack.config.js
const path = require('path')
const { VueLoaderPlugin } = require('vue-loader')
module.exports = {
entry: {
path: './src/main.js',
},
module: {
rules: [
{
test: /\.vue$/,
use: 'vue-loader',
},
{
test: /.css$/,
use: ['style-loader', 'css-loader'],
},
],
},
output: {
filename: 'assets/js/[name].[contenthash:6].js',
path: path.resolve(__dirname, './dist'),
},
plugins: [
new VueLoaderPlugin(),
]
}
配置完成之后,又一次通过 npm run dev
启动项目,不出意外的你将又一次得到下面的错误:
意思就是说 webpack
仍然无法识别图片类型的文件,如:.(png|jpg|jpeg|gif)
等,那么到了这里相信你灵光一闪,想到了需要使用 file-loader/url-loader
,但在这我们不需要配置这两个 loader
,因为我们使用的是 webpack5
,是时候使用其中 资源模块(asset module) 的模块类型了.
配置 webpack
资源模块
废话不多说,直接上官方文档使用说明:
下面就是配置后的 webpack.config.js
内容:
const path = require('path')
const { VueLoaderPlugin } = require('vue-loader')
module.exports = {
entry: {
path: './src/main.js',
},
module: {
rules: [
{
test: /\.vue$/,
use: 'vue-loader',
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
{
test: /\.(png|jpe?g|gif)$/,
type: 'asset/resource',
generator: {
filename: 'assets/img/[hash][ext]'
}
}
],
},
output: {
filename: 'assets/js/[name].[contenthash:6].js',
path: path.resolve(__dirname, './dist'),
},
plugins: [
new VueLoaderPlugin()
]
}
这时候在通过 npm run dev
启动项目,发现终于没有报错了:
此时访问页面内容:
是不是会觉得
别慌问题不大,其实就是没有给 webpack
打包后的 js
代码指定模板.
为 webpack 指定模板
熟悉 webpack
的你肯定猜到要是用 html-webpack-plugin
插件,首先通过 npm install html-webpack-plugin -D
安装依赖,然后配置 webpack.config.js
文件:
const path = require('path')
const { VueLoaderPlugin } = require('vue-loader')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry: {
path: './src/main.js',
},
module: {
rules: [
{
test: /\.vue$/,
use: 'vue-loader',
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
{
test: /\.(png|jpe?g|gif)$/,
type: 'asset/resource',
generator: {
filename: 'assets/img/[hash][ext]'
}
}
],
},
output: {
filename: 'assets/js/[name].[contenthash:6].js',
path: path.resolve(__dirname, './dist'),
},
plugins: [
new VueLoaderPlugin(),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, './index.html')
})
]
}
此时,在重新通过 npm run dev
启动项目并访问页面:
至此,终于成功配置了一个简单的基于 vue3
和 webpack5
的项目.
优化配置文件
通过 F12 打开页面控制台,你会看到这么一段警告信息:
其中 __VUE_OPTIONS_API__
和 __VUE_PROD_DEVTOOLS__
对应的值都是 Boolean
类型,分别代表的是:
__VUE_OPTIONS_API__
:表示是否支持options api
的写法,默认是true
__VUE_PROD_DEVTOOLS__
:表示生产包是否要继续支持devtools
插件,默认是false
即便它们都有默认值,可以不进行设置,但是 Vue
希望我们自己去设置这两个配置,毕竟如果完全拥抱 Vue3
的话,写法上没有必要在使用 options api
的格式,这样在打包的时候,包的体量上也会有所减少.
const path = require('path')
const { VueLoaderPlugin } = require('vue-loader')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const { DefinePlugin } = require('webpack')
module.exports = {
entry: {
path: './src/main.js',
},
module: {
rules: [
{
test: /\.vue$/,
use: 'vue-loader',
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
{
test: /\.(png|jpe?g|gif)$/,
type: 'asset/resource',
generator: {
filename: 'assets/img/[hash][ext]',
},
},
],
},
output: {
filename: 'assets/js/[name].[contenthash:6].js',
path: path.resolve(__dirname, './dist'),
},
plugins: [
new VueLoaderPlugin(),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, './index.html'),
}),
new DefinePlugin({
__VUE_PROD_DEVTOOLS__: false,
__VUE_OPTIONS_API__: false,
}),
],
}
最后
首先通过 npm run build
查看打包后生成为目录结构:
目前存在的不足:
js
文件没有进行抽取,现在所有的js
内容都会默认打包到main.hash.js
中css
样式相关的内容没有进行抽取,现在的样式全部以<style></style>
标签的形式插入在html
文件中- 没有对
css
进行兼容处理 - 没有对
js
进行兼容处理 - 没有很好的区分各个环境,如:开发、测试、生产
- …
当然也有对应的处理方式:
- 通过
webpack
的optimization
选项配置,抽离对应的js
- 通过
mini-css-extract-plugin
插件来抽离对应的css
- 通过
postcss
对css
进行处理 - 通过
babel
对js
进行处理 - 针对公共配置部分进行抽取,或者通过环境变量去合成最终的配置项
- ···
以上的这些就不在一一进行配置,在需要时在进行相应配置即可.
至此,我们成功的将基于 vite + vue3
项目转换成了基于 webpack5 + vue3
的项目.