vue3+vite+ts+eslint9项目搭建

742 阅读3分钟

通过vite初始化项目

yarn create vite my-vue-app --template vue-ts

安装依赖 yarn

配置别名

yarn add @types/node --dev

// vite.config.ts
import { fileURLToPath, URL } from 'node:url'

resolve: {
  alias: {
    '@': fileURLToPath(new URL('./src', import.meta.url)),
  },
},

// tsconfig.app.json
{
    "compilerOptions": {
        "paths": {
          "@/*": ["./src/*"]
        },
        "baseUrl": "."
    }
}

配置 ESLint 和 prettier

//eslint 安装
yarn add eslint -D
//eslint vue插件安装
yarn add eslint-plugin-vue -D
//eslint 识别ts语法
yarn add @typescript-eslint/parser -D
//eslint ts默认规则补充
yarn add @typescript-eslint/eslint-plugin -D
//eslint prettier插件安装
yarn add eslint-plugin-prettier -D
//用来解决与eslint的冲突
yarn add eslint-config-prettier -D
//安装prettier
yarn add prettier -D

// 合起来
yarn add @eslint/js eslint eslint-plugin-prettier eslint-plugin-vue globals prettier vite-plugin-eslint -D

yarn eslint --init

配置eslint

// eslint.config.js
// 引入vue模版的eslint
import pluginVue from 'eslint-plugin-vue';
import eslint from '@eslint/js';
// ts-eslint解析器,使 eslint 可以解析 ts 语法
import tseslint from 'typescript-eslint';
// vue文件解析器
import vueParser from 'vue-eslint-parser';
import { readFile } from 'node:fs/promises';

const autoImportFile = new URL(
  './.eslintrc-auto-imports.json',
  import.meta.url
);
const autoImportGlobals = JSON.parse(await readFile(autoImportFile, 'utf8'));

export default tseslint.config({
  // tseslint.config添加了extends扁平函数,直接用。否则是eslint9.0版本是没有extends的
  extends: [
    eslint.configs.recommended,
    ...tseslint.configs.recommended,
    ...pluginVue.configs['flat/essential'], // vue3推荐的eslint配置
  ],
  languageOptions: {
    parser: vueParser, // 使用vue解析器,这个可以识别vue文件
    parserOptions: {
      parser: tseslint.parser, // 在vue文件上使用ts解析器
      sourceType: 'module',
    },
  },
  rules: {
    semi: ['warn', 'never'],
    'comma-dangle': ['error', 'never'],
    'no-unused-vars': 2,
    'space-before-function-paren': 0,
    'generator-star-spacing': 'off',
    'object-curly-spacing': 0, // 强制在大括号中使用一致的空格
    'array-bracket-spacing': 0, // 方括号
    '@typescript-eslint/no-explicit-any': ['off'],
  },
  languageOptions: {
    globals: {
      ...autoImportGlobals.globals,
    },
    parser: commpnParser,
    parserOptions: {
      ecmaVersion: 'latest',
      sourceType: 'module',
      parser: '@typescript-eslint/parser',
    },
  },
  ignores: ['dist/**', 'node_modules/**', '*.d.ts'],
});

配置prettier

// 根目录创建.prettierrc.json文件
{
  "printWidth": 80,
  "tabWidth": 2,
  "useTabs": false,
  "semi": true,
  "vueIndentScriptAndStyle": true,
  "singleQuote": true,
  "quoteProps": "as-needed",
  "bracketSpacing": true,
  "trailingComma": "es5",
  "jsxBracketSameLine": true,
  "jsxSingleQuote": false,
  "arrowParens": "always",
  "insertPragma": false,
  "requirePragma": false,
  "proseWrap": "preserve",
  "htmlWhitespaceSensitivity": "css",
  "endOfLine": "auto",
  "rangeStart": 0
}

配置vite

// vite.config.ts
import eslintPlugin from 'vite-plugin-eslint';

plugin: {
    eslintPlugin({
    include: ['src/**/*.js', 'src/**/*.vue'],
    cache: true,
  }),
}

新版eslint9会报错,“vite-plugin-eslint未声明”需手动声明

// vite-env.d.ts
declare module 'vite-plugin-eslint' {
  import { Plugin } from 'vite'
  import { ESLint } from 'eslint'

  /** Plugin options, extending from ESlint options */
  interface Options extends ESLint.Options {
    /** Path to ESLint instance that will be used for linting */
    eslintPath?: string
    /** Check all matching files on project startup */
    lintOnStart?: boolean
    /** A single file, or array of files, to include when linting */
    include?: string | string[]
    /** A single file, or array of files, to exclude when linting */
    exclude?: string | string[]
    /** Custom error formatter or the name of a built-in formatter */
    formatter?: string | ESLint.Formatter['format']
    /** The waring found will be printed */
    emitWarning?: boolean
    /** The errors found will be printed */
    emitError?: boolean
    /** Will cause the module build to fail if there are any warnings, based on emitWarning */
    failOnWarning?: boolean
    /** Will cause the module build to fail if there are any errors, based on emitError */
    failOnError?: boolean
  }

  const content: (rawOptions?: Options) => Plugin
  export default content
}

并在vite-env.d.ts设置moduleResolution: node

在vite.config.ts中使用环境变量

vite环境变量和模式

根目录新建环境配置文件 .env.development .env.production .env.test

⚠️ 注意

image.png

注意 Vite 默认是不加载 .env 文件的,因为这些文件需要在执行完 Vite 配置后才能确定加载哪一个,举个例子,root 和 envDir 选项会影响加载行为。不过当你的确需要时,你可以使用 Vite 导出的 loadEnv 函数来加载指定的 .env 文件。

// vite.config.ts
import { defineConfig, loadEnv } from 'vite'
export default (config: { mode: string }) => {
  console.log(loadEnv(config.mode, process.cwd()).VITE_BASE_URL)
  return defineConfig({
    plugins: [vue()],
    resolve: {
      alias: {
        '@': fileURLToPath(new URL('./src', import.meta.url)),
      },
    },
    base: loadEnv(config.mode, process.cwd()).VITE_BASE_DIR
   })
  }

配置自动引入

yarn add unplugin-vue-components unplugin-auto-import -D

// vite.config.ts
import { defineConfig, loadEnv } from 'vite';
import AutoImport from 'unplugin-auto-import/vite';
import Components from 'unplugin-vue-components/vite';
// 如果是使用饿了么的话
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers';
// 如果用的是ant design
// import { AntDesignVueResolver } from 'unplugin-vue-components/resolvers';

export default (config: { mode: string }) => {
  console.log(loadEnv(config.mode, process.cwd()).VITE_BASE_URL)
  return defineConfig({
    plugins: [
        vue(),
        AutoImport({
            resolvers: [ElementPlusResolver()],
            imports: ['vue', 'vue-router'], //自动导入vue和vue-router的相关函数
            // dts: true, // ts的
            dts: 'src/auto-imports.d.ts', // ts的
          }),
          Components({
            resolvers: [ElementPlusResolver()],
          }),
    ],
    resolve: {
      alias: {
        '@': fileURLToPath(new URL('./src', import.meta.url)),
      },
    },
    base: loadEnv(config.mode, process.cwd()).VITE_BASE_DIR
   })
  }

配置ts变量

// vite-env.d.ts

/// <reference types="vite/client" />
//声明.vue文件
declare module '*.vue' {
  import { ComponentOptions } from 'vue';
  const componentOptions: ComponentOptions;
  export default componentOptions;
}

// 识别环境变量
interface ImportMetaEnv {
  readonly VITE_BASE_URL: string;
}

interface ImportMeta {
  readonly env: ImportMetaEnv;
}

安装axios

yarn add axios