跳转至

项目模版搭建

unplugin自动导入(生成文件)

  • 注意,react、vue等都可以自动导入

unplugin-auto-import

  • 将vue api类型以及api的的一些数据类型导入在global模块
  • 用这玩意得注意不能自己导入,否则会导致失效,比如elementplus手动导入ElMessageBox

vite.config.ts

import AutoImport from "unplugin-auto-import/vite";
import { ElementPlusResolver } from "unplugin-vue-components/resolvers";

{
    plugins: [
        AutoImport({
          imports: ["vue", "vue-router", "pinia"], // 预设
          dts: "src/gen/auto-import.d.ts", // 类型声明
          eslintrc: { enabled: true }, // 可选:生成 ESLint 全局规则
          resolvers: [ElementPlusResolver()],
        })
    ]
}

unplugin-vue-components:

  • 给模块vue扩展GlobalComponents接口以及自动导入(在template中直接使用组件而不需要在script中导入组件)
  • 组件
    • 自定义组件(都是vue文件的default(组件以default导出))
    • ElementPlusResolver:el组件
  • 不仅仅只是生成定义,还自动中注册组件,否则自己注册外部组件比较麻烦

vite.config.ts

import VueComponents from "unplugin-vue-components/vite";
import { ElementPlusResolver } from "unplugin-vue-components/resolvers";

{
    plugins: [
        VueComponents({
          dirs: ["src/components"], 
          dts: "src/gen/components.d.ts", 
          resolvers: [ElementPlusResolver()],
        }),
    ],
}

unplugin-icons+iconify

vite.config.ts

import VueComponents from "unplugin-vue-components/vite";
import IconResolver from "unplugin-icons/resolver";
import Icons from "unplugin-icons/vite";
{
    plugins: [
        VueComponents({
          dirs: ["src/components"],
          dts: "src/gen/components.d.ts",
          resolvers: [
            ElementPlusResolver(),
            IconResolver({
              enabledCollections: ["material-symbols"],
            }),
          ],
        }),
        Icons(),
    ],
}

iconify自定义脚本生成自动导入、组件

  • 这么做会比较卡,还是在 Iconify - home of open source icons 中浏览比较好
    import { writeFileSync, mkdirSync } from "fs";
    import iconsJson from "@iconify-json/material-symbols/icons.json"  with { type: 'json' };
    const camelCaseIconNames = Object.keys(iconsJson.icons).map((e) => {
      return {
        iconName: e,
        tname: e.split("-").map((e) => e[0].toUpperCase() + e.slice(1)).join("")
      };
    });
    
    try{mkdirSync("./src/gen/iconify");}catch(e){}
    writeFileSync("./src/gen/iconify/index.d.ts", `
    /* eslint-disable */
    // @ts-nocheck
    // Generated by liruohrh
    // biome-ignore lint: disable
    export {}
    
    /* prettier-ignore */
    declare global {
      ${camelCaseIconNames
      .map(e => `  const IMaterialSymbols${e.tname}: typeof import('~icons/material-symbols/${e.iconName}')['default']`)
      .join("\n").trim()}
    }
    `, { encoding: "utf-8" });
    writeFileSync("./src/gen/iconify/components.d.ts", `
    /* eslint-disable */
    // @ts-nocheck
    // Generated by liruohrh
    // biome-ignore lint: disable
    export {}
    
    /* prettier-ignore */
    declare module "vue" {
      export interface GlobalComponents {
        ${camelCaseIconNames
      .map(e => `    IMaterialSymbols${e.tname}: typeof import('~icons/material-symbols/${e.iconName}')['default']`)
      .join("\n").trim()}
      }
    }
    `, { encoding: "utf-8" });
    

Vue

  • vue
    • vue-router
    • pinia:状态管理
  • ui
    • element-plus:组件库
    • sass:css
    • tailwindcss
  • ts
    • @vue/tsconfig:vue官方ts配置,直接继承

生成vue组件.d.ts

  • tsconfig.vue.json
    {
      "extends": "./tsconfig.json",
      "compilerOptions": {
        "composite": false, 
        //仅做类型检查,不生成文件
        "noEmit": false, 
        //生成.d.ts、.js
        "declaration": true,
        //仅生成.d.ts
        "emitDeclarationOnly": true, 
        "outDir": "dist",
        "baseUrl": ".",
        "paths": {
          "@/*": [
            "./src/*"
          ]
        },
      },
      "include": [
        "src/**/*.ts",
        "src/**/*.vue" 
      ]
    }
    
  • pnpm add -D vue-tsc@^2.0.28
  • vue-tsc -p ./tsconfig.vue.json

Node

  • @types/node
  • ts
    • @tsconfig/nodeN

TS

  • typescript
  • tsconfig.json
    • 推荐写2个references:tsconfig.app.json、tsconfig.node.json

tsconfig.json

{
  //多类型项目配置,每个配置仅对配置的匹配规则匹配到的文件生效
  "references": [{path: ""}],
//继承某个文件
  "extends": "@vue/tsconfig/tsconfig.dom.json", 
//ts文件包含路径
  "include": [
    "env.d.ts",
    "src/**/*.vue"
  ],
//ts文件排除路径
  "exclude": [
    "src/**/__tests__/*"  // 排除测试文件
  ],
  // 启用项目引用(增量编译)
  "compilerOptions": {
    //编译后的 JS 语法级别,如`"ES2020"` → 生成 `async/await` 而不是 `__awaiter`
    "target": "ES2020",
    //模块系统,ESNext保留import/export;CommonJS生成exports.xxx
    "module": "ESNext",
    //Bundler: TS 5.0+, import省略扩展名
    "moduleResolution": "Bundler",
    // 启用项目引用(增量编译)
    "composite": true,
    // 指定增量编译缓存文件路径
    "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
    // 允许导入 .ts/.tsx/.mts/.cts 文件(Vite 需要)
    "allowImportingTsExtensions": true,
    //全局声明,无需import
    //1. 包含中的.d.ts文件,详细看ts/module
    //2. 外部库,加载xxx.d.ts(自己的./xxx)
    "types": [
      "vite/client",
      "node",
      "vue"
    ],
    //3. ts里的库,加载typescript/lib/lib.xxx.d.ts
    "lib": ["ES2020", "DOM", "DOM.Iterable"],
    //4. 仅该文件用, 在.d.ts文件顶部写`/// <reference types="xxx"/>`

    // 路径解析的基础目录
    "baseUrl": ".",
    // 路径别名配置,
    "paths": {
      "@/*": ["./src/*"]
    },
    // 允许隐式的 any 类型(关闭严格类型检查)
    "noImplicitAny": false, 
    // 允许在 TypeScript 项目中使用 .js 文件
    "allowJs": true
  }
}