Webpack5+Vue3+TS 项目搭建(从核心到功能完善)
一、核心基础搭建(确保项目能启动运行)
目标:搭建项目骨架,整合 Vue3、TS、Webpack5 核心依赖,实现最基础的页面渲染,确保开发环境能正常启动。
步骤 1:初始化项目 & 搭建目录
先创建项目文件夹并初始化,搭建最精简的核心目录:
# 创建项目目录并进入
mkdir vue3-ts-webpack5 && cd vue3-ts-webpack5
# 初始化 npm 项目
npm init -y
# 创建核心目录和文件
mkdir -p src/components public
touch tsconfig.json webpack.config.ts src/main.ts src/App.vue src/shims-vue.d.ts public/index.html
基础目录结构(仅保留核心文件):
vue3-ts-webpack5/
├── src/
│ ├── components/ # 组件目录
│ ├── App.vue # 根组件
│ ├── main.ts # 入口文件
│ └── shims-vue.d.ts # Vue 类型声明
├── public/
│ └── index.html # HTML 模板
├── tsconfig.json # TS 配置
├── webpack.config.ts # Webpack 核心配置
└── package.json # 依赖管理
二、安装核心依赖
仅安装启动项目必需的依赖,避免冗余:
# 核心业务依赖
npm i vue
# Webpack 基础依赖
npm i -D webpack webpack-cli webpack-dev-server
# Vue+TS 编译依赖
npm i -D typescript ts-loader @vue/compiler-sfc vue-loader
# 类型声明依赖
npm i -D @types/node @types/webpack ts-node
# HTML 处理插件
npm i -D html-webpack-plugin
步骤 3:配置 TS(tsconfig.json)
适配 Vue3+TS 编译规则,确保 TS 能识别 Vue 文件和模块:
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"moduleResolution": "Node",
"strict": true,
"jsx": "preserve",
"sourceMap": true,
"resolveJsonModule": true,
"esModuleInterop": true,
"lib": ["ES2020", "DOM"],
"types": ["node", "webpack-env"],
"baseUrl": ".",
"paths": { "@/*": ["src/*"] }, # 配置别名,方便导入
"skipLibCheck": true
},
"include": ["src/**/*", "webpack.config.ts"],
"exclude": ["node_modules", "dist"]
}
步骤 4:Vue 类型声明(shims-vue.d.ts)
解决 TS 无法识别 .vue 文件的问题:
declare module '*.vue' {
import type { DefineComponent } from 'vue'
const component: DefineComponent<{}, {}, any>
export default component
}
步骤 5:基础 Webpack 配置(webpack.config.ts)
仅配置核心规则,确保 Vue、TS、HTML 能正常编译:
import path from 'path'
import { Configuration } from 'webpack'
import HtmlWebpackPlugin from 'html-webpack-plugin'
import { VueLoaderPlugin } from 'vue-loader'
const config: Configuration = {
mode: 'development', // 先以开发模式搭建
entry: path.resolve(__dirname, 'src/main.ts'),
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'js/[name].js'
},
devServer: {
port: 8080,
hot: true,
open: true,
compress: true
},
resolve: {
extensions: ['.ts', '.vue', '.js', '.json'],
alias: { '@': path.resolve(__dirname, 'src') }
},
module: {
rules: [
// 处理 Vue 文件
{ test: /.vue$/, loader: 'vue-loader', exclude: /node_modules/ },
// 处理 TS 文件
{ test: /.ts$/, loader: 'ts-loader', options: { appendTsSuffixTo: [/.vue$/] }, exclude: /node_modules/ }
]
},
plugins: [
new VueLoaderPlugin(), // Vue 编译必需
new HtmlWebpackPlugin({
template: path.resolve(__dirname, 'public/index.html'),
filename: 'index.html'
})
],
devtool: 'eval-cheap-module-source-map'
}
export default config
步骤 6:编写基础业务代码
1. public/index.html(模板文件)
<!DOCTYPE html>
核心基础版
2. src/main.ts(入口文件)
import { createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')
3. src/App.vue(根组件)
核心基础搭建完成{{ msg }}<script setup ">
const msg: string = 'Vue3 + TS + Webpack5 运行正常'
console.log(msg)
步骤 7:配置启动脚本并测试
修改 package.json 的 scripts 字段,添加开发环境脚本:
"scripts": {
"dev": "webpack serve --config webpack.config.ts"
}
启动项目,验证核心功能:
npm run dev
浏览器自动打开 localhost:8080,能看到页面内容即说明核心搭建成功。
三、基础功能完善(处理样式、静态资源)
目标:添加 CSS 处理、图片/字体资源加载能力,让项目支持常见静态资源引用。
步骤 1:安装资源处理依赖
# CSS 处理依赖
npm i -D css-loader@6.10.0 style-loader@3.3.4
# 补充静态资源目录
mkdir -p src/assets/{images,fonts,styles}
步骤 2:更新 Webpack 配置(添加资源处理规则)
在 module.rules 中添加 CSS、图片、字体的处理规则:
// 新增规则,插入到 module.rules 数组中
{
test: /.css$/,
use: ['style-loader', 'css-loader'], // 开发环境嵌入 JS
exclude: /node_modules/
},
{
test: /.(png|jpg|jpeg|gif|svg)$/i,
type: 'asset', // webpack5 内置,小文件转 base64,大文件输出单独文件
parser: { dataUrlCondition: { maxSize: 8 * 1024 } }, // 8kb 为界
generator: { filename: 'assets/images/[name].[hash:8][ext]' }
},
{
test: /.(woff2?|eot|ttf|otf)$/i,
type: 'asset/resource',
generator: { filename: 'assets/fonts/[name].[hash:8][ext]' }
}
步骤 3:补充类型声明(shims-vue.d.ts)
让 TS 识别图片、字体资源:
// 新增以下内容
declare module '*.png'
declare module '*.jpg'
declare module '*.ttf'
declare module '*.woff2'
步骤 4:测试资源引用
在 src/assets/images 放入一张图片(如 logo.png),修改 App.vue:
核心基础搭建完成{{ msg }}<script setup
const msg: string = 'Vue3 + TS + Webpack5 运行正常'
console.log(msg)
重启 npm run dev,能正常显示图片和样式即说明功能生效。
四、进阶功能叠加(CSS 剥离、压缩、单位转换)
目标:优化 CSS 处理流程,实现生产环境剥离、压缩,以及 px 转 rem/vw 适配。
步骤 1:安装相关依赖
# CSS 剥离、压缩插件
npm i -D mini-css-extract-plugin css-minimizer-webpack-plugin
# 单位转换 + 浏览器兼容
npm i amfe-flexible # rem 适配必需
npm i -D postcss-loader postcss-preset-env postcss-pxtorem
步骤 2:配置 PostCSS(px 转 rem)
创建 postcss.config.js 文件,实现 px 自动转 rem:
module.exports = {
plugins: {
'postcss-preset-env': { // 自动添加浏览器前缀
autoprefixer: { overrideBrowserslist: ['last 2 versions', '> 1%'] }
},
'postcss-pxtorem': {
rootValue: 37.5, // 设计稿 375px 适配,750px 设为 75
propList: ['*'], // 所有属性转 rem
selectorBlackList: ['html'], // 排除 html 标签
exclude: /node_modules/i
}
}
}
步骤 3:更新 Webpack 配置(CSS 进阶处理)
区分开发/生产环境,实现 CSS 剥离、压缩,整合 PostCSS:
// 顶部引入新增插件
import MiniCssExtractPlugin from 'mini-css-extract-plugin'
import CssMinimizerPlugin from 'css-minimizer-webpack-plugin'
import crossEnv from 'cross-env' // 后续会安装,先引入
// 定义环境变量
const isProd = process.env.NODE_ENV === 'production'
// 更新 CSS 规则
{
test: /.css$/,
use: [
isProd ? MiniCssExtractPlugin.loader : 'style-loader', // 生产剥离,开发嵌入
'css-loader',
'postcss-loader' // 单位转换 + 前缀
],
exclude: /node_modules/
},
// 更新 plugins 数组
plugins: [
new VueLoaderPlugin(),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, 'public/index.html'),
filename: 'index.html',
minify: isProd ? { removeComments: true, collapseWhitespace: true } : false
}),
// 生产环境添加 CSS 剥离插件
...(isProd ? [
new MiniCssExtractPlugin({
filename: 'css/[name].[contenthash:8].css',
chunkFilename: 'css/[name].[contenthash:8].chunk.css'
})
] : [])
],
// 优化配置(添加 CSS 压缩)
optimization: {
minimizer: [
`...`, // 保留默认 JS 压缩器
new CssMinimizerPlugin() // 生产环境压缩 CSS
]
}
步骤 4:适配 rem 单位
在入口文件 main.ts 中引入 amfe-flexible:
import { createApp } from 'vue'
import App from './App.vue'
import 'amfe-flexible' // 动态设置根字体大小
import '@/assets/styles/index.css' // 可新增全局样式文件
重启项目,查看元素样式,px 已自动转为 rem 即生效。
五、打包优化(清理旧资源、多进程编译)
目标:优化打包流程,清理旧资源,提升打包速度。
步骤 1:安装优化依赖
# 清理旧资源插件
npm i -D clean-webpack-plugin
# 多进程编译优化
npm i -D happypack thread-loader
# 环境变量统一
npm i -D cross-env
步骤 2:配置打包清理旧资源
在 Webpack 配置中添加 CleanWebpackPlugin:
// 顶部引入
import { CleanWebpackPlugin } from 'clean-webpack-plugin'
// 加入 plugins 数组(放在最前面,确保打包前清理)
plugins: [
new CleanWebpackPlugin(), // 新增
new VueLoaderPlugin(),
// 其他插件...
]
步骤 3:配置 HappyPack 多进程编译
优化 TS 编译速度,利用多 CPU 核心:
// 顶部引入
import HappyPack from 'happypack'
import os from 'os'
// 初始化线程池(根据 CPU 核心数设置)
const happyThreadPool = HappyPack.ThreadPool({ size: os.cpus().length })
// 修改 TS 处理规则
{
test: /.ts$/,
use: 'happypack/loader?id=ts', // 用 HappyPack 代理
exclude: /node_modules/
},
// 新增 HappyPack 插件配置(加入 plugins 数组)
new HappyPack({
id: 'ts',
threadPool: happyThreadPool,
loaders: [
{
loader: 'ts-loader',
options: {
transpileOnly: true, // 只编译不做类型检查,提升速度
appendTsSuffixTo: [/.vue$/]
}
}
]
})
步骤 4:配置生产环境打包脚本
修改 package.json 的 scripts 字段:
"scripts": {
"dev": "cross-env NODE_ENV=development webpack serve --config webpack.config.ts",
"build": "cross-env NODE_ENV=production webpack --config webpack.config.ts"
}
六、最终测试与验证
步骤 1:测试生产环境打包
npm run build
验证 dist 目录:
- dist 目录已自动清理,无旧文件残留;
- CSS 已剥离为单独文件,且已压缩;
- 图片、字体资源按配置路径输出,带哈希值;
- JS 文件已分割(公共依赖、业务代码分离)。
步骤 2:验证功能完整性
打开 dist/index.html,确认:页面正常渲染、样式适配(rem 生效)、资源加载正常,所有需求功能均实现。
总结:搭建逻辑梳理
整个流程遵循「先跑通核心→再补基础功能→最后优化进阶」的原则,每一步都有明确目标,避免因配置叠加导致的问题:
- 核心层:Vue3+TS+Webpack5 基础整合,确保项目能启动;
- 基础层:处理样式、图片、字体,满足日常开发资源引用;
- 进阶层:CSS 剥离、压缩、单位转换,适配生产环境和移动端;
- 优化层:清理旧资源、多进程编译,提升打包效率和体验。