MonorepoVue项目初始化

发布于:2025-07-10 ⋅ 阅读:(19) ⋅ 点赞:(0)

一、项目初始化

  1. 初始化package.json
pnpm init
  1. 创建pnpm-workspace.yaml文件
packages:
  - "apps/*"
  - "packages/*"

  1. 创建apps、packages文件夹,apps表示应用文件夹,packages表示公共依赖文件夹
    在这里插入图片描述

二、规范化配置

1、eslint配置

① 安装依赖

 "eslint": "9.7.0",
 "@eslint/js": "9.7.0",
 "globals": "15.8.0",
 "eslint-plugin-vue": "9.27.0",
 "vue-eslint-parser": "9.4.3",
 "@typescript-eslint/parser": "7.16.1",
 "eslint-plugin-simple-import-sort": "12.1.1"

② 创建eslint.config.js

import js from "@eslint/js";
import importSort from "eslint-plugin-simple-import-sort";
import pluginVue from "eslint-plugin-vue";
import globals from "globals";
import vueEslintParser from "vue-eslint-parser";
import tsParser from "@typescript-eslint/parser";

export default [
  {
    languageOptions: {
      globals: {
        ...globals.browser,
        computed: "readonly",
        defineEmits: "readonly",
        defineExpose: "readonly",
        defineProps: "readonly",
        onMounted: "readonly",
        onUnmounted: "readonly",
        reactive: "readonly",
        ref: "readonly",
        shallowReactive: "readonly",
        shallowRef: "readonly",
        toRef: "readonly",
        toRefs: "readonly",
        watch: "readonly",
        watchEffect: "readonly",
      },
    },
    name: "xxx/vue/setup",
    plugins: {
      vue: pluginVue,
    },
  },
  {
    files: ["**/*.{ts,tsx,vue}"],
    ignores: [],
    rules: {
      ...js.configs.recommended.rules,
      ...pluginVue.configs["flat/recommended"].rules,
      "no-unused-vars": "error",
      "no-undef": "warn",
      "no-console": "error",
      "simple-import-sort/imports": "error",
      "simple-import-sort/exports": "error",
      "vue/valid-define-emits": "error",
    },
    languageOptions: {
      parser: vueEslintParser,
      parserOptions: {
        extraFileExtensions: [".vue"],
        // ecmaVersion: 'latest',
        ecmaFeatures: {
          jsx: true,
        },
        parser: tsParser,
        sourceType: "module",
        project: [
          path.join(import.meta.dirname, "tsconfig.eslint.json"),
          path.join(import.meta.dirname, "../../**/*/tsconfig.json"),
        ],
        // project: path.join(import.meta.dirname, "tsconfig.eslint.json"),
        tsconfigRootDir: import.meta.dirname,
      },
    },
    plugins: {
      vue: pluginVue,
      "simple-import-sort": importSort,
    },
  },
];

③ 在最外层目录添加eslint脚本

"lint:vue": "eslint --fix"

④ 测试eslint

pnpm run lint:vue

⑤ eslint无法直接检测vue文件,如何处理

  1. 下面这个配置之后也只能检测vue中的js,ts等
import js from "@eslint/js";
import {} from "globals";
import pluginVue from "eslint-plugin-vue";
import vueEslintParser from "vue-eslint-parser";

export default [
  {
    files: ["**/*.{ts,tsx,vue}"],
    rules: {
      ...js.configs.recommended.rules,
      ...pluginVue.configs["flat/recommended"].rules,
      "no-console": "error",
    },
    languageOptions: {
      parser: vueEslintParser,
    },
  },
];
  1. 如何检测vue中的模板,可以使用vue-official,vscode中的插件来检测
    在这里插入图片描述

2、stylelint

① 安装依赖

"stylelint": "16.7.0",
"stylelint-config-standard-vue": "1.0.0",
"stylelint-config-standard": "36.0.0",
"stylelint-config-standard-scss": "13.1.0"

② 编写stylelint.config.js配置文件

export default {
  extends: ["stylelint-config-standard"],
  overrides: [
    {
      files: ["*.scss", "**/*.scss"],
      extends: ["stylelint-config-standard-scss"],
    },
    {
      files: ["*.vue", "**/*.vue"],
      extends: [
        "stylelint-config-standard-scss",
        "stylelint-config-recommended-vue",
      ],
    },
  ],
};

③ 编写.stylelintignore文件

**/node_modules/
**/dist/
**/public/
**/build/

**/vendor/
**/*.min.css
**/*.map

④ package.json中添加脚本命令

"lint:style": "stylelint \"{packages,apps}/**/*.{css,scss}\" --color --cache --fix"

⑤ 执行命令判断是否成功

pnpm run lint:style

3、安装cspell对单词拼写进行校验

① 安装依赖

"cspell": "8.11.0"

② 编写cspell.json配置文件

{
  "import": ["@cspell/dict-lorem-ipsum/cspell-ext.json"],
  "caseSensitive": false,
  "dictionaries": ["custom-words"],
  "dictionaryDefinitions": [
    {
      "name": "custom-words",
      "path": "./.cspell/custom-words.txt",
      "addWords": true
    }
  ],
  "ignorePaths": [
    "**/node_modules/**",
    "**/dist/**",
    "**/lib/**",
    "**/docs/**",
    "**/stats.html",
    "**/language/**",
    "**/language.ts",
    "**/package.json",
    "**/MOCK_DATA.ts",
    "eslint.config.js"
  ]
}

根据上面的配置文件,需要创建文件夹 .cspell 和 custom-words.txt 文件,存放我们自定义的单词,可以绕过校验

③ 配置拼写检查脚本

"spellcheck": "cspell lint --dot --color --cache --show-suggestions \"(packages|apps)/**/*.@(html|js|cjs|mjs|ts|tsx|css|scss|md|vue)\""

4、配置.editorconfig文件

root = true
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[*.md]
trim_trailing_whitespace = false

5、配置prettier代码美化工具

① 安装依赖

"prettier": "3.6.2",
"eslint-config-prettier": "10.1.5",
"eslint-plugin-prettier": "5.5.1"

② 创建.prettierrc文件

{
  "$schema": "https://json.schemastore.org/prettierrc",
  "semi": false,
  "tabWidth": 2,
  "singleQuote": true,
  "printWidth": 100,
  "trailingComma": "none"
}

③ 创建.prettierignore文件

/dist
*.yaml

④ 添加脚本

"prettier": "prettier --check {packages,apps}/**/*.{ts,tsx,js,vue,css,scss,json,yaml,md}",

6、创建.gitignore文件

node_modules
**/.vitepress
**/dist

# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

.DS_Store
dist
dist-ssr
coverage
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

*.tsbuildinfo

7、提交规范检查

① 安装依赖

"cz-git": "1.9.4",
"@commitlint/cli": "19.3.0",
"@commitlint/config-conventional": "19.2.2",
"commitizen": "4.3.0",
"husky": "9.1.6",
"fast-glob": "3.3.2"

② 配置commitizen,在package.json中添加config

"config": {
    "commitizen": {
      "path": "node_modules/cz-git"
    }
  },

③ 配置commitlint.config.js文件(这个文件cz-git和commitlint共用该配置)

import fg from 'fast-glob'

const getPackages = (packagePath) =>
  fg.sync('*', { cwd: packagePath, onlyDirectories: true, deep: 2 })

const scopes = [
  ...getPackages('packages'),
  ...getPackages('apps'),
  ...getPackages('apps/frontend'),
  ...getPackages('apps/backend'),
  ...getPackages('demos'),
  'docs',
  'project',
  'style',
  'ci',
  'dev',
  'deploy',
  'other'
]

// Emoji
/** @type {import('cz-git').UserConfig} */
export default {
  extends: ['@commitlint/config-conventional'], // extends can be nested
  parserPreset: 'conventional-changelog-conventionalcommits',
  rules: {
    'scope-enum': [2, 'always', scopes]
  },
  prompt: {
    settings: {},
    messages: {
      skip: ':skip',
      max: 'upper %d chars',
      min: '%d chars at least',
      emptyWarning: 'can not be empty',
      upperLimitWarning: 'over limit',
      lowerLimitWarning: 'below limit'
    },
    types: [
      { value: 'feat', name: 'feat:     ✨  A new feature', emoji: '✨ ' },
      { value: 'fix', name: 'fix:      🐛  A bug fix', emoji: '🐛 ' },
      { value: 'docs', name: 'docs:     📝  Documentation only changes', emoji: '📝 ' },
      {
        value: 'style',
        name: 'style:    💄  Changes that do not affect the meaning of the code',
        emoji: '💄 '
      },
      {
        value: 'refactor',
        name: 'refactor: 📦️   A code change that neither fixes a bug nor adds a feature',
        emoji: '📦️ '
      },
      {
        value: 'perf',
        name: 'perf:     🚀  A code change that improves performance',
        emoji: '🚀 '
      },
      {
        value: 'test',
        name: 'test:     🚨  Adding missing tests or correcting existing tests',
        emoji: '🚨 '
      },
      {
        value: 'build',
        name: 'build:    🛠   Changes that affect the build system or external dependencies',
        emoji: '🛠 '
      },
      {
        value: 'ci',
        name: 'ci:       🎡  Changes to our CI configuration files and scripts',
        emoji: '🎡 '
      },
      {
        value: 'chore',
        name: "chore:    🔨  Other changes that don't modify src or test files",
        emoji: '🔨 '
      },
      { value: 'revert', name: 'revert:   ⏪️  Reverts a previous commit', emoji: ':rewind:' }
    ],
    useEmoji: true,
    confirmColorize: true,
    emojiAlign: 'center',
    questions: {
      scope: {
        description: 'What is the scope of this change (e.g. component or file name)'
      },
      subject: {
        description: 'Write a short, imperative tense description of the change'
      },
      body: {
        description: 'Provide a longer description of the change'
      },
      isBreaking: {
        description: 'Are there any breaking changes?'
      },
      breakingBody: {
        description:
          'A BREAKING CHANGE commit requires a body. Please enter a longer description of the commit itself'
      },
      breaking: {
        description: 'Describe the breaking changes'
      },
      isIssueAffected: {
        description: 'Does this change affect any open issues?'
      },
      issuesBody: {
        description:
          'If issues are closed, the commit requires a body. Please enter a longer description of the commit itself'
      },
      issues: {
        description: 'Add issue references (e.g. "fix #123", "re #123".)'
      }
    }
  }
}

// 汉化
// /** @type {import('cz-git').UserConfig} */
// module.exports = {
//     rules: {
//         // @see: https://commitlint.js.org/#/reference-rules
//     },
//     prompt: {
//         alias: { fd: 'docs: fix typos' },
//         messages: {
//             type: '选择你要提交的类型 :',
//             scope: '选择一个提交范围(可选):',
//             customScope: '请输入自定义的提交范围 :',
//             subject: '填写简短精炼的变更描述 :\n',
//             body: '填写更加详细的变更描述(可选)。使用 "|" 换行 :\n',
//             breaking: '列举非兼容性重大的变更(可选)。使用 "|" 换行 :\n',
//             footerPrefixesSelect: '选择关联issue前缀(可选):',
//             customFooterPrefix: '输入自定义issue前缀 :',
//             footer: '列举关联issue (可选) 例如: #31, #I3244 :\n',
//             generatingByAI: '正在通过 AI 生成你的提交简短描述...',
//             generatedSelectByAI: '选择一个 AI 生成的简短描述:',
//             confirmCommit: '是否提交或修改commit ?'
//         },
//         types: [
//             { value: '特性', name: '特性:     新增功能' },
//             { value: '修复', name: '修复:     修复缺陷' },
//             { value: '文档', name: '文档:     文档变更' },
//             { value: '格式', name: '格式:     代码格式(不影响功能,例如空格、分号等格式修正)' },
//             { value: '重构', name: '重构:     代码重构(不包括 bug 修复、功能新增)' },
//             { value: '性能', name: '性能:     性能优化' },
//             { value: '测试', name: '测试:     添加疏漏测试或已有测试改动' },
//             { value: '构建', name: '构建:     构建流程、外部依赖变更(如升级 npm 包、修改 webpack 配置等)' },
//             { value: '集成', name: '集成:     修改 CI 配置、脚本' },
//             { value: '回退', name: '回退:     回滚 commit' },
//             { value: '其他', name: '其他:     对构建过程或辅助工具和库的更改(不影响源文件、测试用例)' }
//         ],
//         useEmoji: false,
//         emojiAlign: 'center',
//         useAI: false,
//         aiNumber: 1,
//         themeColorCode: '',
//         scopes: [],
//         allowCustomScopes: true,
//         allowEmptyScopes: true,
//         customScopesAlign: 'bottom',
//         customScopesAlias: '以上都不是?我要自定义',
//         emptyScopesAlias: '跳过',
//         upperCaseSubject: false,
//         markBreakingChangeMode: false,
//         allowBreakingChanges: ['feat', 'fix'],
//         breaklineNumber: 100,
//         breaklineChar: '|',
//         skipQuestions: [],
//         issuePrefixes: [
//             // 如果使用 gitee 作为开发管理
//             { value: 'link', name: 'link:     链接 ISSUES 进行中' },
//             { value: 'closed', name: 'closed:   标记 ISSUES 已完成' }
//         ],
//         customIssuePrefixAlign: 'top',
//         emptyIssuePrefixAlias: '跳过',
//         customIssuePrefixAlias: '自定义前缀',
//         allowCustomIssuePrefix: true,
//         allowEmptyIssuePrefix: true,
//         confirmColorize: true,
//         maxHeaderLength: Infinity,
//         maxSubjectLength: Infinity,
//         minSubjectLength: 0,
//         scopeOverrides: undefined,
//         defaultBody: '',
//         defaultIssues: '',
//         defaultScope: '',
//         defaultSubject: ''
//     }
// }

④ 初始化husky

npx husky init

在这里插入图片描述
修改pre-commit脚本

#!/usr/bin/env bash

npx lint-staged && pnpm spellcheck && pnpm typecheck

⑤ package.json中添加提交代码脚本

"commit": "git-cz",

8、配置lint-staged

① 安装依赖

"lint-staged": "15.2.10",

② package.json中配置lint-staged

"lint-staged": {
    "*.{md,json}": [
      "prettier --cache --write --no-error-on-unmatched-pattern"
    ],
    "*.{css,less}": [
      "prettier --cache --write"
    ],
    "*.{js,jsx}": [
      "eslint --fix",
      "prettier --cache --write"
    ],
    "*.{ts,tsx}": [
      "eslint --fix",
      "prettier --cache --parser=typescript --write"
    ]
  },

9、配置turbo

① 安装依赖

"turbo": "2.2.3",

② 配置turbo.json

{
  "$schema": "https://turbo.build/schema.json",
  "tasks": {
    "build:watch": {
      "cache": false,
      "persistent": true
    },
    "build": {
      "dependsOn": ["^build"],
      "outputs": []
    },
    "dev": {
      "cache": false,
      "persistent": true
    },
    "typecheck": {
      "cache": false,
      "persistent": true
    }
  },
  "ui": "tui",
  "cacheDir": ".turbo/cache"
}

③ package.json中编写turbo脚本

// 构建并且观察
"build:watch": "turbo build:watch",
// 构建
"build": "turbo build",
// 开发
"dev": "turbo dev",
"typecheck": "turbo typecheck",

10、typescript配置

tsconfig.json

{
  "compilerOptions": {
    "alwaysStrict": false,
    "declaration": true,
    "declarationMap": true,
    "downlevelIteration": true,
    "importHelpers": true,
    "inlineSources": true,
    "isolatedModules": true,
    "lib": ["ESNext"],
    "moduleResolution": "node",
    "noErrorTruncation": true,
    "noFallthroughCasesInSwitch": true,
    "noImplicitReturns": true,
    "noUnusedLocals": false,
    "noUnusedParameters": false,
    "preserveWatchOutput": true,
    "sourceMap": true,
    "strict": true,
    "strictBindCallApply": false,
    "target": "es2018",
    "noUncheckedIndexedAccess": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "resolveJsonModule": true,
    "noEmit": true,
    "baseUrl": "."
  },
  "include": ["packages/**/*", "apps/**/*"],
  "exclude": ["node_modules", "**/*.spec.ts"]
}

tsconfig.eslint.json

{
  "root": true,
  "ignorePatterns": ["**/*.js"],
  "overrides": [
    {
      "files": ["*.ts", "*.tsx"],
      "parser": "@typescript-eslint/parser",
      "parserOptions": {
        "project": "./tsconfig.json",
        "createDefaultProgram": true,
        "ecmaVersion": 2020,
        "sourceType": "module"
      },
      "plugins": ["@typescript-eslint/eslint-plugin"],
      "extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended", "prettier"],
      "rules": {
        "@typescript-eslint/no-explicit-any": ["warn"],
        "@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }],
        "@typescript-eslint/no-empty-function": ["off"],
        "prefer-const": ["error"],
        "no-console": ["warn"]
      }
    }
  ]
}


网站公告

今日签到

点亮在社区的每一天
去签到