本项目选型默认使用vue3 + typescript + vite
1. 使用vite初始化项目
vite创建地址,创建完成后有一个基本的项目结构了,如下图
2. 配置vite.config.ts,配置详解
import { defineConfig } from 'vite'
import path from 'path';
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue(), vueJsx()],
resolve: {
//设置文件路径解析,需要配合tsconfig.json的paths结合解析
alias: {
'@': path.resolve(__dirname, 'src'),
components: path.resolve(__dirname, 'src/components'),
}
},
//相关打包配置
build: {
sourcemap: true,
// Turning off gzip-compressed size display can slightly reduce packaging time
reportCompressedSize: false,
chunkSizeWarningLimit: 2000,
},
//服务器相关配置,vite3默认端口5173
server: {
host: true,
}
})
发现报错了 Cannot find module path or its corresponding type declarations
那么需要安装@types/node并且在tsconfig.json中的types中添加’node’,如下配置
3. 配置tsconfig.json
{
"compilerOptions": {
"rootDir": ".", // 根目录地址
"target": "ESNext", // 指定 ECMAScript 目标版本
"useDefineForClassFields": true, // 对类字段使用定义
"noImplicitAny": false, // 在表达式和声明上有隐含的 any类型时不报错
"module": "ESNext", // 指定使用模块
"moduleResolution": "Node", // 选择模块解析策略: 'node' (Node.js)
"strict": true, // 启用所有严格类型检查选项
"jsx": "preserve", // 指定 jsx 代码的生成
"sourceMap": true, // 生成相应的 '.map' 文件
"resolveJsonModule": true, // 解析 JSON 模块
"isolatedModules": true, // 将每个文件作为单独的模块
"esModuleInterop": true, // ES 模块互操作
"lib": ["ESNext", "DOM"], // 指定要包含在编译中的库文件
"skipLibCheck": true, // 过默认库检查
"types": ["node", "naive-ui/volar"], // 需要包含的类型声明文件名列表
"baseUrl": ".", // 用于解析非相对模块名称的基目录
"importHelpers": true, // 导入帮助
"strictNullChecks": true, // 启用严格的 null 检查
"allowSyntheticDefaultImports": true, // 允许合成默认导入
"allowJs": false, //允许js文件
"noEmit": true, // 不要发出编译器输出文件
"paths": { //路径映射
"@/*": ["src/*"],
"components/*": ["src/components/*"]
}
},
//指定需要包含的文件
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
"references": [{ "path": "./tsconfig.node.json" }] // 引用其他tsconfig配置,参考
}
4. 配置git提交检查
前端一般使用yorkie和husky来对git提交进行lint检查,差异可看yorkie的文档介绍
npm install yorkie lint-staged --save-dev
//在package.json中配置
"gitHooks": {
"pre-commit": "lint-staged",
"commit-msg": "node scripts/verifyCommit.js"
},
"lint-staged": {
"*.{js,jsx,ts,tsx}": [
"eslint --fix",
"prettier --write"
],
"package.json": [
"prettier --write"
],
"*.vue": [
"eslint --fix",
"prettier --write",
"stylelint --fix"
],
"*.{scss,less,styl,html}": [
"stylelint --fix",
"prettier --write"
],
"*.md": [
"prettier --write"
]
}
scripts里面的erifyCommit.js和.github/commit-convention.md文件参考vue3
5. 配置eslint进行代码规范化
pnpm add -D eslint @antfu/eslint-config eslint-plugin-prettier eslint-config-prettier //直接安装使用即可
module.exports = {
"extends": [
"@antfu",
"prettier" //eslint走prettier,关闭所有不必要或可能与Prettier冲突的规则,eslint-config-prettier
"plugin:prettier/recommended" // 其实是一些已经配置好的规则插件等,使用recommended配置
]
}
6. 配置prettier进行代码格式化
prettier可配置规则
// prettier.config.js
module.exports = {
printWidth: 120, // 设置每行显示最长的长度
tabWidth: 2, // eslint/rules/indent 指定每个缩进级别的空格数
useTabs: false, // 用 tabs 之后很多问题,例如按 tab 后不能一次性定位到正确缩进位置,建议用 space
semi: false, // 与 trailingComma 相对应,应该加上行尾分号
trailingComma: 'all', // eslint/rules/comma-dangle,行尾加上逗号
singleQuote: true, // eslint/rules/quotes 使用单引号
jsxSingleQuote: true, // jsx使用单引号
arrowParens: 'avoid', // 在唯一的箭头函数参数周围包含括号
};
7. 配置style规则,实现快速格式化css
module.exports = {
root: true,
plugins: ['stylelint-order'],
extends: ["stylelint-config-standard", "stylelint-config-prettier", "stylelint-config-recommended-vue"],
customSyntax: 'postcss-html',
rules: {
'selector-pseudo-class-no-unknown': [
true,
{
ignorePseudoClasses: ['deep', 'v-slotted'],
},
],
'selector-pseudo-element-no-unknown': [
true,
{
ignorePseudoElements: ['v-deep', ':deep'],
},
],
'at-rule-no-unknown': [
true,
{
ignoreAtRules: [
'tailwind',
'apply',
'variants',
'responsive',
'screen',
'function',
'if',
'each',
'include',
'mixin',
'extend',
':deep',
],
},
],
'value-keyword-case': null,
'no-empty-source': null,
'no-duplicate-selectors': null,
'named-grid-areas-no-invalid': null,
'unicode-bom': 'never',
'no-descending-specificity': null,
'font-family-no-missing-generic-family-keyword': null,
'declaration-colon-space-after': 'always-single-line',
'declaration-colon-space-before': 'never',
// 'declaration-block-trailing-semicolon': 'always',
'custom-property-empty-line-before': 'never',
'rule-empty-line-before': null,
'unit-no-unknown': [true, { ignoreUnits: ['rpx'] }],
'order/order': [
[
'dollar-variables',
'custom-properties',
'at-rules',
'declarations',
{
type: 'at-rule',
name: 'supports',
},
{
type: 'at-rule',
name: 'media',
},
'rules',
],
{ severity: 'warning' },
],
'selector-class-pattern': null,
'function-name-case': null,
'declaration-empty-line-before': null,
'color-function-notation': null,
'alpha-value-notation': null,
'order/properties-order': [
'position',
'top',
'right',
'bottom',
'left',
'z-index',
'display',
'visibility',
'float',
'clear',
'overflow',
'-ms-overflow-x',
'-ms-overflow-y',
'overflow-x',
'overflow-y',
'-webkit-overflow-scrolling',
'clip',
'-webkit-align-content',
'-ms-flex-line-pack',
'align-content',
'-webkit-box-align',
'-moz-box-align',
'-webkit-align-items',
'align-items',
'-ms-flex-align',
'-webkit-align-self',
'-ms-flex-item-align',
'-ms-grid-row-align',
'align-self',
'-webkit-box-flex',
'-webkit-flex',
'-moz-box-flex',
'-ms-flex',
'flex',
'-webkit-flex-flow',
'-ms-flex-flow',
'flex-flow',
'-webkit-flex-basis',
'-ms-flex-preferred-size',
'flex-basis',
'-webkit-box-orient',
'-webkit-box-direction',
'-webkit-flex-direction',
'-moz-box-orient',
'-moz-box-direction',
'-ms-flex-direction',
'flex-direction',
'-webkit-flex-grow',
'-ms-flex-positive',
'flex-grow',
'-webkit-flex-shrink',
'-ms-flex-negative',
'flex-shrink',
'-webkit-flex-wrap',
'-ms-flex-wrap',
'flex-wrap',
'-webkit-box-pack',
'-moz-box-pack',
'-ms-flex-pack',
'-webkit-justify-content',
'justify-content',
'-webkit-box-ordinal-group',
'-webkit-order',
'-moz-box-ordinal-group',
'-ms-flex-order',
'order',
'-webkit-box-sizing',
'-moz-box-sizing',
'box-sizing',
'margin',
'margin-top',
'margin-right',
'margin-bottom',
'margin-left',
'padding',
'padding-top',
'padding-right',
'padding-bottom',
'padding-left',
'min-width',
'min-height',
'max-width',
'max-height',
'width',
'height',
'outline',
'outline-width',
'outline-style',
'outline-color',
'outline-offset',
'border',
'border-spacing',
'border-collapse',
'border-width',
'border-style',
'border-color',
'border-top',
'border-top-width',
'border-top-style',
'border-top-color',
'border-right',
'border-right-width',
'border-right-style',
'border-right-color',
'border-bottom',
'border-bottom-width',
'border-bottom-style',
'border-bottom-color',
'border-left',
'border-left-width',
'border-left-style',
'border-left-color',
'-webkit-border-radius',
'-moz-border-radius',
'border-radius',
'-webkit-border-top-left-radius',
'-moz-border-radius-topleft',
'border-top-left-radius',
'-webkit-border-top-right-radius',
'-moz-border-radius-topright',
'border-top-right-radius',
'-webkit-border-bottom-right-radius',
'-moz-border-radius-bottomright',
'border-bottom-right-radius',
'-webkit-border-bottom-left-radius',
'-moz-border-radius-bottomleft',
'border-bottom-left-radius',
'-webkit-border-image',
'-moz-border-image',
'-o-border-image',
'border-image',
'-webkit-border-image-source',
'-moz-border-image-source',
'-o-border-image-source',
'border-image-source',
'-webkit-border-image-slice',
'-moz-border-image-slice',
'-o-border-image-slice',
'border-image-slice',
'-webkit-border-image-width',
'-moz-border-image-width',
'-o-border-image-width',
'border-image-width',
'-webkit-border-image-outset',
'-moz-border-image-outset',
'-o-border-image-outset',
'border-image-outset',
'-webkit-border-image-repeat',
'-moz-border-image-repeat',
'-o-border-image-repeat',
'border-image-repeat',
'-webkit-border-top-image',
'-moz-border-top-image',
'-o-border-top-image',
'border-top-image',
'-webkit-border-right-image',
'-moz-border-right-image',
'-o-border-right-image',
'border-right-image',
'-webkit-border-bottom-image',
'-moz-border-bottom-image',
'-o-border-bottom-image',
'border-bottom-image',
'-webkit-border-left-image',
'-moz-border-left-image',
'-o-border-left-image',
'border-left-image',
'-webkit-border-corner-image',
'-moz-border-corner-image',
'-o-border-corner-image',
'border-corner-image',
'-webkit-border-top-left-image',
'-moz-border-top-left-image',
'-o-border-top-left-image',
'border-top-left-image',
'-webkit-border-top-right-image',
'-moz-border-top-right-image',
'-o-border-top-right-image',
'border-top-right-image',
'-webkit-border-bottom-right-image',
'-moz-border-bottom-right-image',
'-o-border-bottom-right-image',
'border-bottom-right-image',
'-webkit-border-bottom-left-image',
'-moz-border-bottom-left-image',
'-o-border-bottom-left-image',
'border-bottom-left-image',
'background',
"-ms-filter:'progid:DXImageTransform.Microsoft.Alpha",
'filter:progid:DXImageTransform.Microsoft.Alpha(Opacity',
'-ms-interpolation-mode',
'-webkit-filter',
'-ms-filter',
'filter',
'background-color',
'background-image',
'background-attachment',
'background-position',
'-ms-background-position-x',
'-ms-background-position-y',
'background-position-x',
'background-position-y',
'-webkit-background-clip',
'-moz-background-clip',
'background-clip',
'background-origin',
'-webkit-background-size',
'-moz-background-size',
'-o-background-size',
'background-size',
'background-repeat',
'object-fit',
'box-decoration-break',
'-webkit-box-shadow',
'-moz-box-shadow',
'box-shadow',
'color',
'table-layout',
'caption-side',
'empty-cells',
'list-style',
'list-style-position',
'list-style-type',
'list-style-image',
'quotes',
'content',
'counter-increment',
'counter-reset',
'-ms-writing-mode',
'vertical-align',
'text-align',
'-webkit-text-align-last',
'-moz-text-align-last',
'-ms-text-align-last',
'text-align-last',
'text-decoration',
'text-emphasis',
'text-emphasis-position',
'text-emphasis-style',
'text-emphasis-color',
'text-indent',
'-ms-text-justify',
'text-justify',
'text-outline',
'text-transform',
'text-wrap',
'-ms-text-overflow',
'text-overflow',
'text-overflow-ellipsis',
'text-overflow-mode',
'text-shadow',
'white-space',
'word-spacing',
'-ms-word-wrap',
'word-wrap',
'-ms-word-break',
'word-break',
'-moz-tab-size',
'-o-tab-size',
'tab-size',
'-webkit-hyphens',
'-moz-hyphens',
'hyphens',
'letter-spacing',
'font',
'font-weight',
'font-style',
'font-variant',
'font-size-adjust',
'font-stretch',
'font-size',
'font-family',
'src',
'line-height',
'opacity',
'-ms-interpolation-mode',
'resize',
'cursor',
'nav-index',
'nav-up',
'nav-right',
'nav-down',
'nav-left',
'-webkit-transition',
'-moz-transition',
'-ms-transition',
'-o-transition',
'transition',
'-webkit-transition-delay',
'-moz-transition-delay',
'-ms-transition-delay',
'-o-transition-delay',
'transition-delay',
'-webkit-transition-timing-function',
'-moz-transition-timing-function',
'-ms-transition-timing-function',
'-o-transition-timing-function',
'transition-timing-function',
'-webkit-transition-duration',
'-moz-transition-duration',
'-ms-transition-duration',
'-o-transition-duration',
'transition-duration',
'-webkit-transition-property',
'-moz-transition-property',
'-ms-transition-property',
'-o-transition-property',
'transition-property',
'-webkit-transform',
'-moz-transform',
'-ms-transform',
'-o-transform',
'transform',
'-webkit-transform-origin',
'-moz-transform-origin',
'-ms-transform-origin',
'-o-transform-origin',
'transform-origin',
'-webkit-animation',
'-moz-animation',
'-ms-animation',
'-o-animation',
'animation',
'-webkit-animation-name',
'-moz-animation-name',
'-ms-animation-name',
'-o-animation-name',
'animation-name',
'-webkit-animation-duration',
'-moz-animation-duration',
'-ms-animation-duration',
'-o-animation-duration',
'animation-duration',
'-webkit-animation-play-state',
'-moz-animation-play-state',
'-ms-animation-play-state',
'-o-animation-play-state',
'animation-play-state',
'-webkit-animation-timing-function',
'-moz-animation-timing-function',
'-ms-animation-timing-function',
'-o-animation-timing-function',
'animation-timing-function',
'-webkit-animation-delay',
'-moz-animation-delay',
'-ms-animation-delay',
'-o-animation-delay',
'animation-delay',
'-webkit-animation-iteration-count',
'-moz-animation-iteration-count',
'-ms-animation-iteration-count',
'-o-animation-iteration-count',
'animation-iteration-count',
'-webkit-animation-direction',
'-moz-animation-direction',
'-ms-animation-direction',
'-o-animation-direction',
'animation-direction',
'pointer-events',
'unicode-bidi',
'direction',
'-webkit-columns',
'-moz-columns',
'columns',
'-webkit-column-span',
'-moz-column-span',
'column-span',
'-webkit-column-width',
'-moz-column-width',
'column-width',
'-webkit-column-count',
'-moz-column-count',
'column-count',
'-webkit-column-fill',
'-moz-column-fill',
'column-fill',
'-webkit-column-gap',
'-moz-column-gap',
'column-gap',
'-webkit-column-rule',
'-moz-column-rule',
'column-rule',
'-webkit-column-rule-width',
'-moz-column-rule-width',
'column-rule-width',
'-webkit-column-rule-style',
'-moz-column-rule-style',
'column-rule-style',
'-webkit-column-rule-color',
'-moz-column-rule-color',
'column-rule-color',
'break-before',
'break-inside',
'break-after',
'page-break-before',
'page-break-inside',
'page-break-after',
'orphans',
'widows',
'-ms-zoom',
'zoom',
'max-zoom',
'min-zoom',
'user-zoom',
'orientation',
],
},
ignoreFiles: ['dist/**/*','**/*.js', '**/*.jsx', '**/*.tsx', '**/*.ts', './*.js'],
}
8. CICD
首先是处于.github/workflows
文件夹下面,所以如果没有这个文件夹,那么你需要先建立对应的文件夹
然后在创建一个ci.yml
文件,写的时候需要写yml
语法,需要学习的话可以菜鸟教材
// ci.yml
name: CI
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install pnpm
uses: pnpm/action-setup@v2
- name: Set node
uses: actions/setup-node@v3
with:
node-version: 18.x
cache: pnpm
- name: Setup
run: npm i -g pnpm
- name: Lint
run: pnpm run lint
test:
runs-on: ubuntu-latest
strategy:
matrix:
node: [14.x, 16.x, 18.x]
fail-fast: false
steps:
- uses: actions/checkout@v3
- name: Install pnpm
uses: pnpm/action-setup@v2
- name: Set node version to ${{ matrix.node }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node }}
cache: pnpm
- name: Setup
run: npm i -g pnpm
- name: Build
run: pnpm run build
- name: Typecheck
run: nr typecheck
- name: Test
run: pnpm run test
// cd.yml
name: Publish Package
on:
push:
tags:
- v*
jobs:
publish-npm:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Install pnpm
uses: pnpm/action-setup@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
registry-url: https://registry.npmjs.org/
cache: pnpm
- run: pnpm install
- run: npx changelogithub --no-group
continue-on-error: true
env:
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
- run: pnpm run publish
env:
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
NODE_OPTIONS: --max-old-space-size=6144