Skip to content

Vue3 实战 - 项目搭建

版本选择:

node 20.9.0

npm 10.1.0

Vue3: 3.4.21

Eslint: 8.57.0

Prettier:3.2.5

Vite:5.2.6

TypeScript:5.4.3

创建项目

这里使用 pnpm 来创建项目:

bash
$ pnpm create vite
... ...
 Project name: amu-admin
 Select a framework: Vue
 Select a variant: TypeScript

Scaffolding project in /Users/amu/Desktop/tmp/vue3/first...

Done. Now run:

  cd amu-admin
  pnpm install
  pnpm run dev

安装 pnpm: npm install pnpm -g

配置 Typescript

修改 tsconfig.json

json
{
    "compilerOptions": {
        "target": "ESNext", // 将代码编译为最新版本的 JS
        "useDefineForClassFields": true,
        "module": "ESNext", // 使用 ES Module 格式打包编译后的文件
        "lib": ["ESNext", "DOM", "DOM.Iterable"], // 引入 ES 最新特性和 DOM 接口的类型定义
        "skipLibCheck": true, // 跳过对 .d.ts 文件的类型检查

        /* Bundler mode */
        "moduleResolution": "node", // 使用 Node 的模块解析策略
        "allowImportingTsExtensions": true,
        "resolveJsonModule": true, // 允许引入 JSON 文件
        "isolatedModules": true, // 要求所有文件都是 ES Module 模块。
        "noEmit": true, // 不输出文件,即编译后不会生成任何js文件
        "jsx": "preserve", // 保留原始的 JSX 代码,不进行编译

        /* Linting */
        "strict": true, // 开启所有严格的类型检查
        "noUnusedLocals": true, // 报告未使用的局部变量的错误
        "noUnusedParameters": true, //报告函数中未使用参数的错误
        "noFallthroughCasesInSwitch": true, //确保switch语句中的任何非空情况都包含
        "esModuleInterop": true, // 允许使用 import 引入使用 export = 导出的内容
        "allowJs": false, //允许使用js
        "baseUrl": ".", //查询的基础路径
        "paths": { "@/*": ["src/*"], "#/*": ["src/types/*"] }, //路径映射,配合别名使用
        // Volar支持,指定全局组件类型
        "types": ["element-plus/global"]
    },
    "include": ["src/**/*.d.ts", "src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"],
    "exclude": ["node_modules"],
    "references": [{ "path": "./tsconfig.node.json" }]
}

修改 tsconfig.node.json

json
{
  "compilerOptions": {
    "composite": true,
    "skipLibCheck": true,
    "module": "ESNext",
    "moduleResolution": "Node",
    "allowSyntheticDefaultImports": true,
    "strict": true
  },
  "include": ["vite.config.ts"]
}

修改 env.d.ts

创建 vite 项目后,src 目录下会有一个 vite-env.d.ts 文件,重命名该文件为 env.d.ts,并移动到 src同级的 types 目录下,在里面添加一下代码:

ts
/// <reference types="vite/client" />
declare module '*.vue' {
    import { DefineComponent } from 'vue';
    const component: DefineComponent<object, object, any>;
    export default component;
}

修改 package.json

json
"scripts": {
    "ts": "vue-tsc --noEmit",
},

运行 pnpm run ts 即可查看文件是否有ts类型错误

配置路径别名

安装

bash
pnpm add @types/node -D

修改 vite.config.ts

typescript
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from "path"

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      "@": resolve(__dirname, "src"),
    }
  }
})

路径映射在上述修改 tsconfig.json 时通过 baseUrlpaths 属性已完成

反向代理

解决跨域问题 & 配置项目运行端口

ts
export default defineConfig({
  ... 
	server: {
      host: "0.0.0.0",
      port: 9000,
      open: true,
      proxy: {
          "/api": {
              target: "http://localhost:8080",
              changeOrigin: true,
              rewrite: (path: string) => path.replace(/^\/api/, ""),
          },
      },
  },
  ...
}

配置预加载组件

ts
export default defineConfig({
  ... 
  // 预加载项目必需的组件
  optimizeDeps: {
      include: [
          'vue',
      ]
  },
  ...
}

构建配置

ts
export default defineConfig({
  ... 
	build: {
      chunkSizeWarningLimit: 2000, // 消除打包大小超过500kb警告
      minify: 'terser', // Vite 2.6.x 以上需要配置 minify: "terser", terserOptions 才能生效
      terserOptions: {
          compress: {
              keep_infinity: true, // 防止 Infinity 被压缩成 1/0,这可能会导致 Chrome 上的性能问题
              drop_console: true, // 生产环境去除 console
              drop_debugger: true // 生产环境去除 debugger
          },
          format: {
              comments: false // 删除注释
          }
      }
  }
  ...
}