Webpack5+Vue3+TS 项目搭建(从核心到功能完善)

33 阅读4分钟

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 生效)、资源加载正常,所有需求功能均实现。

总结:搭建逻辑梳理

整个流程遵循「先跑通核心→再补基础功能→最后优化进阶」的原则,每一步都有明确目标,避免因配置叠加导致的问题:

  1. 核心层:Vue3+TS+Webpack5 基础整合,确保项目能启动;
  2. 基础层:处理样式、图片、字体,满足日常开发资源引用;
  3. 进阶层:CSS 剥离、压缩、单位转换,适配生产环境和移动端;
  4. 优化层:清理旧资源、多进程编译,提升打包效率和体验。