前言:平时我们搭建vue项目都是用vue-cli脚手架快速搭建,下面我基于webpack5搭建vue环境,以此来加深了解vue-cli都做了些什么方便我们的工作。本文以vue3为例。
一、创建目录结构
1.新建vue-webpack文件夹,在该目录下运行npm init命令生成package.json项目配置文件。
2.在根目录新建webpack.config.js配置文件,以及项目代码。创建的目录结构大概如下图:
二、安装基本依赖
下面列出一些要安装的基本依赖,其他的依赖后面需要的时候再安装:
1.npm install vue
2.npm webpack webpack-cli web-dev-server -D
注意:在webpack 3中,webpack本身和它的CLI以前都是在同一个包中,但在第4版中,他们已经将两者分开来更好地管理它们。所以webpack4以上,要安装webpack-cli。
webpack-dev-server是一个基于Node.js的开发服务器,用于在开发过程中提供实时的热更新和自动刷新功能。它可以监听文件的变化,并在文件改变时重新编译和刷新页面,以提高开发效率。下面有详细讲解。
三、webpack基本配置
// webpack.config.js
const path = require('path');
module.exports = {
entry: {
path: './src/main.js'
},
output: {
filename: 'asset/js/[name].[contenthash:6].js',
path: path.resolve(__dirname, './dist'),
}
}
entry入口起点,一个html文件对应一个入口,单页面(SPA)只有一个入口,多页面有多个入口。
四、package.json创建脚本
// package.json
"scripts": {
"dev": "webpack server --mode=development",
"build": "webpack --mode=production"
},
五、启动项目
完成以上准备动作,就可以运行npm run dev来启动项目了,但是这时候会出现下图错误
这是因为webpack不能认识.vue文件,需要安装loader对其进行处理。安装命令如下:
npm install vue-loader@next @vue/compiler-sfc -D
vue-loader默认处理是vue2的,这里使用的是vue3,所以要安装vue-loader@next
// 单文件组件示例
<script setup>
import { ref } from 'vue'
const greeting = ref('Hello World!')
</script>
<template>
<p class="greeting">{{ greeting }}</p>
</template>
<style>
.greeting {
color: red;
font-weight: bold;
}
</style>
如你所见,Vue 的单文件组件是网页开发中 HTML、CSS 和 JavaScript 三种语言经典组合的自然延伸。<template>、<script> 和 <style> 三个块在同一个文件中封装、组合了组件的视图、逻辑和样式。
import MyComponent from './MyComponent.vue'
export default {
components: {
MyComponent
}
}
Vue SFC 是一个框架指定的文件格式,因此必须交由 @vue/compiler-sfc 编译为标准的 JavaScript 和 CSS,一个编译后的 SFC 是一个标准的 JavaScript(ES) 模块,这也意味着在构建配置正确的前提下,你可以像导入其他 ES 模块一样导入 SFC。
六、webpack处理.vue文件
安装vue-loader和@vue/compiler-sfc依赖后,在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: 'asset/js/[name].[contenthash:6].js',
path: path.resolve(__dirname, './dist'),
},
plugins: [
new VueLoaderPlugin()
]
}
配置完成之后,我们再通过npm run dev启动项目,发现还是报错:
原因同上,webpack不认识<style></style>相关内容,需要安装css-loader、style-loader依赖。
七、webpack处理<style></style> 样式相关的内容
通过命令npm install css-loader style-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: 'asset/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的内容:
// 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: 'asset/img/[fullhash][ext]'
}
},
{
test: /\.svg$/i,
type: 'asset/inline'
}
]
},
output: {
filename: 'asset/js/[name].[contenthash:6].js',
path: path.resolve(__dirname, './dist'),
},
plugins: [
new VueLoaderPlugin()
]
}
这时候npm run dev启动项目,终于不再报错了,但是页面没渲染出来。这是因为没有给webpack打包后的js指定模板。
九、为webpack指定模板
通过npm install html-webpack-plugin -D安装依赖,配置webpack.config.js文件后:
// webpack.config.js
const path = require('path');
const htmlWebpackPlugin = require('html-webpack-plugin');
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: 'asset/img/[fullhash][ext]'
}
},
{
test: /\.svg$/i,
type: 'asset/inline'
}
]
},
output: {
filename: 'asset/js/[name].[contenthash:6].js',
path: path.resolve(__dirname, './dist'),
},
plugins: [
new VueLoaderPlugin(),
new htmlWebpackPlugin({
template: path.resolve(__dirname, './index.html')
})
]
}
这时候再启动项目并访问页面,简单的vue项目环境就搭建成功了。
十、优化配置文件
const path = require('path');
const htmlWebpackPlugin = require('html-webpack-plugin');
const {VueLoaderPlugin} = require('vue-loader');
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: 'asset/img/[fullhash][ext]'
}
},
{
test: /\.svg$/i,
type: 'asset/inline'
}
]
},
output: {
filename: 'asset/js/[name].[contenthash:6].js',
path: path.resolve(__dirname, './dist'),
clean: true, // 在构建前清除目标输出
},
plugins: [
new VueLoaderPlugin(),
new htmlWebpackPlugin({
template: path.resolve(__dirname, './index.html')
}),
new DefinePlugin({
__VUE_PROD_DEVTOOLS__: false,
__VUE_OPTIONS_API__: false,
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__: true
}),
]
}