仓库地址

仓库地址:https://gitee.com/tongchaowei/nuxt-ts-vite-template
项目源码下载:https://gitee.com/tongchaowei/nuxt-ts-vite-template/releases

全局安装 pnpm 包管理工具

执行如下命令在系统全局安装 pnpm 包管理工具:

npm i pnpm -g 

image.png

创建 Nuxt 项目

执行如下命令创建 Nuxt 项目:

npx nuxi@latest init <project-name>

选择包管理工具,pnpm

> Which package manager would you like to use?
npm
> pnpm
yarn
bun

是否初始化 Git 仓库,这里选择了初始化 Git 仓库

> Initialize git repository?
> Yes /   No

image.png
然后,进入项目目录中,执行如下命令确保项目中的依赖已被安装

pnpm install

启动运行项目,测试项目是否创建成功

pnpm run dev

image.png
image.png

关于 Nuxt 项目中的目录别名

在项目根目录中的 .nuxt/tsconfig.json 文件中,在其中的 paths 配置项中我们可以发现 Nuxt 已经为项目的许多目录进行别名配置:

这里仅对一些常用的目录别名进行相关说明

  • nuxt:node_modules 中 Nuxt 依赖包的别名;
  • ~/@/~~/@@:项目根目录的别名;
  • assets:项目根目录中 assets 目录的别名;
  • public:项目根目录中 public 目录的别名;
  • #components:项目根目录中 components 目录的别名;

配置 TypeScript

中文文档:https://nuxt.com.cn/docs/guide/concepts/typescript

安装 TypeScript 及其相关依赖

希望项目在开发过程中启动运行或项目构建时启用类型检查,那么我们需要执行如下命令安装安装 TypeScript 及其相关依赖

pnpm i -D vue-tsc@1 typescript

image.png

启用项目启动运行或构建时自动类型检查

如果,没有启用项目启动运行或构建时自动类型检查,那么要进行类型检查,需要执行如下命令:

npx nuxi typecheck

我们可以在 nuxt.config.ts 配置文件中,通过配置启用项目启动运行或构建时自动类型检查

// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
  devtools: { enabled: true },
  // 启用项目启动运行或构建时自动类型检查
  typescript: {
    typeCheck: true
  }
})

开启严格模式

我们可以在 nuxt.config.ts 配置文件中,通过配置开启 TypeScript 的严格模式

// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
  devtools: {enabled: true},
  // typescript 配置
  typescript: {
    // 启用项目启动运行或构建时自动类型检查
    typeCheck: true,
    // 开启严格模式
    strict: true
  }
})

修改 TypeScript 配置文件

然后,我们根据需要对项目中的 TypeScript 配置文件 tsconfig.json 进行修改,修改后的内容如下:

{
  // https://nuxt.com/docs/guide/concepts/typescript
  // 继承配置
  "extends": "./.nuxt/tsconfig.json",
  // 重写配置,根据需要进行自定义配置
  // TS 编译器选项
  "compilerOptions": {
    // 默认所有可见的 @types 包会在编译过程中被包含进来。
    // 包含什么目录下的类型声明文件
    // "typeRoots": [],
    // 包含 node_modules/@types 或者 typeRoots 配置项
    // 指定的目录里面的哪些库的类型声明文件包
    // "types": [],
    // TS 代码编译成的 JS 代码的目标版本
    "target": "ES2015",
    // TS 代码编译成的 JS 代码的使用的模块化标准
    "module": "ESNext",
    // 允许在项目中使用 js 文件
    "allowJs": true,
    // 是否生成 TS 代码转换成 JS 代码时的源码映射文件
    "sourceMap": true,
    // 是否将 class 声明中的字段语义从 [[Set]] 变更到 [[Define]]
    "useDefineForClassFields": true,
    // 编译过程中需要引入的库
    // 可选值参考:https://www.tslang.cn/docs/handbook/compiler-options.html
    "lib": ["ES2015", "ESNext", "DOM", "DOM.Iterable"],
    // 是否忽略对所有的声明文件( *.d.ts)的类型检查
    "skipLibCheck": true,
    /* Bundler mode 打包模式配置 */
    // 模块解析策略
    "moduleResolution": "Node",
    // 是否允许导入 TypeScript 文件时省略文件的后缀
    "allowImportingTsExtensions": true,
    // 是否允许 JSON 文件作为模块导入
    "resolveJsonModule": true,
    // 是否将每个文件作为单独的模块
    "isolatedModules": true,
    // 是否不生成 TS 代码编译成 JS 代码的输出文件
    "noEmit": true,
    // 编译后生成的代码中会保留 JSX 代码,后续代码的使用需要代码转换工具进行转换操作,
    // 如 Babel,输出文件会带有 .jsx 扩展名
    "jsx": "preserve",
    // 指定 jsx 导入源
    "jsxImportSource": "vue",
    /* Linting */
    // 是否开启所有严格模式选项
    "strict": true,
    // 当 this 表达式的值为 any 类型的时候,生成一个错误。
    "noImplicitThis": true,
    // 是否强制代码中使用的模块文件名必须和文件系统中的文件名保持大小写一致
    "forceConsistentCasingInFileNames": true,
    // 是否允许从没有设置默认导出的模块中默认导入
    "allowSyntheticDefaultImports": false,
    // 对于没有使用的局部变量是否报错
    "noUnusedLocals": true,
    // 对于没有使用的参数是否报错
    "noUnusedParameters": true,
    // 对于 switch 语句中的 case 穿透是否报错
    "noFallthroughCasesInSwitch": true,
    // 对于在表达式和声明上有隐含的 any 类型时是否报错
    "noImplicitAny": true
    // 由于继承的配置中已经进行了目录别名的配置所以这里不重复进行配置
    //    // 解析非相对模块名的基准目录,从当前 tsconfig.json 文件所在的目录开始查找
    //    // 由于 tsconfig.json 文件在项目根目录中,所以从项目根目录开始查找
    //    "baseUrl": ".",
    //    // 配置模块名基于 baseUrl 配置的基准目录的路径映射
    //    "paths": {
    //      // 配置项目根目录下 src 目录的别名为 @
    //      "@/*": [
    //        "src/*"
    //      ]
    //    }
  }
  // 在继承的配置中,已经对需要 TS 编译器处理的目录和文件以及排除的目录和文件进行了配置,以继承的为主,不重复配置
  //  // 配置需要被编译的文件或文件夹
  //  "include": [
  //    "src/**/*.ts",
  //    "src/**/*.tsx",
  //    "src/**/*.vue"
  //  ],
  //  // 配置哪些文件不需要 TypeScript 编译器进行处理
  //  "exclude": [
  //    "node_modules"
  //  ]
}

统一项目中使用的安装依赖的包管理工具为 pnpm

在项目的根目录中创建 scripts/preinstall.js 文件,在该文件中添加下面的内容

// 如果安装依赖使用的包管理工具不是 pnpm,则在终端控制台中打印警告,然后退出本次执行的命令
if (!/pnpm/.test(process.env.npm_execpath || '')) {
  console.warn(
    `\u001b[33m 本项目中必须使用 pnpm 作为包管理工具 ` +
    `请使用 'npm i -g pnpm' 或 'npm i pnpm' 安装 pnpm \u001b[39m\n`,
  )
  process.exit(1)
}

然后,在 package.json 文件中添加 preinstall 脚本:

当我们使用包管理工具安装依赖时,会触发 preinstall 脚本的执行(npm 提供的生命周期钩子),然后就会执行我们指定的 scripts/preinstall.js 文件,检查当前安装依赖使用的包管理工具是不是 pnpm。

  "scripts": {
    "preinstall": "node ./scripts/preinstall.js",
    "build": "nuxt build",
    "dev": "nuxt dev",
  },

image.png

配置 ESLint

安装 eslint 依赖

首先,我们需要安装 ESLint 依赖:

pnpm i eslint -D

image.png

生成 ESLint 配置文件

然后,执行如下命令生成 ESLint 配置文件

npx eslint --init

输入 y 同意安装 ESLint 生成配置文件所需的依赖

You can also run this command directly using 'npm init @eslint/config'.
Need to install the following packages:
@eslint/create-config@0.4.6
Ok to proceed? (y) y

生成 ESLint 配置文件时,我的选择:
image.png
选择你要如何使用 ESLint:

  • 检查语法
  • 检查语法,发现问题
  • 检查语法,发现问题,并强制代码风格
? How would you like to use ESLint? ...
  To check syntax only
  To check syntax and find problems
> To check syntax, find problems, and enforce code style

选择你的项目要使用的模块化规范:

  • ES6 模块化规范
  • CommonJS 模块化规范
  • 这些都没有
? What type of modules does your project use? ...
> JavaScript modules (import/export)
  CommonJS (require/exports)
  None of these

选择你的项目中使用的框架:

  • React
  • Vue
  • 这些都没有
? Which framework does your project use? ...
  React
> Vue.js
  None of these

你的项目中是否使用了 TS?

? Does your project use TypeScript? » No / Yes

你的代码会在哪里运行(空格选中或取消选中):

  • 浏览器
  • Node
? Where does your code run? ...  (Press <space> to select, <a> to toggle all, <i> to invert selection)
√ Browser
√ Node

要使用什么样的代码风格:

  • 使用流行的风格
  • 通过回答问题确定风格
? How would you like to define a style for your project? ...
> Use a popular style guide
  Answer questions about your style

选中想要使用的代码风格:

  • 标准
  • XO
? Which style guide do you want to follow? ...
> Standard: https://github.com/standard/eslint-config-standard-with-typescript
  XO: https://github.com/xojs/eslint-config-xo-typescript

ESLint 配置文件要使用什么文件格式:

  • JavaScript
  • YAML
  • JSON
? What format do you want your config file to be in? ...
> JavaScript
  YAML
  JSON

是否现在安装所需的依赖?

? Would you like to install them now? » No / Yes   

选择你使用的包管理工具:

  • npm
  • yarn
  • pnpm
? Which package manager do you want to use? ...
  npm
  yarn
> pnpm

已安装的插件的相关说明:

  • eslint-plugin-vue:可以帮助我们检查 Vue 相关代码语法的正确性和规范性;
  • eslint-config-standard-with-typescript:标准推荐的适合 TS 的 ESLint 配置;
  • @typescript-eslint/eslint-plugin:用于从 typescript-eslint 加载自定义规则和规则配置列表,这些规则依赖于 @typescript-eslint/parser 将 TypeScript 代码解析为与 ESLint 兼容并提供后备 TypeScript 程序。
  • eslint-plugin-import:针对 impot 语法的插件,可以帮助我们检查 import 和 export 语句的正确性和规范性;
  • eslint-plugin-n:由 eslint-plugin-node v11 派生而来,eslint-plugin-node 似乎长时间没有维护了。eslint-plugin-node 是为 Node.js 准备的 ESLint 规则;
  • eslint-plugin-promise:可以帮助我们检查 promise 相关代码语法的正确性和规范性。

安装其他所需的和 ESlint 相关的依赖

如何,执行如下命令,安装其他所需的和 ESlint 相关的依赖:

pnpm i eslint-import-resolver-alias @typescript-eslint/parser@6 eslint-plugin-prettier eslint-config-prettier -D

image.png

  • eslint-import-resolver-alias:
    • 在使用 ESLint 进行代码检查时,经常会遇到 import 模块时无法识别别名(alias)的问题,这是因为 ESLint 默认不支持在 import 语句中使用别名(alias)。
    • 为了解决这个问题,我们需要安装此 ESLint 插件,然后在 ESLint 配置文件中配置 import/resolver 的 alias 选项,这个选项用于指定如何解析 import 语句中的别名(alias)。
    • 此插件依赖 eslint-plugin-import。
  • @typescript-eslint/parser:
    • 因为 TypeScript 生成的 AST 格式与 ESLint 工作所需的格式不同,所以该插件是用于将 TypeScript 代码解析为兼容 ESLint 的 ESLint 解析器以及提供支持的 TypeScript 程序。
    • 官方文档:https://typescript-eslint.io/packages/parser/
  • eslint-plugin-prettier:这个插件的主要作用就是将 prettier 作为 ESLint 的规则来使用,相当于代码不符合 Prettier 的标准时,会报一个 ESLint 错误,同时也可以通过 eslint --fix 来进行格式化。
  • eslint-config-prettier:让所有与 prettier 规则存在冲突的 ESLint rules 失效,避免 ESLint 和 prettier 冲突;

生成的 ESLint 配置文件的相关解释说明

生成的 ESLint 配置文件的相关解释说明:

module.exports = {
    // 项目代码运行的环境
    "env": {
        // 浏览器环境
        "browser": true,
        // es 模块化规范 import/export
        "es2021": true,
        // node 环境
        "node": true
    },
    // 本项目继承的 eslint 规则
    "extends": [
        // 标准的 ts 语法规则
        "standard-with-typescript",
        // vue3 语法规则
        "plugin:vue/vue3-essential"
    ],
    // 对继承的规则进行重写
    "overrides": [
        {
            // 运行环境
            "env": {
                // 允许项目在 node 环境下运行
                "node": true
            },
            // eslint 配置文件的文件名
            "files": [
                ".eslintrc.{js,cjs}"
            ],
            // 解析器配置
            "parserOptions": {
                // 源码类型为脚本 script (默认)
                "sourceType": "script"
            }
        }
    ],
    // 解析器选项
    "parserOptions": {
        // ECMA 版本为最新版本
        "ecmaVersion": "latest",
        // 源码类型,使用 es 模块化
        "sourceType": "module"
    },
    // 插件
    "plugins": [
        "vue"
    ],
    // 自定义 eslint 规则
    "rules": {
    }
}

修改 ESLint 配置文件

由于后面使用不到生成 ESLint 配置文件时安装的 eslint-config-standard-with-typescript 插件,所以这里将其卸载:

pnpm uninstall eslint-config-standard-with-typescript

image.png
对生成的 ESLint 配置文件进行修改,修改后的内容如下:

由于后续会为项目中的 src 目录配置别名 @,为了使在使用 ESLint 进行代码检查时,遇到使用别名 import 模块时,不报错,使 ESLint 能够支持别名配置,所以在 ESLint 配置文件中 import/resolver 的 alias 选项,配置如何解析 import 语句中的别名,依赖 eslint-import-resolver-alias 和 eslint-plugin-import 插件。

module.exports = {
    // 项目代码运行的环境
    env: {
        // 浏览器环境
        browser: true,
        // es 模块化规范 import/export
        es2021: true,
        // node 环境
        node: true,
        // jest 测试环境
        jest: true,
    },
    // 指定解析语法的解析器
    // parser 的作用是将我们写的代码转换为 ESTree(AST)
    // ESLint 会对 ESTree 进行校验
    parser: 'vue-eslint-parser',
    // 优先级低于 parse 的语法解析器配置
    parserOptions: {
        // es 模块化版本
        ecmaVersion: 'latest',
        // 源码类型为模块化语法,使用 esm 模块化规范
        sourceType: 'module',
        // ts eslint 的解析器
        parser: '@typescript-eslint/parser',
        // jsx tsx 语法规则
        jsxPragma: 'React',
        // ecma 特性,允许使用 jsx、tsx
        ecmaFeatures: {
            tsx: true,
            jsx: true,
        },
    },
    // 本项目继承的 eslint 规则
    extends: [
        // eslint 推荐的规则
        'eslint:recommended',
        // vue3 语法规则
        'plugin:vue/vue3-essential',
        // typescript-eslint 推荐的规则
        'plugin:@typescript-eslint/recommended',
        // prettier 推荐的规则
        // 继承使用 eslint 规则插件时,插件名前缀 eslint-config-, 可省略
        'plugin:prettier/recommended',
    ],
    // 全局自定义的宏,这样在源文件中使用就不会报错或者警告
    // 在 Vue3 的 setup 中,defineProps defineEmits 等我们是可以直接使用的,
    // 无需 import 引入,进行全局自定义宏,这样在源文件中使用就不会报错或者警告
    globals: {
        defineProps: 'readonly',
        defineEmits: 'readonly',
        defineExpose: 'readonly',
        withDefault: 'readonly',
    },
    // 插件
    // 配置使用插件时,插件名称的前缀 eslint-plugin-, 可省略
    // vue 官方提供的 ESLint 插件 eslint-plugin-vue 中提供了 parser 和 rules,
    // parser 为 vue-eslint-parser,配置使用写在上面的 parser 字段,
    // rules 选择合适的规则写在 extends 字段里
    plugins: ['vue', '@typescript-eslint'],
    // 设置
    settings: {
        // 对于 import 导入模块的解析配置
        "import/resolver": {
            // 配置 import 导入模块时使用的别名映射
            alias: {
                map: [
                    ['@', '.'],
                    ['@@', '.'],
                    ['~', '.'],
                    ['~~', '.'],
                    ['assets', './assets'],
                    ['public', './public'],
                    ['#components', './components'],
                    ['nuxt', './node_modules/.pnpm/nuxt@3.11.2_@unocss+reset@0.58.9_floating-vue@5.2.2_typescript@5.4.4_unocss@0.58.9_vite@5.2.8_vue-tsc@2.0.10/node_modules/nuxt'],
                ],
                // 告诉 resolver-alias 有哪些后缀的文件要解析
                // 解决:Unable to resolve path to module
                extensions: ['.ts', '.js', 'tsx', 'jsx', 'json', 'vue']
            },
        },
    },
    // 自定义 eslint 规则
    /*
     * "off" 或 0    ==>  关闭规则
     * "warn" 或 1   ==>  打开的规则作为警告(不影响代码执行)
     * "error" 或 2  ==>  规则作为一个错误(代码不能执行,界面报错)
     */
    rules: {
        // eslint(https://eslint.bootcss.com/docs/rules/)
        // 要求使用 let 或 const 而不是 var
        'no-var': 'error',
        // 不允许多个空行,最多一个
        'no-multiple-empty-lines': ['warn', {max: 1}],
        // 生产环境下不允许 console debugger
        'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
        'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
        // 禁止空余的多行
        'no-unexpected-multiline': 'error',
        // 禁止不必要的转义字符
        'no-useless-escape': 'off',
        // 数组和对象键值对最后一个逗号,
        // never参数:不能带末尾的逗号,
        // always参数:必须带末尾的逗号,
        // always-multiline:多行模式必须带逗号,单行模式不能带逗号
        'comma-dangle': ['warn', "always-multiline"],
        // 要求对象字面量属性名称用引号括起来
        'quote-props': 'off',
        // 强制使用一致的反勾号、双引号或单引号
        // 允许使用模板字符串
        'quotes': ["error", "single", {"avoidEscape": true, "allowTemplateLiterals": true}],

        // typeScript (https://typescript-eslint.io/rules)
        // 禁止定义未使用的变量
        '@typescript-eslint/no-unused-vars': 'error',
        // 禁止使用 @ts-ignore
        '@typescript-eslint/prefer-ts-expect-error': 'error',
        // 禁止使用 any 类型
        '@typescript-eslint/no-explicit-any': 'error',
        // 禁止使用 postfix 运算符的非 null 断言。
        // 如 example.property!.includes('baz');
        '@typescript-eslint/no-non-null-assertion': 'off',
        // 禁止使用自定义 TypeScript 模块和命名空间。
        '@typescript-eslint/no-namespace': 'off',
        // 语句结尾带分号
        '@typescript-eslint/semi': 'off',
        // 解决 vite.config.ts 的引入报错
        'import/no-extraneous-dependencies': 'off',
        // import 时后缀名,可以省略
        'import/extensions': 'off',

        // eslint-plugin-vue (https://eslint.vuejs.org/rules/)
        // 要求组件名称始终为 “-” 链接的单词
        'vue/multi-word-component-names': 'off',
        // 防止 <script setup> 使用的变量 <template> 被标记为未使用
        'vue/script-setup-uses-vars': 'error',
        // 不允许组件 prop 的改变
        'vue/no-mutating-props': 'error',
        // 对模板中的自定义组件强制执行属性命名样式
        'vue/attribute-hyphenation': 'off',
        // 解决按需导入 ElMessage 未定义的问题
        'no-undef': 'off',
    },
}

配置 ESLint 忽略文件

在项目根目录中创建 .eslintignore ESLint 忽略文件,并在该文件中配置 ESLint 需要忽略的不进行检查的目录和文件:

node_modules
.nuxt
public
dist
.output
.data
.nitro
.cache

配置运行或构建项目时自动执行 ESLint 代码检查和修复

如果我们希望在运行或构建项目时,能够自动执行 ESLint 的代码检查和修复,那么我们需要安装并配置 vite-plugin-eslint 插件。

vite-plugin-eslint 官方文档:

安装 vite-plugin-eslint 插件:

pnpm i vite-plugin-eslint -D

image.png
然后,需要在 nuxt.config.ts 文件中,引入并配置使用 vite-plugin-eslint 插件:

// https://nuxt.com/docs/api/configuration/nuxt-config
// 运行或构建项目时,能够自动执行 ESLint 代码检查和修复的插件
import eslint from 'vite-plugin-eslint'

export default defineNuxtConfig({
  devtools: { enabled: true },
  // typescript 配置
  typescript: {
    // 启用项目启动运行或构建时自动类型检查
    typeCheck: true,
    // 开启严格模式
    strict: true,
  },
  // vite 构建工具配置
  vite: {
    // vite 插件配置
    plugins: [
      // 运行或构建项目时,能够自动执行 ESLint 代码检查和修复的插件
      eslint({
        // 缓存现在可以正确识别文件更改,以减少执行时间
        cache: true,
        // 开启自动修复
        fix: true,
        // 打印警告信息
        emitWarning: true,
        // 发生警告不停止构建继续执行
        failOnWarning: false,
        // 打印错误信息
        emitError: true,
        // 发生错误停止构建
        failOnError: true,
        // 指定排除检查的文件和目录
        exclude: [
          '**/node_modules/**',
          '**/dist/**',
          '**/public/**',
          '**/.nuxt/**',
          '**/.output/**',
          '**/.nitro/**',
          '**/.data/**',
        ],
        // 指定要执行检查的文件和目录
        include: [
          './**/*.ts',
          './**/*.tsx',
          './**/*.js',
          './**/*.jsx',
          './**/*.vue',
          './*.ts',
          './*.tsx',
          './*.js',
          './*.jsx',
          './*.vue',
        ],
      }),
    ],
  },
})

此时,在 app.vue 中编写了 ESLint 无法修复的错误,const a = 1,声明变量但不使用,项目运行结果如下:
image.png

如果在 nuxt.config.ts 中引入 vite-plugin-eslint 插件,出现如下报错:
Could not find a declaration file for module vite-plugin-eslint. xxxxx/node_modules/vite-plugin-eslint/dist/index.mjs implicitly has an any type.
解决方法可以参考:https://www.yuque.com/u27599042/vue/cgnesb8kh65dpu4s

添加运行脚本

然后,我们在 package.json 文件中添加如下 ESLint 相关的脚本,通过执行如下的脚本能够让 ESLint 对我们代码进行检查,按照我们配置的风格修复代码:

由于我们项目的代码都在项目根目录下,所以让 ESLint 检查和修复项目根目录下的代码

"scripts": {
    "lint": "eslint ./",
    "fix": "eslint ./ --fix",
}
  • lint:校验项目根目录下的语法
  • fix:校验项目根目录下的语法,并对语法错误的进行纠正

在 webstorm 中配置使用项目的 ESLint 配置

最后,在 webstorm 中配置使用我们项目的 ESLint 配置,让其在保存代码时,自动为我们执行 ESLint 的代码修复。
image.png

配置 Prettier

如果我们在项目中配置了 eslint-plugin-prettier 插件,那么 ESLint 在对代码进行修复时,采用的是 Prettier 来对代码进行修复和格式化

安装 Prettier 及其相关依赖

我们这里只需要安装 Prettier 依赖即可,因为让 ESLint 采用 Prettier 来修复格式化代码的 eslint-plugin-prettier 插件和避免 ESLint 和 prettier 冲突的 eslint-config-prettier 插件,在 https://www.yuque.com/u27599042/eikcfe/nzlfuq9636phrgcg#vzfDk 中已经完成了安装,所以这里不再次进行安装,

pnpm i prettier -D

image.png

创建 Prettier 配置文件并进行相应配置

在项目根目录中创建 Prettier 配置文件 .prettierrc.json,并在该文件中进行如下配置:

{
  "printWidth": 100,
  "useTabs": false,
  "tabWidth": 2,
  "singleQuote": true,
  "semi": false,
  "bracketSpacing": true,
  "endOfLine": "auto",
  "trailingComma": "all",
  "arrowParens": "avoid",
  "htmlWhitespaceSensitivity": "css",
  "proseWrap": "never"
}
  • "printWidth": 100:一行最多多少字符
  • "useTabs": false:是否使用制表符,不使用制表符,使用空格
  • "tabWidth": 2:缩进的宽度,2 个空格
  • "singleQuote": true:是否使用单引号
  • "semi": false:语句结尾是否使用分号
  • "bracketSpacing": true:大括号 {} 中开始和结束是否要空格,true — { foo: 1 },false — {foo: 1}
  • "endOfLine": "auto":每行的结束符(回车符、换行符),取值请参考 https://www.prettier.cn/docs/options.html#end-of-line
  • "trailingComma": "all":数组或对象或参数的最后一项是否尾随逗号,none — 没有尾随逗号,all — 尽可能使用尾随逗号,es5 — 在 ES5 中有效的尾随逗号(对象、数组等),TypeScript 和 Flow 类型参数中的尾随逗号。
  • "arrowParens": "avoid":只有一个参数的箭头函数是否带括号,always — 始终带括号,avoid — 不带括号
  • "htmlWhitespaceSensitivity": "css":根据显示样式决定 html 要不要折行
  • "proseWrap": "never":什么对代码进行折行,always — 如果超过 printWidth 指定的一行最多字符宽度,则进行折行;never — 将每块代码块展开成一行;preserve — 什么都不做,保持原样。

创建并配置 Prettier 忽略文件

在项目根目录中创建 Prettier 忽略文件 .prettierignore,并在该文件中进行如下配置:

/.nuxt/**
/node_modules/**
/dist/**
/.output/**
/public/**
/html/**
/.data/**
/.nitro/**
/.cache/**
/.local/**
**/*.svg
**/*.sh

添加运行脚本

然后,我们在 package.json 文件中添加如下 Prettier 相关的脚本,通过执行如下的脚本能够让 Prettier 根据配置对我们代码进行格式化。

由于我们项目的代码都在项目根目录下,所以让 Prettier 格式化项目根目录下指定类型文件的代码

"scripts": {
    "format": "prettier --write \"./**/*.{html,vue,ts,js,json,md}\" --config ./.prettierrc.json",
}

在 webstorm 中配置使用项目的 Prettier 配置

最后,在 webstorm 中配置使用我们项目的 Prettier 配置,让其在保存代码时,自动为我们执行 Prettier,进行代码的格式化。
image.png

集成 sass

安装 sass 依赖

我们要在项目中使用 sass,不仅需要安装 sass 依赖,还需要安装 sass 预处理器 sass-loader

pnpm i sass sass-loader -D

image.png
默认情况下,在项目中安装完成 sass 和 sass-loader 后,vite 在编译项目时,对于 sass 代码会自动寻找并使用合适的预处理器预处理 sass 代码。

配置全局 sass 变量文件

在项目中配置全局 sass 变量文件,其实就是使用 sass 的预处理器通过其附加数据的功能将我们用于声明全局 sass 变量的文件导入到每个 Vue 文件中的 style 样式模块中。
先在项目中创建用于声明全局 sass 变量的文件 assets/styles/var.scss,然后在 nuxt.config.ts 文件的 vite 配置项中与 plugins 同级的配置项 css 中添加如下配置:

// https://nuxt.com/docs/api/configuration/nuxt-config
// 运行或构建项目时,能够自动执行 ESLint 代码检查和修复的插件
import eslint from 'vite-plugin-eslint'

export default defineNuxtConfig({
  devtools: { enabled: true },
  // typescript 配置
  typescript: {
    // ...
  },
  // vite 构建工具配置
  vite: {
    // vite 插件配置
    plugins: [
      // ...
    ],
    // 样式处理配置
    css: {
      // css 预处理器配置选项
      preprocessorOptions: {
        // sass 预处理器
        scss: {
          javascriptEnabled: true,
          // additionalData: `@import "用于声明全局 sass 变量的文件的路径";`
          // 将用于声明全局 sass 变量的文件导入到每个 Vue 文件中的 style 样式模块中
          additionalData: `@import "./assets/styles/var.scss";`,
        },
      },
    },
  },
})

配置 Stylelint

Stylelint 是一个强大、先进的 CSS 代码检查器(linter),可以帮助我们规避 CSS 代码中的错误并保持一致的编码风格。

Stylelint 中文文档:https://www.stylelint.cn/

如果在项目以及 IDE 中配置 Stylelint 完成后,在写样式的位置开头出现如下报错,这是由于在新版本的 Stylelint 中,这些规则取消了,而在一些 Stylelint 规则配置插件中仍然存在这些规则,所以报错了:
image.png
image.png
下面安装依赖的命令中,在经过多次尝试后,我已经为所有依赖指定了不会报错的版本,可能不是很好的依赖配置选择,目前只是做到了不报错,我的 Stylelint 配置能够正常使用

安装依赖

pnpm i stylelint@15 postcss@8 postcss-scss@4 postcss-html@1 stylelint-config-prettier@8 stylelint-config-recess-order@4 stylelint-config-recommended-scss@9 stylelint-config-standard@32 stylelint-config-standard-vue@1 stylelint-scss@4 stylelint-order@6 stylelint-config-standard-scss@7 -D

image.png
安装的依赖的相关说明:

  • stylelint:Stylelint 是一个强大、先进的 CSS 代码检查器(linter),可以帮助我们规避 CSS 代码中的错误并保持一致的编码风格。
  • postcss:PostCSS 是一种 JavaScript 工具,可将我们的 CSS 代码转换为抽象语法树 (AST),然后提供相关的 API(应用程序编程接口)让 JavaScript 插件能够对 PostCSS 将 CSS 代码转换出来的抽象语法树 (AST) 进行分析和修改。
  • postcss-scss:PostCSS 的 scss 语法解析器,让 PostCSS 能够转换 sass 源码和 css。
  • postcss-html:用于解析 HTML 的 PostCSS 语法解析器
  • stylelint-config-prettier:该插件可以关闭 Stylelint 中所有不必要的或可能与 Prettier 冲突的规则,这使得我们可以在使用 Prettier 时,使用 Stylelint 和 Prettier 的可共享配置。
  • stylelint-config-recess-order:Stylelint 配置,以 recess 的方式对 CSS 属性进行排序。
  • stylelint-config-recommended-scss:Stylelint 中推荐的适合 scss 的配置。
  • stylelint-config-standard:Stylelint 中标准的配置。
  • stylelint-config-standard-vue:Stylelint 中标准的适合 vue 的配置。
  • stylelint-scss:Stylelint 中对于 scss 的代码检查规则集合。
  • stylelint-order:Stylelint 中与排序相关的代码检查规则集合。
  • stylelint-config-standard-scss:Stylelint 中标准的适合 scss 的配置。

创建 Stylelint 配置文件并进行相应的配置

在项目根目录中创建 Stylelint 配置文件 .stylelintrc.cjs,并在该文件中进行如下配置:

Stylelint 规则官方文档:https://www.stylelint.cn/user-guide/rules

// @see https://stylelint.bootcss.com/

module.exports = {
    // 继承规则配置
    extends: [
        // 继承 Stylelint 中标准的配置
        'stylelint-config-standard',
        // 继承 Stylelint 中适合于 vue 中 template 样式格式化的配置
        'stylelint-config-html/vue',
        // 继承 Stylelint 中标准的适合 scss 的配置
        'stylelint-config-standard-scss',
        // 继承 Stylelint 中推荐的适合于 vue 中 scss 样式格式化的配置
        'stylelint-config-recommended-vue/scss',
        // 继承 Stylelint 中以 recess 的方式对 CSS 属性进行排序的配置
        'stylelint-config-recess-order',
        // 继承规则配置,关闭 Stylelint 中所有不必要的或可能与 Prettier 冲突的规则
        'stylelint-config-prettier',
    ],
    // 对继承的规则配置进行重写覆盖
    overrides: [
        // 使用 PostCSS 的 scss 语法解析器解析匹配文件中的样式代码
        {
            files: ['**/*.(scss|css|vue|html)'],
            customSyntax: 'postcss-scss',
        },
        // 使用 PostCSS 的 html 语法解析器解析匹配文件中的代码
        {
            files: ['**/*.(html|vue)'],
            customSyntax: 'postcss-html',
        },
    ],
    // 配置不需要 Stylelint 检查的文件类型
    ignoreFiles: [
        '**/*.js',
        '**/*.jsx',
        '**/*.tsx',
        '**/*.ts',
        '**/*.json',
        '**/*.md',
        '**/*.yaml',
    ],
    /**
     * 自定义 Stylelint 规则
     * null  => 关闭该规则
     * always => 必须
     */
    rules: {
        // 为样式属性关键字的属性值指定小写或大写,"lower"(属性值必须小写)|"upper"(属性值必须大写)
        'value-keyword-case': null,
        // 关闭禁止在具有较高优先级的选择器后出现被其覆盖的较低优先级的选择器
        'no-descending-specificity': null,
        // 要求或禁止 URL 的引号 "always(必须加上引号)"|"never(没有引号)"
        'function-url-quotes': 'always',
        // 关闭禁止存在空的源码,即样式代码块中可以为空
        'no-empty-source': null,
        // 关闭强制选择器类名的格式
        'selector-class-pattern': null,
        // 关闭禁止未知的样式属性,即允许使用未知的样式属性
        'property-no-unknown': null,
        // 大括号之前必须有一个空格或不能有空白符,always —— 大括号 {} 之前必须有一个空格
        'block-opening-brace-space-before': 'always',
        // 关闭禁止使用带有浏览器前缀的属性值,如 --webkit-box,即允许使用
        'value-no-vendor-prefix': null,
        // 关闭禁止使用带有浏览器前缀的属性,如 -webkit-mask,即允许使用
        'property-no-vendor-prefix': null,
        // 禁止使用未知的伪类选择器
        'selector-pseudo-class-no-unknown': [
            // 不允许使用未知的伪类选择器
            true,
            {
                // 忽略属性,对于配置在 ignorePseudoClasses 中的伪类选择器允许使用
                // 修改element默认样式的时候能使用到
                ignorePseudoClasses: ['global', 'v-deep', 'deep'],
            },
        ],
    },
}

配置 Stylelint 忽略文件

在项目根目录中创建 Stylelint 忽略文件 .stylelintignore,并在该文件中进行如下配置:

/node_modules/*
/dist/*
/html/*
/public/*
/scripts/*
/.nuxt/*
/.data/*
/.cache/*
/.output/*
/.nitro/*
/.local/*

添加运行脚本

然后,我们在 package.json 文件中添加如下 Stylelint 相关的脚本,通过执行如下的脚本能够让 Stylelint 根据配置对我们样式相关的代码进行格式化。
此时,样式相关的代码的检查和修复交给 Stylelint,其他的代码的检查交给 ESLint。

由于我们项目的代码都在项目根目录下,所以只需让 Prettier 格式化项目根目录下指定类型文件的代码

"scripts": {
    "lint:eslint": "eslint ./**/*.{js,jsx,ts,tsx,vue} --cache --fix",
    "lint:style": "stylelint ./**/*.{css,scss,vue} --cache --fix",
}

在 webstorm 中配置使用项目的 Stylelint 配置

最后,在 webstorm 中配置使用我们项目的 Stylelint 配置,让其在保存代码时,自动为我们执行 Stylelint,进行代码的检查和修复。

目前 webstorm 中,并不能根据 Stylelint 配置文件中的配置对代码进行修复,只能对代码进行检查,如果要使用 Stylelint 对代码进行修复,我们需要执行上面在 package.json 文件中添加如下 Stylelint 相关的脚本 pnpm lint:style.

image.png

配置 husky

通过配置使用 husky,可以实现在我们使用 Git 提交代码时,触发相应的钩子,帮助我们在代码提交之前执行 Prettier 相应的脚本命令,对我们的代码进行格式化,以确保我们提交的代码都是符合配置的规范的。

安装 husky 依赖

pnpm i husky -D

image.png

初始化本地 Git 仓库

如果已经为当前项目完成初始化本地 Git 仓库,可以跳过此步骤

在初始化 husky 之前,我们需要先为我们的项目初始化本地 Git 仓库,否则在初始化 husky 时会出现如下报错:
image.png
在项目根目录中执行如下命令,为我们的项目初始化本地 Git 仓库

git init

image.png

初始化 husky

我们可以通过执行如下命令,进行 husky 的初始化,会在项目的根目录下生成个一个 .husky 目录,在这个目录下面会有一个 pre-commit 文件,这个文件在我们执行 Git 的 commit 命令的时候会被调用执行

npx husky-init

同意安装 husky 初始化时所需要的相关依赖

Need to install the following packages:
husky-init@8.0.0
Ok to proceed? (y) y

image.png

修改 husky 脚本文件 pre-commit

我们在初始化 husky 之后,会在项目的根目录下生成个一个 .husky 目录,并且会在该目录中自动为我们生成一个 pre-commit 文件,这个文件在我们执行 Git 的 commit 命令的时候会被调用执行。
因此,我们在 .husky/pre-commit 文件中编写执行 Prettier 格式化代码的命令,这样子在外面提交代码时,就会自动触发 pre-commit 钩子执行其中的命令

#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

pnpm format

这里需要说明的是,在 commit 提交代码时,如果触发了钩子进行了代码格式化,代码因格式化发生了修改和变动,那么需要再次 add 和 commit,然后推送远程仓库,这样子才是将格式化后的符合规范的代码提交,否则提交的是格式化之前的版本。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐