Vite + Vue3 +TS 项目搭建



安装 nvm

安装 node

使用 Vite创建项目

vite3.x
文档:https://cn.vitejs.dev/guide/#scaffolding-your-first-vite-project

使用 NPM:

$ npm create vite@latest

使用 Yarn:

$ yarn create vite

使用 PNPM:

$ pnpm create vite

然后直接进入项目初始化的选择,自定义一些选项可以选择
Customize with create-vue
image

或者直接附加命令行选项,省去选择操作,直接生成默认最小项目:

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

运行项目

pnpm install
pnpm format // perttier 格式化
pnpm dev

初始化 Git 仓库

项目目录下运行

git init

修改 vite 配置文件

打包虚拟路径
设置别名
设置代理

集成 EditorConfig 配置

EditorConfig有助于为在不同编辑器和IDE中处理同一项目的多个开发人员维护一致的编码风格。
官网:editorconfig.org

插件安装

  • VS Code 安装 EditorConfig for VS Code 插件
  • JetBrains 系列(WebStorm、IntelliJ IDEA 等)则不用额外安装插件,可直接使用 EditorConfig 配置。

配置文件

在根目录下创建 .editorconfig 文件↓

# Editor configuration, see http://editorconfig.org

# 表示是最顶层的 EditorConfig 配置文件
root = true

[*] # 表示所有文件适用
charset = utf-8 # 设置文件字符集为 utf-8
indent_style = space # 缩进风格(tab | space)
indent_size = 2 # 缩进大小
end_of_line = lf # 控制换行类型(lf | cr | crlf)
trim_trailing_whitespace = true # 去除行首的任意空白字符
insert_final_newline = true # 始终在文件末尾插入一个新行

[*.md] # 表示仅 md 文件适用以下规则
max_line_length = off
trim_trailing_whitespace = false

集成 Prettier 配置

代码格式化程序
官网:prettier.io

  1. 下载 Prettier - Code formatter VS Code 插件

  2. 在根目录下创建 .prettierrc.json 文件↓

{
  "$schema": "https://json.schemastore.org/prettierrc",
  "semi": false,
  "tabWidth": 2,
  "singleQuote": true,
  "printWidth": 100,
  "trailingComma": "none"
}
  1. 使用命令格式化代码
# 格式化所有文件(. 表示所有文件)
npx prettier --write .

集成 ESLint 配置

官网:eslint.org

  1. 安装与配置
    CLI自带,无特殊要求不需要配置。
    手动集成参考:https://juejin.cn/post/6951649464637636622#heading-13

  2. 下载 ESLint VS Code 插件

解决 ESlint 和 Prettier 冲突

有时,ESLint 的规则和 Prettier 的规则可能存在冲突,导致代码格式化不一致。使用 eslint-config-prettier 可以关闭 ESLint 中与 Prettier 冲突的规则。

  1. 安装插件
npm i eslint-plugin-prettier eslint-config-prettier -D
  • eslint-config-prettier :关闭eslint中与prettier相互冲突的规则。
  • eslint-plugin-prettier : 允许eslint用prettier格式化代码的能力。安装依赖并修改.eslintrc文件
  1. .eslintrc.js 添加 prettier 插件
module.exports = {
  ...
  extends: [
    'plugin:vue/essential',
    'airbnb-base',
    'plugin:prettier/recommended' // 添加 prettier 插件
  ],
  ...
}

集成 stylelint

可格式化css代码,检查css语法错误与不合理的写法,指定css书写顺序等
参考:掘金博客

1. 安装

pnpm add stylelint postcss postcss-less postcss-html stylelint-config-prettier stylelint-config-recommended-less stylelint-config-standard stylelint-config-standard-vue stylelint-less stylelint-order -D

依赖说明:

  • stylelint: css样式lint工具
  • postcss: 转换css代码工具
  • postcss-less: 识别less语法
  • postcss-html: 识别html/vue 中的标签中的样式
  • stylelint-config-standard: Stylelint的标准可共享配置规则,详细可查看官方文档
  • stylelint-config-prettier: 关闭所有不必要或可能与Prettier冲突的规则
  • stylelint-config-recommended-less: less的推荐可共享配置规则,详细可查看官方文档
  • stylelint-config-standard-vue: lint.vue文件的样式配置
  • stylelint-less: stylelint-config-recommended-less的依赖,less的stylelint规则集合
  • stylelint-order: 指定样式书写的顺序,在.stylelintrc.js中order/properties-order指定顺序

2. 配置 .stylelintrc.cjs

// @see: https://stylelint.io

module.exports = {
  extends: [
    'stylelint-config-standard',
    'stylelint-config-prettier',
    'stylelint-config-recommended-less',
    'stylelint-config-standard-vue'
  ],
  plugins: ['stylelint-order'],
  // 不同格式的文件指定自定义语法
  overrides: [
    {
      files: ['**/*.(less|css|vue|html)'],
      customSyntax: 'postcss-less'
    },
    {
      files: ['**/*.(html|vue)'],
      customSyntax: 'postcss-html'
    }
  ],
  ignoreFiles: [
    '**/*.js',
    '**/*.jsx',
    '**/*.tsx',
    '**/*.ts',
    '**/*.json',
    '**/*.md',
    '**/*.yaml'
  ],
  rules: {
    'no-descending-specificity': null, // 禁止在具有较高优先级的选择器后出现被其覆盖的较低优先级的选择器
    'selector-pseudo-element-no-unknown': [
      true,
      {
        ignorePseudoElements: ['v-deep']
      }
    ],
    'selector-pseudo-class-no-unknown': [
      true,
      {
        ignorePseudoClasses: ['deep']
      }
    ],
    // 指定样式的排序
    'order/properties-order': [
      'position',
      'top',
      'right',
      'bottom',
      'left',
      'z-index',
      'display',
      'justify-content',
      'align-items',
      'float',
      'clear',
      'overflow',
      'overflow-x',
      'overflow-y',
      'padding',
      'padding-top',
      'padding-right',
      'padding-bottom',
      'padding-left',
      'margin',
      'margin-top',
      'margin-right',
      'margin-bottom',
      'margin-left',
      'width',
      'min-width',
      'max-width',
      'height',
      'min-height',
      'max-height',
      'font-size',
      'font-family',
      'text-align',
      'text-justify',
      'text-indent',
      'text-overflow',
      'text-decoration',
      'white-space',
      'color',
      'background',
      'background-position',
      'background-repeat',
      'background-size',
      'background-color',
      'background-clip',
      'border',
      'border-style',
      'border-width',
      'border-color',
      'border-top-style',
      'border-top-width',
      'border-top-color',
      'border-right-style',
      'border-right-width',
      'border-right-color',
      'border-bottom-style',
      'border-bottom-width',
      'border-bottom-color',
      'border-left-style',
      'border-left-width',
      'border-left-color',
      'border-radius',
      'opacity',
      'filter',
      'list-style',
      'outline',
      'visibility',
      'box-shadow',
      'text-shadow',
      'resize',
      'transition'
    ]
  }
}

3. 安装VS Code Stylelint 插件

image

配置 husky

操作 git 钩子的工具
官网:husky

1. 安装 & 配置

# 用 CMD 命令行执行
pnpm dlx husky-init && pnpm install

2. 自动做的事情

  • 安装 husky 到开发依赖
  • 在项目根目录下创建 .husky 目录
  • 在 .husky 目录创建 pre-commit hook,并初始化 pre-commit 命令为 npm test
  • 修改 package.jsonscripts,增加 "prepare": "husky install"

配置 lint-staged

本地暂存代码检查工具

1. 安装

pnpm i lint-staged -D

2. 配置

2.1 方式一(推荐):根目录新建 lint-staged.config.cjs文件添加配置

module.exports = {
  '*.{js,jsx,ts,tsx}': ['eslint --fix', 'prettier --write'],
  '{!(package)*.json,*.code-snippets,.!(browserslist)*rc}': ['prettier --write--parser json'],
  'package.json': ['prettier --write'],
  '*.vue': ['eslint --fix', 'prettier --write', 'stylelint --fix'],
  '*.{scss,less,styl,html}': ['stylelint --fix', 'prettier --write'],
  '*.md': ['prettier --write']
}

2.2 方式二:在 package.json下添加配置

{
  ....
  "scripts": {....},
  "dependencies": {....},
  "devDependencies": {....},
  "lint-staged": {
    "*.{vue,js,ts,jsx,tsx,md,json}": "eslint --fix"
  }
}

3. 配置 husky 钩子

.husky/pre-commit

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

pnpm exec lint-staged

配置 commitlint

commit message 校验工具
文档:commitlint

1. 安装

pnpm i @commitlint/config-conventional @commitlint/cli -D

2. 配置

2.1 在根目录新建 commitlint.config.cjs文件添加配置
module.exports = {
  extends: ['@commitlint/config-conventional']
}
2.2 使用 husky 的 commit-msg hook 触发验证提交信息的命令

我们使用 husky 命令在 .husky 目录下创建 commit-msg 文件,并在此执行 commit message 的验证命令。

# 用 CMD 命令行执行
# pnpm
pnpm exec husky add .husky/commit-msg "pnpm exec commitlint --edit \"${1}\""

# npm
npx husky add .husky/commit-msg "npx --no-install commitlint --edit $1"

配置 commitizen

辅助生成 commit message ,就像这样,通过选择输入,规范提交信息
中文配置文档:cz-git
commitlint.config.cjs模板1:template1
commitlint.config.cjs模板2:template2

1.1 全局安装 Commitizen

全局安装 commitizen,如此一来可以快速使用 czgit cz 命令进行启动。
不全局安装 git cz 命令启动不了

npm install -g commitizen

1.2 安装 cz-git

pnpm install -D cz-git

1.3 修改 package.json 添加 config 指定使用的适配器

{
  "scripts": {

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

1.4 添加自定义配置(可选,否则使用默认)

有两种配置方式

方式一(推荐):
cz-git 与 commitlint 进行联动给予校验信息,所以可以编写于 commitlint 配置文件之中。

// commitlint.config.cjs
// @see: https://cz-git.qbenben.com/zh/guide
const fs = require('fs')
const path = require('path')

const scopes = fs
  .readdirSync(path.resolve(__dirname, 'src'), { withFileTypes: true })
  .filter((dirent) => dirent.isDirectory())
  .map((dirent) => dirent.name.replace(/s$/, ''))

/** @type {import('cz-git').UserConfig} */
module.exports = {
  ignores: [(commit) => commit.includes('init')],
  extends: ['@commitlint/config-conventional'],
  rules: {
    // @see: https://commitlint.js.org/#/reference-rules
    'body-leading-blank': [2, 'always'],
    'footer-leading-blank': [1, 'always'],
    'header-max-length': [2, 'always', 108],
    'subject-empty': [2, 'never'],
    'type-empty': [2, 'never'],
    'subject-case': [0],
    'type-enum': [
      2,
      'always',
      [
        'feat',
        'fix',
        'docs',
        'style',
        'refactor',
        'perf',
        'test',
        'build',
        'ci',
        'chore',
        'revert',
        'wip',
        'workflow',
        'types',
        'release'
      ]
    ]
  },
  prompt: {
    messages: {
      // type: "Select the type of change that you're committing:",
      // scope: 'Denote the SCOPE of this change (optional):',
      // customScope: 'Denote the SCOPE of this change:',
      // subject: 'Write a SHORT, IMPERATIVE tense description of the change:\n',
      // body: 'Provide a LONGER description of the change (optional). Use "|" to break new line:\n',
      // breaking: 'List any BREAKING CHANGES (optional). Use "|" to break new line:\n',
      // footerPrefixsSelect: 'Select the ISSUES type of changeList by this change (optional):',
      // customFooterPrefixs: 'Input ISSUES prefix:',
      // footer: 'List any ISSUES by this change. E.g.: #31, #34:\n',
      // confirmCommit: 'Are you sure you want to proceed with the commit above?'
      // 中文版
      type: '选择你要提交的类型 :',
      scope: '选择一个提交范围(可选):',
      customScope: '请输入自定义的提交范围 :',
      subject: '填写简短精炼的变更描述 :\n',
      body: '填写更加详细的变更描述(可选)。使用 "|" 换行 :\n',
      breaking: '列举非兼容性重大的变更(可选)。使用 "|" 换行 :\n',
      footerPrefixsSelect: '选择关联issue前缀(可选):',
      customFooterPrefixs: '输入自定义issue前缀 :',
      footer: '列举关联issue (可选) 例如: #31, #I3244 :\n',
      confirmCommit: '是否提交或修改commit ?'
    },
    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: '⏪️'
      // },
      // {
      //   value: 'wip',
      //   name: 'wip:      🕔  work in process',
      //   emoji: '🕔'
      // },
      // {
      //   value: 'workflow',
      //   name: 'workflow: 📋  workflow improvements',
      //   emoji: '📋'
      // },
      // {
      //   value: 'type',
      //   name: 'type:     🔰  type definition file changes',
      //   emoji: '🔰'
      // }
      // 中文版
      { value: 'feat', name: 'feat:   ✨  新增功能', emoji: '✨' },
      { value: 'fix', name: 'fix:   🧩  修复缺陷', emoji: '🧩' },
      { value: 'docs', name: 'docs:   📚  文档变更', emoji: '📚' },
      {
        value: 'style',
        name: 'style:   🎨  代码格式(不影响功能,例如空格、分号等格式修正)',
        emoji: '🎨'
      },
      {
        value: 'refactor',
        name: 'refactor:   ♻️  代码重构(不包括 bug 修复、功能新增)',
        emoji: '♻️'
      },
      { value: 'perf', name: 'perf:    🚀  性能优化', emoji: '🚀' },
      { value: 'test', name: 'test:   ✅  添加疏漏测试或已有测试改动', emoji: '✅' },
      {
        value: 'build',
        name: 'build:   📦️  构建流程、外部依赖变更(如升级 npm 包、修改 webpack 配置等)',
        emoji: '📦️'
      },
      { value: 'ci', name: 'ci:   🎡  修改 CI 配置、脚本', emoji: '🎡' },
      {
        value: 'chore',
        name: 'chore:   🔨  对构建过程或辅助工具和库的更改(不影响源文件、测试用例)',
        emoji: '🔨'
      },
      {
        value: 'revert',
        name: 'revert:   ⏪️  回滚 commit',
        emoji: '⏪️'
      },
      { value: 'wip', name: 'wip:   🕔  正在开发中', emoji: '🕔' },
      { value: 'workflow', name: 'workflow:   📋  工作流程改进', emoji: '📋' },
      { value: 'types', name: 'types:   🔰  类型定义文件修改', emoji: '🔰' }
    ],
    useEmoji: true,
    scopes: [...scopes],
    customScopesAlign: 'bottom',
    emptyScopesAlias: 'empty',
    customScopesAlias: 'custom',
    allowBreakingChanges: ['feat', 'fix']
  }
}

// commitlint.config.cjs
module.exports = {
  parserPreset: 'conventional-changelog-conventionalcommits',
  rules: {
    // @see: https://commitlint.js.org/#/reference-rules
    'body-leading-blank': [1, 'always'],
    'body-max-line-length': [2, 'always', 100],
    'footer-leading-blank': [1, 'always'],
    'footer-max-line-length': [2, 'always', 100],
    'header-max-length': [2, 'always', 100],
    'subject-case': [2, 'never', ['sentence-case', 'start-case', 'pascal-case', 'upper-case']],
    'subject-empty': [2, 'never'],
    'subject-full-stop': [2, 'never', '.'],
    'type-case': [2, 'always', 'lower-case'],
    'type-empty': [2, 'never'],
    'type-enum': [
      2,
      'always',
      ['build', 'chore', 'ci', 'docs', 'feat', 'fix', 'perf', 'refactor', 'revert', 'style', 'test']
    ]
  },
  prompt: {
    questions: {
      type: {
        description: "Select the type of change that you're committing",
        enum: {
          feat: {
            description: 'A new feature',
            title: 'Features',
            emoji: '✨'
          },
          fix: {
            description: 'A bug fix',
            title: 'Bug Fixes',
            emoji: '🐛'
          },
          docs: {
            description: 'Documentation only changes',
            title: 'Documentation',
            emoji: '📚'
          },
          style: {
            description:
              'Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)',
            title: 'Styles',
            emoji: '💎'
          },
          refactor: {
            description: 'A code change that neither fixes a bug nor adds a feature',
            title: 'Code Refactoring',
            emoji: '📦'
          },
          perf: {
            description: 'A code change that improves performance',
            title: 'Performance Improvements',
            emoji: '🚀'
          },
          test: {
            description: 'Adding missing tests or correcting existing tests',
            title: 'Tests',
            emoji: '🚨'
          },
          build: {
            description:
              'Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)',
            title: 'Builds',
            emoji: '🛠'
          },
          ci: {
            description:
              'Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs)',
            title: 'Continuous Integrations',
            emoji: '⚙️'
          },
          chore: {
            description: "Other changes that don't modify src or test files",
            title: 'Chores',
            emoji: '♻️'
          },
          revert: {
            description: 'Reverts a previous commit',
            title: 'Reverts',
            emoji: '🗑'
          }
        }
      },
      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".)'
      }
    }
  }
}

方式二(不推荐):
在 package.json 下 config.commitizen 下添加自定义配置,但过量的配置项会导致 package.json 臃肿,适合简单自定义。例如:

{
  "scripts": {
    "commit": "git-cz"
  },
  "config": {
    "commitizen": {
      "path": "node_modules/cz-git",
      "useEmoji": true
    }
  }
}

集成 normalize.css(根据实际使用的css预编译器灵活配置)

github:normalize.css

  1. 从官网下载文件

  2. main.ts中引入

集成 postcss-px-to-viewport

1. 安装

pnpm install postcss-px-to-viewport --save-dev

2. 配置,在根目录下新增 postcss.config.cjs 文件

// @see: https://www.npmjs.com/package/postcss-px-to-viewport#usage
module.exports = {
  plugins: {
    // autoprefixer: {},
    'postcss-px-to-viewport': {
      viewportWidth: 375, // // 视口的宽度
      unitPrecision: 2, // 允许 vw 单位保留的小数
      viewportUnit: 'vw',
      selectorBlackList: ['.ignore', /^body$/, '.hairlines', /^\.dp/, /^\.scroller/], // 要忽略并保留为 px 的选择器
      minPixelValue: 1, // 替换的最小像素值
      mediaQuery: false // 允许在媒体查询中转换px
    }
  }
}

集成 Axios && 通用请求函数

1. 安装

2. 通用请求函数

其他按需集成

Common:

集成 CSS预处理器(less / scss / stylus)

集成 dayjs

集成 good-storage

集成 lodash

集成 mitt

集成 vueuse

PC:

集成 element-plus

H5:

集成 Vant

集成 vconsole

集成 Better-scroll

posted @ 2023-04-21 18:48  Better-HTQ  阅读(350)  评论(0编辑  收藏  举报