阅读视图

发现新文章,点击刷新页面。

vue3+vite+ts创建项目-企业级

Vue3+Vite+TS 企业级项目搭建完整指南(含多环境配置)

本文基于 Vue3、Vite4+、TypeScript 构建企业级项目,整合多环境配置、代码规范、自动导入、样式处理等核心功能,配置结构清晰可扩展,适配生产、开发、测试多场景需求。

一、初始化 Vue3 项目

采用 Vite 构建工具(比 Webpack 启动更快、热更新更高效,是 Vue3 官方推荐方案),快速初始化项目并集成 TypeScript。

步骤 1:执行初始化命令

# 使用 npm/cnpm/pnpm 均可,这里以 cnpm 为例
cnpm create vite@latest

# 若需指定版本,可执行:cnpm create vite

步骤 2:交互式配置项目

  1. 输入项目名:如 vite-vue3-ts-enterprise(建议英文,避免特殊字符)
  2. 选择框架:上下键切换至 Vue(默认适配 Vue3)
  3. 选择变体:切换至 TypeScript(集成 TS 类型校验)

步骤 3:安装依赖并启动项目

# 进入项目目录
cd vite-vue3-ts-enterprise

# 安装依赖(优先用项目包管理器,避免版本冲突)
cnpm install

# 启动开发环境
cnpm run dev

启动成功后,访问 http://localhost:5173 即可看到 Vue3 初始页面。Vite 默认端口为 5173,后续可在配置中修改。

二、基础配置(环境、别名、类型)

完善项目基础配置,解决路径别名、Node 类型、环境变量加载等核心问题,适配企业级开发习惯。

步骤 1:安装 Node 类型依赖

为 TS 提供 Node 环境类型定义,避免路径处理等操作时 TS 报错。

cnpm i @types/node --save-dev

步骤 2:配置 tsconfig.json

优化 TS 编译规则,添加路径别名、类型目录等配置,确保 TS 语法兼容 Vue3 单文件组件(SFC)。

{
  "compilerOptions": {
    "typeRoots": [
      "node_modules/@types", // 默认类型目录
      "src/types" // 自定义类型目录(后续可存放全局类型)
    ],
    "target": "ESNext", // 目标 ES 版本
    "useDefineForClassFields": true, // 适配 Vue3 类组件
    "module": "ESNext", // 模块规范
    "moduleResolution": "Node", // 模块解析方式
    "strict": true, // 开启严格模式(强制类型校验)
    "jsx": "preserve", // 保留 JSX 语法(适配 Vue3 JSX/TSX)
    "resolveJsonModule": true, // 允许导入 JSON 文件
    "isolatedModules": true, // 确保每个文件都是独立模块(Vite 要求)
    "esModuleInterop": true, // 兼容 CommonJS 模块
    "lib": ["ESNext", "DOM"], // 引入 ES 特性和 DOM 类型
    "skipLibCheck": true, // 跳过第三方库类型校验(提升编译速度)
    "noEmit": true, // 不生成编译产物(Vite 负责构建)
    "baseUrl": "./", // 基础路径
    "paths": { // 路径别名(简化导入,避免相对路径嵌套)
      "@": ["src"],
      "@/*": ["src/*"]
    }
  },
  "include": [ // 需要 TS 校验的文件
    "src/**/*.ts",
    "src/**/*.d.ts",
    "src/**/*.tsx",
    "src/**/*.vue",
    "build/**/*" // 新增:让 TS 识别 build 文件夹下的配置文件
  ],
  "references": [
    { "path": "./tsconfig.node.json" } // 关联 Node 环境配置
  ]
}

步骤 3:配置多环境变量(env 文件夹)

创建独立 env 文件夹管理不同环境变量,实现开发、测试、生产环境隔离,避免硬编码。

1. 创建 env 文件夹及配置文件

# 根目录创建 env 文件夹
mkdir env

# 新建 3 个环境配置文件(对应开发、测试、生产)
touch env/.env.development
touch env/.env.test
touch env/.env.production

2. 编写各环境变量

Vite 环境变量需以 VITE_ 为前缀,否则无法在业务代码中访问。

  • env/.env.development(开发环境) # 开发环境 API 基础地址 `` VITE_API_BASE_URL=http://localhost:3000/api `` # 环境标识 `` VITE_ENV=development `` # 调试模式(开发环境开启) ``VITE_DEBUG=true
  • env/.env.test(测试环境) VITE_API_BASE_URL=https://test.api.example.com `` VITE_ENV=test ``VITE_DEBUG=false
  • env/.env.production(生产环境) VITE_API_BASE_URL=https://api.example.com `` VITE_ENV=production ``VITE_DEBUG=false

步骤 4:拆分多环境 Vite 配置(build 文件夹)

将 Vite 配置拆分为「基础配置+环境专属配置」,统一放入 build 文件夹,提升可维护性,后续新增环境可快速扩展。

1. 创建 build 文件夹及配置文件

# 根目录创建 build 文件夹(集中管理所有配置)
mkdir build

# 新建 3 个配置文件
touch build/vite.base.ts # 基础通用配置
touch build/vite.dev.ts  # 开发环境配置
touch build/vite.prod.ts # 生产环境配置

调整后根目录核心结构:

vite-vue3-ts-enterprise/
├── build/               # 配置文件目录
│   ├── vite.base.ts     # 基础配置(通用逻辑)
│   ├── vite.dev.ts      # 开发环境专属配置
│   └── vite.prod.ts     # 生产环境专属配置
├── env/                 # 环境变量目录
├── src/                 # 业务代码目录
├── public/              # 静态资源目录
├── package.json
├── tsconfig.json
└── tsconfig.node.json

2. 编写 build 文件夹下的配置文件

(1)build/vite.base.ts(基础通用配置)

抽取所有环境共用逻辑,如插件、别名、环境变量目录、静态资源处理等。

import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue'; // Vue 单文件组件插件
import vueJsx from '@vitejs/plugin-vue-jsx'; // 支持 Vue3 JSX/TSX
import path from 'path';

export default defineConfig({
  // 环境变量目录(指定 env 文件夹,而非默认根目录)
  envDir: path.resolve(__dirname, '../env'),
  // 插件配置(所有环境共用插件)
  plugins: [
    vue(), // 解析 .vue 文件
    vueJsx() // 解析 .jsx/.tsx 文件
  ],
  // 路径解析配置
  resolve: {
    alias: {
      // 别名 @ 指向 src 目录(与 tsconfig.json 保持一致)
      '@': path.resolve(__dirname, '../src')
    }
  },
  // 基础构建配置
  build: {
    outDir: path.resolve(__dirname, '../dist'), // 打包输出目录
    assetsDir: 'assets', // 静态资源存放目录
    rollupOptions: {
      // 静态资源分类打包(按后缀名分组)
      output: {
        assetFileNames: (assetInfo) => {
          if (assetInfo.name?.endsWith('.css')) {
            return 'css/[name].[hash:8].[ext]';
          }
          if (assetInfo.name?.match(/.(png|jpg|jpeg|gif|svg)$/i)) {
            return 'images/[name].[hash:8].[ext]';
          }
          return 'assets/[name].[hash:8].[ext]';
        },
        // JS 文件分类打包
        chunkFileNames: 'js/chunks/[name].[hash:8].js',
        entryFileNames: 'js/[name].[hash:8].js'
      }
    }
  }
});
(2)build/vite.dev.ts(开发环境配置)

补充开发环境独有逻辑,如热更新、代理、端口配置等,优化开发体验。

import { defineConfig ,mergeConfig} from 'vite';
import path from 'path';
import baseConfig from './vite.base';

export default mergeConfig(
  baseConfig,
  defineConfig({
    mode: 'development', // 开发模式
    server: {
      port: 8080, // 自定义开发端口(替换默认 5173)
      open: true, // 启动后自动打开浏览器
      hmr: { // 热模块替换(提升热更新速度)
        host: 'localhost',
        port: 8080
      },
      proxy: { // 接口代理(解决跨域问题)
        '/api': {
          target: process.env.VITE_API_BASE_URL, // 读取环境变量中的 API 地址
          changeOrigin: true, // 开启跨域代理
          rewrite: (path) => path.replace(/^/api/, '') // 重写路径(移除前缀 /api)
        }
      }
    },
    css: {
      devSourcemap: true // 开发环境生成 CSS SourceMap(便于调试样式)
    }
  })
);
(3)build/vite.prod.ts(生产环境配置)

补充生产环境优化逻辑,如压缩、清除控制台、SourceMap 控制等,提升打包产物性能。

import { defineConfig ,mergeConfig} from 'vite';
import { visualizer } from 'rollup-plugin-visualizer'; // 打包分析插件
import baseConfig from './vite.base';

export default mergeConfig(
  baseConfig,
  defineConfig({
    mode: 'production', // 生产模式
    build: {
      minify: 'terser', // 使用 terser 压缩代码(比默认 esbuild 压缩更彻底)
      sourcemap: false, // 生产环境关闭 SourceMap(保护源码,减小包体积)
      terserOptions: {
        compress: {
          drop_console: true, // 清除控制台打印(生产环境可选)
          drop_debugger: true // 清除 debugger 语句
        }
      }
    },
    plugins: [
      // 打包分析插件(可选,生成可视化报告,优化包体积)
      visualizer({
        open: false, // 不自动打开报告
        filename: path.resolve(__dirname, '../dist/analysis.html')
      })
    ]
  })
);

4. 更新 package.json 脚本

修改启动、打包脚本,指向 build 文件夹下的对应配置文件,实现按环境加载配置。

"scripts": {
  "dev": "vite --config build/vite.dev.ts", // 启动开发环境
  "build:dev": "vue-tsc -b && vite build --config build/vite.dev.ts", // 开发环境打包(测试用)
  "build:test": "vue-tsc -b && vite build --config build/vite.prod.ts --mode test", // 测试环境打包
  "build:prod": "vue-tsc -b && vite build --config build/vite.prod.ts", // 生产环境打包
  "type-check": "vue-tsc --noEmit", // TS 类型校验(不生成产物)
  "preview": "vite preview" // 预览打包产物
}

vue-tsc -b 用于在打包前执行 TS 类型校验,若存在类型错误则终止打包,避免带错上线;--mode 参数用于指定环境,匹配 env 文件夹下的配置文件。

三、集成代码规范工具(ESLint + Prettier)

统一代码风格,减少团队协作冲突,自动修复格式问题,确保代码质量。需先在 VS Code 安装 ESLintPrettier 插件。

步骤 1:安装依赖

# ESLint 核心及 Vue/TS 适配依赖
cnpm i eslint @eslint/js typescript-eslint @typescript-eslint/parser @typescript-eslint/plugin eslint-plugin-vue vue-eslint-parser -D

# Prettier 及 ESLint 兼容依赖(解决两者规则冲突)
cnpm i prettier eslint-config-prettier eslint-plugin-prettier -D

# Vite ESLint 插件(开发时实时校验)
cnpm i vite-plugin-eslint -D

步骤 2:配置 ESLint(eslint.config.js)

ESLint 8.21.0+ 支持扁平配置文件,适配 Vue3+TS 语法,集成 Prettier 规则。

import globals from "globals";
import pluginJs from "@eslint/js";
import tseslint from "typescript-eslint";
import pluginVue from "eslint-plugin-vue";
import prettier from "eslint-plugin-prettier";
import prettierConfig from "eslint-config-prettier";
import eslintParser from "vue-eslint-parser";

export default [
  // 配置忽略文件(替代传统 .eslintignore)
  {
    ignores: [
      "node_modules/**",
      "dist/**",
      "public/**",
      "build/**",
      "src/assets/**",
      "*.config.js",
      "*.config.ts"
    ]
  },
  // 基础配置(适配 Vue/TS 文件)
  {
    files: ["**/*.{js,mjs,cjs,vue,ts,tsx}"],
    languageOptions: {
      parser: eslintParser, // 解析 Vue 单文件组件
      parserOptions: {
        parser: "@typescript-eslint/parser", // 解析 TS 语法
        ecmaVersion: 2020,
        sourceType: "module"
      },
      globals: { ...globals.browser, ...globals.node } // 全局变量
    },
    plugins: {
      vue: pluginVue,
      "@typescript-eslint": tseslint.plugin,
      prettier: prettier // 集成 Prettier
    },
    rules: {
      // 基础规则
      "no-var": "error", // 禁止使用 var
      "no-console": process.env.NODE_ENV === "production" ? "error" : "off", // 生产环境禁止 console
      "no-multiple-empty-lines": ["warn", { max: 1 }], // 最多允许 1 行空行
      
      // Vue 规则
      "vue/multi-word-component-names": "off", // 关闭组件名多单词校验(灵活命名)
      "vue/valid-template-root": "off", // 允许模板根节点多元素
      
      // TS 规则
      "@typescript-eslint/no-explicit-any": "off", // 允许使用 any(可选,根据团队规范调整)
      "no-unused-vars": ["error", { "varsIgnorePattern": "Vue" }], // 忽略 Vue 未使用警告
      
      // Prettier 规则(将 Prettier 错误作为 ESLint 错误提示)
      "prettier/prettier": "error"
    }
  },
  // 集成推荐规则
  pluginJs.configs.recommended,
  ...tseslint.configs.recommended,
  ...pluginVue.configs["flat/essential"],
  ...pluginVue.configs["flat/recommended"],
  prettierConfig // 覆盖 ESLint 与 Prettier 冲突的规则
];

步骤 3:配置 Prettier(.prettierrc.js)

定义代码格式化规则,与 ESLint 规则兼容,统一团队代码风格。

module.exports = {
  printWidth: 80, // 一行最多 80 字符
  tabWidth: 2, // 2 个空格缩进(与 Vue 官方一致)
  useTabs: false, // 不使用 Tab 缩进
  semi: true, // 行尾添加分号
  singleQuote: true, // 使用单引号
  quoteProps: "as-needed", // 对象 key 仅必要时加引号
  jsxSingleQuote: false, // JSX 中使用双引号
  trailingComma: "all", // 对象/数组末尾添加逗号(便于 diff)
  bracketSpacing: true, // 大括号内保留空格 { foo: bar }
  jsxBracketSameLine: false, // JSX 闭合标签换行
  arrowParens: "always", // 箭头函数单参数也加括号 (x) => x
  endOfLine: "auto" // 自动适配系统换行符
};

步骤 4:配置 VS Code 自动格式化(.vscode/settings.json)

实现保存时自动修复 ESLint 错误并执行 Prettier 格式化,提升开发效率。

{
  "eslint.enable": true,
  "eslint.format.enable": true,
  "editor.quickSuggestions": true,
  "eslint.validate": ["javascript", "javascriptreact", "vue-html", "typescript", "html", "vue"],
  "eslint.options": {
    "extensions": [".js", ".jsx", ".ts", ".tsx", ".vue"]
  },
  "editor.formatOnSave": true, // 保存时格式化
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": "explicit" // 保存时自动修复 ESLint 错误
  },
  // 不同文件指定默认格式化工具
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "[vue]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[typescript]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  }
}

步骤 5:添加脚本命令

"scripts": {
  // 新增 ESLint/Prettier 命令
  "lint": "eslint "src/**/*.{js,ts,vue,tsx}" --fix", // 自动修复 ESLint 错误
  "prettier": "prettier --write "src/**/*.{js,ts,vue,tsx,json,css}"" // 自动格式化
}

四、集成 Git 提交规范(Husky + Lint-Staged + CommitLint)

约束 Git 提交信息,在提交前校验代码规范,避免不合格代码入库,保障代码仓库整洁。

步骤 1:初始化 Git 仓库(若未初始化)

git init

步骤 2:安装依赖

# Husky(Git Hook 工具)、Lint-Staged(暂存区代码校验)
cnpm i husky@9.1.2 lint-staged@^15.2.7 -D

# CommitLint(提交信息校验)
cnpm i @commitlint/cli@^19.3.0 @commitlint/config-conventional@^19.2.2 -D

步骤 3:配置 Husky

# 生成 .husky 文件夹(存储 Git Hook 脚本)
npx husky init

# 手动创建 pre-commit(提交前校验)和 commit-msg(提交信息校验)脚本
touch .husky/pre-commit
touch .husky/commit-msg

步骤 4:编写 Hook 脚本

  • .husky/pre-commit(提交前校验暂存区代码) #!/bin/sh `` . "$(dirname -- "$0")/_/husky.sh" ```` echo -e "\033[33m ------------- 正在校验暂存区代码规范 ---------------- \033[0m" ``npx --no-install lint-staged
  • .husky/commit-msg(校验提交信息格式) #!/bin/sh `` . "$(dirname -- "$0")/_/husky.sh" ```` echo -e "\033[33m ------------- 正在校验提交信息格式 ---------------- \033[0m" ``npx --no-install commitlint --edit "$1"

步骤 5:配置 Lint-Staged(package.json)

仅对暂存区代码执行校验和格式化,提升效率(避免全量校验)。

"lint-staged": {
  "src/**/*.{vue,js,jsx,ts,tsx}": [
    "eslint --fix", // 自动修复 ESLint 错误
    "prettier --write" // 格式化代码
  ],
  "src/**/*.{cjs,json,css}": [
    "prettier --write" // 格式化配置文件和样式文件
  ]
}

步骤 6:配置 CommitLint(commitlint.config.cjs)

由于 package.json 默认为 ES 模块,需用 .cjs 后缀声明 CommonJS 格式。

module.exports = {
  ignores: [commit => commit.includes('init')], // 忽略 init 初始化提交
  extends: ['@commitlint/config-conventional'], // 基础规范
  rules: {
    'body-leading-blank': [2, 'always'], // 提交描述主体前空行
    'footer-leading-blank': [1, 'always'], // 底部说明前空行
    'header-max-length': [2, 'always', 108], // 标题最大长度 108
    'subject-empty': [2, 'never'], // 标题不可为空
    'type-empty': [2, 'never'], // 类型不可为空
    'type-enum': [ // 允许的提交类型(规范提交场景)
      2,
      'always',
      [
        'wip', // 开发中
        'feat', // 新增功能
        'fix', // 修复 Bug
        'test', // 测试相关
        'refactor', // 代码重构
        'build', // 构建配置(如依赖、打包)
        'docs', // 文档更新
        'perf', // 性能优化
        'style', // 代码风格(不影响逻辑)
        'ci', // 持续集成配置
        'chore', // 琐事(如配置文件修改)
        'revert', // 回滚代码
        'types', // 类型声明更新
        'release' // 版本发布
      ]
    ]
  }
};

提交格式规范

git commit -m "<type>[optional scope]: <description>"

# 示例
git commit -m "feat[user]: 新增用户登录功能"
git commit -m "fix[api]: 修复用户列表接口跨域问题"

说明:type 为提交类型(必填),optional scope 为涉及模块(可选),description 为提交描述(必填,简洁明了)。

五、Vue3 专属插件集成(提升开发效率)

步骤 1:自动导入(API/组件)

无需手动导入 Vue 内置 API(如 ref、reactive)和全局组件,减少模板代码。

# 安装自动导入插件
cnpm i unplugin-auto-import unplugin-vue-components -D

# 若使用 UI 库(如 Ant Design Vue),需安装对应解析器
cnpm i unplugin-vue-components/resolvers -D

更新 build/vite.base.ts,添加插件配置:

import AutoImport from 'unplugin-auto-import/vite';
import Components from 'unplugin-vue-components/vite';
import { AntDesignVueResolver } from 'unplugin-vue-components/resolvers'; // AntD Vue 解析器

export default defineConfig({
  plugins: [
    // ... 原有插件
    // 自动导入 Vue API
    AutoImport({
      imports: ['vue', 'vue-router', 'pinia'], // 自动导入的库
      dts: path.resolve(__dirname, '../src/auto-imports.d.ts'), // 生成类型声明文件
      eslintrc: {
        enabled: true // 生成 ESLint 配置,避免未导入警告
      }
    }),
    // 自动导入组件
    Components({
      dirs: [path.resolve(__dirname, '../src/components')], // 自定义组件目录
      extensions: ['vue', 'tsx'], // 组件后缀
      dts: path.resolve(__dirname, '../src/components.d.ts'), // 生成组件类型声明
      resolvers: [AntDesignVueResolver({ importStyle: false })], // UI 库组件自动导入
    })
  ]
});

步骤 2:PX 转 REM(适配多端)

实现移动端自适应,将 PX 自动转为 REM,替代手动计算。

cnpm i postcss @minko-fe/postcss-pxtorem autoprefixer -D

根目录创建 postcss.config.js

import pxtorem from '@minko-fe/postcss-pxtorem';
import autoprefixer from 'autoprefixer';

export default {
  plugins: [
    pxtorem({
      rootValue: 16, // 基准值(1rem = 16px,可根据设计稿调整)
      unitPrecision: 5, // 转换精度(保留 5 位小数)
      propList: ['*'], // 所有属性都转换
      selectorBlackList: ['no-rem'], // 类名含 no-rem 的不转换
      atRules: ['media'], // 媒体查询中的 PX 也转换
      exclude: /node_modules/ // 排除第三方库
    }),
    autoprefixer() // 自动添加 CSS 前缀(适配低版本浏览器)
  ]
};

步骤 3:SVG 组件化

将 SVG 图片转为 Vue 组件,支持按需引入和样式修改。

cnpm i vite-svg-loader -D

更新 build/vite.base.ts

import svgLoader from 'vite-svg-loader';

export default defineConfig({
  plugins: [
    // ... 原有插件
    svgLoader() // 解析 SVG 为 Vue 组件
  ]
});

使用方式:import Logo from '@/assets/logo.svg';,直接作为组件使用 <Logo />

六、项目测试与验证

  1. 开发环境启动cnpm run dev,验证热更新、接口代理、自动导入是否正常。
  2. 类型校验cnpm run type-check,确保无 TS 类型错误。
  3. 代码规范校验cnpm run lint,自动修复格式错误。
  4. 生产环境打包cnpm run build:prod,验证打包产物是否正常,体积是否合理。
  5. 提交测试:修改代码后执行 git add .git commit -m "test: 测试提交规范",验证 Husky 校验是否生效。

七、总结

本指南构建了一套企业级 Vue3+Vite+TS 项目架构,核心亮点:

  • 多环境配置拆分,环境隔离清晰,可快速扩展测试环境。
  • 完整代码规范体系,从开发到提交全流程约束,保障代码质量。
  • Vue3 专属插件集成,自动导入、自适应等功能提升开发效率。
  • 配置结构清晰,build 文件夹集中管理配置,便于后期维护。

可根据项目需求扩展 Pinia(状态管理)、Vue Router(路由)、单元测试等功能,适配更复杂的业务场景。

webpack5搭建vue3项目

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. 优化层:清理旧资源、多进程编译,提升打包效率和体验。

vue3+ts+eslint+prettier 实现代码风格统一

vue3+ts+eslint+prettier 实现代码风格统一

一.安装eslint

npm i eslint -D

1.初始化eslint

当前文章是基于 eslint9.39.2 版本创作

创建eslint配置文件,eslint8.21.0之后可以使用eslint.config.js文件名。

或使用命令初始化eslint配置文件

npx eslint --init

1)安装@eslint/config@lates image.png 2)选择要检测的文件 image.png 3)选择如何使用eslint image.png 4)选择使用哪种模块类型 image.png 5)框架选择 image.png 6)是否使用ts image.png 7)选择运行环境 image.png 8)希望配置文件用什么语法 image.png 9)选择要安装解析相关依赖包 image.png 10)选择希望使用的安装包工具 image.png

2.修改eslint.config.js中的相关配置
import pluginJs from '@eslint/js';
import tseslint from 'typescript-eslint';
import pluginVue from 'eslint-plugin-vue';
import prettier from 'eslint-plugin-prettier';
import prettierConfig from 'eslint-config-prettier';
import eslintparser from 'vue-eslint-parser';
export default [
  {
    files: ['**/*.{js,mjs,cjs,vue}'],
    ignores: [
        'node_modules/**', 
        'dist/**', 
        'public/**', 
        'coverage/**', 
        'src/assets/**'
    ],
    languageOptions: {
      globals: globals.browser,
      parser: eslintparser,
      parserOptions: {
        ecmaVersion: 2020,
        sourceType: 'module',
        parser: '@typescript-eslint/parser',
        ecmaFeatures: {
          jsx: true,
        },
      },
    },
  },

  pluginJs.configs.recommended,
  ...tseslint.configs.recommended,
  ...pluginVue.configs['flat/essential'],
  ...pluginVue.configs['flat/recommended'],
  prettierConfig, // 解决prettier和eslint的冲突
  {
    plugins: {
      prettier: prettier, // 使用prettier格式化
    },
    rules: {
      // 开启这条规则后,会将prettier的校验规则传递给eslint,这样eslint就可以按照prettier的方式来进行代码格式的校验
      'prettier/prettier': 'error',
      'no-var': 'error', // 要求使用 let 或 const 而不是 var
      'no-console': 'off',
      'no-restricted-globals': 'off',
      'no-restricted-syntax': 'off',
      'vue/multi-word-component-names': 'off', // 禁用vue文件强制多个单词命名
      'no-multiple-empty-lines': ['warn', { max: 1 }],
      'vue/valid-template-root': 'off',
      'no-unused-vars': 'off',
      'no-undef': 'off', // 自动引入vue和UI组件库报错问题
      '@typescript-eslint/no-unused-vars': 'off', // 关闭未使用变量规则
      '@typescript-eslint/no-explicit-any': 'off', // 关闭ts中any校验
      semi: ['error', 'always'],
      'no-debugger': 'warn', //提交时不允许有debugger
      'no-console': [
        //提交时不允许有console.log
        'warn',
        {
          allow: ['warn', 'error'],
        },
      ],
    },
  },
];

3.修改vite.config.ts
// 引入vite-plugin-eslint 
import eslintPlugin from 'vite-plugin-eslint' 
// 配置plugins 
eslintPlugin({ 
    include: ['src/**/*.js', 'src/**/*.vue'], 
    cache: true, 
}),

4.命令行式运行:修改 package.json
{ 
... 
"scripts": { 
    ... 
    "eslint:comment": "使用 ESLint 检查并自动修复 src 目录下所有扩展名为 .js 和 .vue 的文件", 
    "eslint": "eslint --ext .js,.vue --ignore-path .gitignore --fix src",//旧版 
    "eslint": "eslint \"src/**/*.{js,ts,vue}\" --fix",//新版 } 
... 
}
5.注意

eslintignore文件已经废除,新版本的gnore写在eslint.config.js中

image.png

二.安装prettier

1.安装

npm i prettier -D

npm i eslint-config-prettier -D

cnpm i eslint-plugin-prettier -D

2.创建配置文件: .prettierrc.js
// 一行最多 120 字符 
printWidth: 120, 
// 使用 2 个空格缩进
tabWidth: 2, 
// 不使用 tab 缩进,而使用空格 
useTabs: false, 
// 行尾需要有分号 
semi: true, 
// 使用单引号代替双引号 
singleQuote: true,
// 对象的 key 仅在必要时用引号 
quoteProps: 'as-needed', 
// jsx 不使用单引号,而使用双引号 
jsxSingleQuote: false, 
// 末尾使用逗号 
trailingComma: 'all', 
// 大括号内的首尾需要空格{ foo: bar }
bracketSpacing: true, 
// jsx 标签的反尖括号需要换行 
jsxBracketSameLine: false, 
// 箭头函数,只有一个参数的时候,也需要括号 
arrowParens: 'always', 
// 每个文件格式化的范围是文件的全部内容 
rangeStart: 0, 
rangeEnd: Infinity, 
// 不需要写文件开头的 
@prettier requirePragma: false, 
// 不需要自动在文件开头插入 
@prettier insertPragma: false, 
// 使用默认的折行标准 
proseWrap: 'preserve', 
// 根据显示样式决定 html 要不要折行 
htmlWhitespaceSensitivity: 'css', 
// 换行符使用 lf endOfLine: 'auto' 
}
3.修改 eslint.config.js 配置,添加prettier
import prettier from 'eslint-plugin-prettier' 
export default [ 
        ...
        { 
        plugins: {
            prettier: prettier,
        }, 
        rules: { 
            'prettier/prettier': 'error', 
        ... 
        }, 
    }, 
]
4.命令行式运行:修改 package.json
{ 
    ... 
    "scripts": { 
        ... 
        "prettier:comment": "自动格式化当前目录下的所有文件", 
        "prettier": "prettier --write" 
        } 
    ... 
}
5.解决eslint和pretter中的冲突
// eslint.config.js 
import prettier from 'eslint-plugin-prettier' 
import prettierConfig from'eslint-config-prettier'; 
export default [ 
    .... 
    // 插件的默认推荐配置需要直接包含在配置数组中 
    prettierConfig, 
    { 
        plugins: { 
            prettier: prettier, //解决prettier和eslint的冲突 
        }, 
        rules: { 
            'prettier/prettier': 'error', 
            ... 
        }, 
    }, 
]

三.创建.vscode文件夹

在项目的根目录创建文件夹.vscode,再在目录中创建settings.json文件。将如下代码拷其中

{ 
"editor.formatOnSave": true, // 核心:保存时自动格式化 
"editor.quickSuggestions": true,// 启用代码提示
"eslint.enable": true, //启用 ESLint 插件 
//ESLint 应该验证哪些文件类型 
"eslint.validate": [
    "javascript", 
    "javascriptreact", 
    "vue-html", 
    "typescript", 
    "html", 
    "vue"
 ], 
"eslint.options": { 
    // 检查这些文件类型
    "extensions": [".js", ".jsx", ".ts", ".tsx", ".vue"] 
 },
// 可选:保存时先修复代码问题(如ESLint报错)再格式化(前端常用) 
"editor.codeActionsOnSave": { 
    "source.fixAll": true
}, 
// 可选:指定默认格式化工具(比如前端优先用Prettier) 
"editor.defaultFormatter": "esbenp.prettier-vscode" ,
"[vue]": { 
    "editor.defaultFormatter": "esbenp.prettier-vscode"
    }, 
"[typescript]": { 
    "editor.defaultFormatter": "esbenp.prettier-vscode" 
    }
}

❌