第263集:Vue 3自定义构建流程
概述
在Vue 3项目开发中,构建流程是非常重要的一环。默认的构建配置可能无法满足所有项目的需求,因此需要进行自定义构建流程配置。本集将深入探讨Vue 3自定义构建流程,包括npm脚本配置、自定义构建脚本、CI/CD集成和构建优化等内容,帮助开发者掌握Vue 3项目的自定义构建流程,提高构建效率和项目质量。
npm脚本配置
npm脚本是自定义构建流程的基础,通过配置package.json中的scripts字段,可以定义各种构建命令。
1. 基本npm脚本配置
// package.json
{
"name": "my-vue-project",
"version": "1.0.0",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview",
"lint": "eslint . --ext .vue,.js,.ts,.jsx,.tsx --fix",
"test": "vitest",
"test:coverage": "vitest run --coverage"
}
}2. 自定义构建脚本
可以创建自定义的构建脚本文件,然后通过npm脚本调用:
// package.json
{
"scripts": {
"build:custom": "node scripts/build.js"
}
}// scripts/build.js
const { execSync } = require('child_process')
const fs = require('fs')
const path = require('path')
console.log('开始自定义构建流程...')
// 步骤1:清理旧的构建目录
console.log('清理旧的构建目录...')
const distPath = path.join(__dirname, '../dist')
if (fs.existsSync(distPath)) {
fs.rmSync(distPath, { recursive: true, force: true })
}
// 步骤2:运行ESLint检查
console.log('运行ESLint检查...')
execSync('npm run lint', { stdio: 'inherit' })
// 步骤3:运行测试
console.log('运行测试...')
execSync('npm run test:coverage', { stdio: 'inherit' })
// 步骤4:构建项目
console.log('构建项目...')
execSync('vite build', { stdio: 'inherit' })
// 步骤5:生成构建报告
console.log('生成构建报告...')
// 可以在这里添加生成构建报告的逻辑
console.log('自定义构建流程完成!')3. 环境特定的构建脚本
可以为不同环境配置不同的构建脚本:
// package.json
{
"scripts": {
"build:dev": "vite build --mode development",
"build:test": "vite build --mode test",
"build:prod": "vite build --mode production"
}
}4. 复合脚本
使用&&或&组合多个命令:
// package.json
{
"scripts": {
"build:all": "npm run lint && npm run test && npm run build",
"dev:with-mock": "concurrently \"vite\" \"npm run mock-server\""
}
}自定义构建脚本
除了使用npm脚本外,还可以创建更复杂的自定义构建脚本,使用Node.js和各种构建工具库。
1. 使用shelljs简化脚本编写
// scripts/build.js
const shell = require('shelljs')
const fs = require('fs')
const path = require('path')
// 设置shelljs为严格模式
shell.set('-e')
console.log('开始自定义构建流程...')
// 清理旧的构建目录
console.log('清理旧的构建目录...')
shell.rm('-rf', 'dist')
// 运行ESLint检查
console.log('运行ESLint检查...')
shell.exec('npm run lint')
// 运行测试
console.log('运行测试...')
shell.exec('npm run test:coverage')
// 构建项目
console.log('构建项目...')
shell.exec('vite build')
console.log('自定义构建流程完成!')2. 使用gulp进行构建
// gulpfile.js
const gulp = require('gulp')
const eslint = require('gulp-eslint')
const { exec } = require('child_process')
// ESLint任务
gulp.task('lint', () => {
return gulp.src(['**/*.{vue,js,ts,jsx,tsx}', '!node_modules/**'])
.pipe(eslint())
.pipe(eslint.format())
.pipe(eslint.failAfterError())
})
// 测试任务
gulp.task('test', (done) => {
exec('npm run test:coverage', (err, stdout, stderr) => {
console.log(stdout)
console.error(stderr)
done(err)
})
})
// 构建任务
gulp.task('build', (done) => {
exec('vite build', (err, stdout, stderr) => {
console.log(stdout)
console.error(stderr)
done(err)
})
})
// 清理任务
gulp.task('clean', (done) => {
exec('rm -rf dist', (err, stdout, stderr) => {
console.log(stdout)
console.error(stderr)
done(err)
})
})
// 主构建任务
gulp.task('build:all', gulp.series('clean', 'lint', 'test', 'build'))3. 使用webpack进行构建
虽然Vue 3默认使用Vite,但也可以配置使用webpack进行构建:
// webpack.config.js
const { VueLoaderPlugin } = require('vue-loader')
const path = require('path')
module.exports = {
entry: './src/main.ts',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
},
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader'
},
{
test: /\.ts$/,
loader: 'ts-loader',
options: {
appendTsSuffixTo: [/\.vue$/]
}
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
]
},
plugins: [
new VueLoaderPlugin()
],
resolve: {
extensions: ['.ts', '.js', '.vue', '.json']
}
}// package.json
{
"scripts": {
"build:webpack": "webpack --mode production"
}
}CI/CD集成
1. GitHub Actions配置
# .github/workflows/ci.yml
name: CI
on:
push:
branches: [ main, master ]
pull_request:
branches: [ main, master ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: 使用Node.js 18
uses: actions/setup-node@v3
with:
node-version: 18
cache: 'npm'
- name: 安装依赖
run: npm ci
- name: 运行ESLint检查
run: npm run lint
- name: 运行测试
run: npm run test:coverage
- name: 构建项目
run: npm run build
- name: 上传构建产物
uses: actions/upload-artifact@v3
with:
name: dist
path: dist2. GitLab CI配置
# .gitlab-ci.yml
image: node:18
stages:
- install
- lint
- test
- build
- deploy
install:
stage: install
script:
- npm ci
artifacts:
paths:
- node_modules
cache:
key: $CI_COMMIT_REF_SLUG
paths:
- node_modules
lint:
stage: lint
script:
- npm run lint
dependencies:
- install
test:
stage: test
script:
- npm run test:coverage
dependencies:
- install
artifacts:
reports:
coverage_report:
coverage_format: cobertura
path: coverage/cobertura-coverage.xml
build:
stage: build
script:
- npm run build
dependencies:
- install
artifacts:
paths:
- dist
# 部署阶段可以根据实际情况配置
deploy:
stage: deploy
script:
- echo "部署到生产环境"
dependencies:
- build
only:
- main
- master3. Jenkins配置
// Jenkinsfile
pipeline {
agent any
stages {
stage('安装依赖') {
steps {
sh 'npm ci'
}
}
stage('ESLint检查') {
steps {
sh 'npm run lint'
}
}
stage('运行测试') {
steps {
sh 'npm run test:coverage'
}
post {
always {
publishHTML(target: [
allowMissing: false,
alwaysLinkToLastBuild: true,
keepAll: true,
reportDir: 'coverage',
reportFiles: 'index.html',
reportName: '代码覆盖率报告'
])
}
}
}
stage('构建项目') {
steps {
sh 'npm run build'
}
post {
success {
archiveArtifacts artifacts: 'dist/**/*', fingerprint: true
}
}
}
stage('部署') {
steps {
sh 'echo "部署到生产环境"'
}
when {
branch 'main'
}
}
}
}构建优化
1. 缓存策略
// vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins: [vue()],
build: {
// 启用构建缓存
cacheDir: '.vite/cache',
// 启用rollup缓存
rollupOptions: {
cache: true
}
}
})2. 并行构建
使用npm-run-all或concurrently实现并行构建:
// package.json
{
"scripts": {
"build:parallel": "npm-run-all --parallel lint test build"
}
}3. 增量构建
// vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins: [vue()],
build: {
// 启用增量构建
incremental: true
}
})4. 构建分析
使用rollup-plugin-visualizer分析构建产物:
// vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { visualizer } from 'rollup-plugin-visualizer'
export default defineConfig({
plugins: [vue()],
build: {
rollupOptions: {
plugins: [
visualizer({
open: true,
gzipSize: true,
brotliSize: true,
filename: 'stats.html'
})
]
}
}
})构建流程最佳实践
1. 分离构建环境
将构建环境与开发环境分离,使用不同的配置文件:
// vite.config.js - 基础配置
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
'@': '/src'
}
}
})
// vite.config.dev.js - 开发配置
import baseConfig from './vite.config.js'
export default {
...baseConfig,
server: {
port: 3000,
open: true
}
}
// vite.config.prod.js - 生产配置
import baseConfig from './vite.config.js'
export default {
...baseConfig,
build: {
outDir: 'dist',
sourcemap: false,
rollupOptions: {
output: {
manualChunks: {
vue: ['vue'],
'vue-router': ['vue-router'],
pinia: ['pinia']
}
}
}
}
}2. 使用构建变量
在构建过程中使用环境变量:
// vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { loadEnv } from 'vite'
export default defineConfig(({ mode }) => {
const env = loadEnv(mode, process.cwd())
return {
plugins: [vue()],
define: {
'process.env.NODE_ENV': JSON.stringify(mode),
'process.env.API_URL': JSON.stringify(env.VITE_API_URL)
}
}
})3. 构建前检查
在构建前进行各种检查,确保构建质量:
// scripts/pre-build.js
const shell = require('shelljs')
const fs = require('fs')
const path = require('path')
console.log('开始构建前检查...')
// 检查Node.js版本
const nodeVersion = process.version
console.log(`Node.js版本: ${nodeVersion}`)
const requiredVersion = 'v16.0.0'
if (nodeVersion < requiredVersion) {
console.error(`错误: 需要Node.js版本 ${requiredVersion} 或更高版本`)
process.exit(1)
}
// 检查npm版本
const npmVersion = shell.exec('npm --version', { silent: true }).stdout.trim()
console.log(`npm版本: ${npmVersion}`)
// 检查依赖是否已安装
if (!fs.existsSync(path.join(__dirname, '../node_modules'))) {
console.error('错误: 依赖未安装,请先运行 npm install')
process.exit(1)
}
console.log('构建前检查通过!')4. 构建后处理
在构建完成后进行一些处理,如生成构建报告、部署等:
// scripts/post-build.js
const shell = require('shelljs')
const fs = require('fs')
const path = require('path')
console.log('开始构建后处理...')
// 生成构建信息
const buildInfo = {
timestamp: new Date().toISOString(),
version: require('../package.json').version,
commit: shell.exec('git rev-parse HEAD', { silent: true }).stdout.trim(),
branch: shell.exec('git rev-parse --abbrev-ref HEAD', { silent: true }).stdout.trim()
}
fs.writeFileSync(
path.join(__dirname, '../dist/build-info.json'),
JSON.stringify(buildInfo, null, 2)
)
console.log('构建信息已生成!')
// 复制静态资源
console.log('复制静态资源...')
shell.cp('-r', 'public/*', 'dist/')
console.log('构建后处理完成!')总结
自定义构建流程是Vue 3项目开发中的重要环节,通过合理配置npm脚本、自定义构建脚本、CI/CD集成和构建优化,可以提高构建效率和项目质量。本集介绍了npm脚本配置、自定义构建脚本、CI/CD集成和构建优化等内容,同时还介绍了一些构建流程的最佳实践。
通过掌握Vue 3自定义构建流程,开发者可以根据项目需求定制构建过程,提高构建效率,减少构建错误,同时保证构建产物的质量。合理的构建流程配置对于大型Vue 3项目尤为重要,可以显著提高开发效率和项目可维护性。
在下一集中,我们将探讨Vue 3多页面应用构建,包括多页面应用的配置、路由设计、状态管理和部署策略等内容,进一步深入了解Vue 3的构建工具链。