文章目录
Vite3创建项目
- 创建:
pnpm create vite editor --template vue
- 配置:
/* vite.config.js */ import { defineConfig } from 'vite'; import { resolve } from 'path'; import vue from '@vitejs/plugin-vue'; export default defineConfig({ base: './', plugins: [ vue(), ], resolve: { alias: { '@': resolve(__dirname, './src') , }, }, server: { // 是否开启 https https: false, // 端口号 port: 3000, // 监听所有地址 host: '0.0.0.0', // 服务启动时是否自动打开浏览器 open: true, // 允许跨域 cors: true, // 自定义代理规则 proxy: {}, }, build: { // 设置最终构建的浏览器兼容目标 target: 'es2015', // 构建后是否生成 source map 文件 sourcemap: false, // chunk 大小警告的限制(以 kbs 为单位) chunkSizeWarningLimit: 2000, // 启用/禁用 gzip 压缩大小报告 reportCompressedSize: false, }, });
目录结构
├── dist/
└── src/
├── api/ // 接口请求目录
├── assets/ // 静态资源目录
├── common/ // 通用类库目录
├── components/ // 公共组件目录
├── router/ // 路由配置目录
├── store/ // 状态管理目录
├── style/ // 通用样式目录
├── utils/ // 工具函数目录
├── views/ // 页面组件目录
├── App.vue
├── main.js
├── tests/ // 单元测试目录
├── index.html
├── jsconfig.json // JavaScript 配置文件
├── vite.config.js // Vite 配置文件
└── package.json
└── pnpm-workspace.yaml // 工作空间
pnpm 工作空间
创建 pnpm-workspace.yaml
packages:
- 'src/*'
vue-router
- 安装:
pnpm add vue-router -w
- 目录
└── src/ ├── router/ ├── index.js ├── modules/ // 各路由模块目录 ├── index.js // 集成导出各路由模块 ├── test.js ├── ...
- 定义 router
/* src/router/index.js */ import { createRouter, createWebHistory } from "vue-router"; import modules from './modules'; const routes = [...modules]; const router = createRouter({ history: createWebHistory(import.meta.env.BASE_URL), routes, scrollBehavior(){ return { el: '#app', top: 0, behavior: 'smooth', }; }, }); export default router;
- 集成
/* src/main.js */ import router from './router'; const app = createApp(App); app.use(router);
Pinia
- 安装:
pnpm add pinia -w
- pinia 没有 modules 概念
- pinia 没有 mutations 概念
- pinia 的 actions 可同步可异步
- 定义:
/* src/store/modules/test.js */ import { defineStore } from 'pinia'; /** * import { useStore } from '@/store' * const store = useStore() * 重置store:store.$reset() * sotre.$patch({}) / store.$patch((state) => {}) * */ export const useTestStore = defineStore('test', { state: () => ({}), // getters 可以用来进行一些计算的操作 getters: { }, // 没有 mutation // 没有 modules // actions 可以是同步也可以是异步 // actions 异步调用接口,处理响应结果 actions: { test(){ // 执行一些操作 } } }); // 扁平化,不再使用 modules export const useToDoStore = defineStore('todo', {});
- 使用
<script setup> import { useTestStore } from '@/store'; const testStore = useTestStore; // 调用 test actions testStore.test(); </script>
- 目录
└── src/ ├── store/ ├── index.js ├── modules/ ├── index.js ├── test.js ├── ...
- 定义 store
/* src/store/index.js */ import { createPinia } from "pinia"; const store = createPinia(); export default store; export * from './modules';
- 集成
/* src/main.js */ import store from './store'; const app = createApp(App); app.use(store);
element-plus
- 安装:
pnpm add element-plus -w
- 按需引入:
pnpm add -w -D unplugin-vue-components unplugin-auto-import
使用组件时不需要再导入。/* vite.config.ts */ import { defineConfig } from 'vite'; import AutoImport from 'unplugin-auto-import/vite'; import Components from 'unplugin-vue-components/vite'; import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'; export default defineConfig({ // ... plugins: [ // ... AutoImport({ resolvers: [ElementPlusResolver()], }), Components({ resolvers: [ElementPlusResolver()], }), ], });
- 全局配置
<!-- src/App.vue --> <template> <el-config-provider :size="size" :z-index="zIndex"> <router-view /> </el-config-provider> </template> <script setup> const zIndex = ref(3000); const size = ref('small'); </script>
axios
- 安装:
pnpm add axios -w
- 封装
/* src/utils/request.js */ import axios from 'axios'; // 创建请求实例 const instance = axios.create({ baseURL: '/api', // 指定请求超时的毫秒数 timeout: 1000, // 表示跨域请求时是否需要使用凭证 withCredentials: false, }); // 前置拦截器(发起请求之前的拦截) instance.interceptors.request.use( (config) => { /** * 在这里一般会携带前台的参数发送给后台,比如下面这段代码: * const token = getToken() * if (token) { * config.headers.token = token * } */ return config; }, (error) => { return Promise.reject(error); }, ); // 后置拦截器(获取到响应时的拦截) instance.interceptors.response.use( (response) => { /** * 根据你的项目实际情况来对 response 和 error 做处理 * 这里对 response 和 error 不做任何处理,直接返回 */ return response; }, (error) => { const { response } = error; if (response && response.data) { return Promise.reject(error); } const { message } = error; console.error(message); return Promise.reject(error); }, );
less
vite 内置 less,仅需安装即可
- 安装:
pnpm add less -w -D
- 全局样式:
创建/* vite.config.js */ export default defineConfig({ css: { preprocessorOptions: { less: { javascriptEnabled: true, additionalData: `@import "${resolve(__dirname, 'src/style/variables.less')}";` } } } // css: { // preprocessorOptions: { // less: { // modifyVars: { // hack: `true; @import (reference) "${resolve('src/style/variables.less')}";`, // }, // math: 'strict', // javascriptEnabled: true, // }, // }, // }, });
src/style/variables.less
EditorConfig
EditorConfig helps maintain consistent coding styles for multiple developers working on the same project across various editors and IDEs.
EditorConfig帮助跨不同编辑器和ide从事同一项目的多个开发人员维护一致的编码风格。
- VScode 安装插件
EditorConfig for VSCode
- 配置(
.editorconfig
):# .editorconfig # 表示最顶层的 EditorConfig 配置文件 root = true # 表示所有文件适用 [*] # 缩进风格(space|tab|unset) indent_style = space # 控制换行类型(lf|cr|crlf|unset) end_of_line = lf # 设置文件字符集 utf-8 charset = utf-8 # 去除行首的任意空白字符 trim_trailing_whitespace = true # 始终在文件末尾插入一个新行 insert_final_newline = true # 表示 *.md 文件适用以下规则 [*.md] max_line_length = off trim_trailing_whitespace = false # 表示仅 ts、js、vue、css 文件适用以下规则 [*.{ts,js,vue,css}] indent_size = 4
eslint
ESLint 可组装的JavaScript和JSX检查工具
-
安装
ESLint
: ESLint 本体eslint-define-config
: 改善 ESLint 规范编写体验eslint-plugin-vue
: 适用于 Vue 文件的 ESLint 插件eslint-config-airbnb-base
: Airbnb JavaScript 风格指南eslint-plugin-import
: 使用 eslint-config-airbnb-base 时必须安装的前置插件vue-eslint-parser
: 使用 eslint-plugin-vue 时必须安装的 ESLint 解析器
pnpm add -w eslint eslint-define-config eslint-config-airbnb-base eslint-plugin-import eslint-plugin-vue vue-eslint-parser -D
-
VSCode 安装插件
ESLint
-
配置(
.eslintrc.js
)/* .eslintrc.js */ const { defineConfig } = require('eslint-define-config'); module.exports = defineConfig({ root: true, env: { browser: true, jest: true, node: true, es6: true }, plugins: ['vue'], parser: 'vue-eslint-parser', parserOptions: { ecmaVersion: 'latest', sourceType: 'module', allowImportExportEverywhere: true, ecmaFeatures: { jsx: true, }, }, extends: [ 'airbnb-base', 'eslint:recommended', 'plugin:vue/vue3-essential', 'plugin:vue/vue3-recommended', // 解决 prettier 冲突 'plugin:prettier/recommended', ], rules: { // 禁止使用多余的包 'import/no-extraneous-dependencies': 0, // 确保在导入路径内一致使用扩展名 'import/extensions': 0, // 确保导入指向可以解析的文件/模块 'import/no-unresolved': 0, // 首选默认导出导入/首选默认导出 'import/prefer-default-export': 0, // 要求使用 let/const,而不是 var 'no-var': 'error', // 禁止使用 new 以避免产生副作用 'no-new': 1, // 禁止变量声明与外层作用域变量同名 'no-shadow': 0, // 禁用 console 'no-console': 0, // 禁止标识符中有悬空下划线 'no-underscore-dangle': 0, // 禁止在可能与比较操作符相混淆的地方使用箭头函数 'no-confusing-arrow': 0, // 禁用一元操作符 ++ 和 -- 'no-plusplus': 0, // 禁止对 function 参数进行重新赋值 'no-param-reassign': 0, // 禁用特定的语法 'no-restricted-syntax': 0, // 禁止在变量定义之前使用它们 'no-use-before-define': 0, // 禁止直接调用 Object.prototypes 的内置属性 'no-prototype-builtins': 0, // 禁止可以在有更简单的可替代的表达式时使用三元操作符 'no-unneeded-ternary': 'error', // 禁止重复模块导入 'no-duplicate-imports': 'error', // 禁止在对象中使用不必要的计算属性 'no-useless-computed-key': 'error', // 强制使用一致的缩进(4个空格) indent: ['error', 4], // 强制使用驼峰式写法 camelcase: 0, // 强制类方法使用 this 'class-methods-use-this': 0, // 要求构造函数首字母大写 'new-cap': 0, // 强制一致的使用 function 声明函数或表达式 'func-style': 0, // 强制一行的最大长度 'max-len': 0, // 要求 return 语句要么总是指定返回的值,要么不指定 'consistent-return': 0, // 强制 switch 要有 default 分支 'default-case': 2, // 强制剩余和扩展运算符及其表达式之间有空格 'rest-spread-spacing': 'error', // 要求使用 const 声明那些声明后不再被修改的变量 'prefer-const': 'error', // 强制箭头函数的箭头前后使用一致的空格 'arrow-spacing': 'error', }, // overrides: [ // { // file: ['*.vue'], // rules: { // // 要求组件名称总是多个单词 // 'vue/multi-word-component-names': 0, // } // } // ] });
prettier
prettier 是代码格式化工具
-
VSCode 安装插件
Prettier - Code formatter
-
安装:
pnpm add -w prettier -D
-
配置(
.prettierrc.js
)/* .prettierrc.js */ module.exports = { // 一行最多 120 个字符 printWidth: 120, // 不用 tab,用空格 useTabs: false, // 缩进4个空格 tabWidth: 4, // 行尾要有分号 semi: true, // 使用单引号 singleQuote: true, // 对象的 key 仅在必要时用双引号 jsxSingleQuote: false, // 末尾需要有逗号 trailingComma: 'all', // 大括号内的首尾需要空格 bracketSpacing: true, // jsx 标签的反尖括号需要换行 jsxBracketSameLine: false, // 箭头函数,只有一个参数的时候,也需要写括号 arrowParens: 'always', // 每个文件格式化的范围是文件的全部内容 rangeStart: 0, rangeEnd: Infinity, // 不需要写文件开头的 @prettier requirePragma: false, // 不需要自动在开头插入 @prettier insertPragma: false, // 使用默认的折行标准 proseWrap: 'preserve', // 根据显示样式决定 html 要不要折行 htmlWhitespaceSensitivity: 'css', // vue 文件中的 script 和 style 内不用缩进 vueIndentScriptAndStyle: false, // 换行符使用 lf endOfLine: 'lf', // 格式化嵌入的内容 embeddedLanguageFormatting: 'auto', // html, vue, jsx 中的每个属性占一行 singleAttributePerLine: false, }
-
过滤(
.prettierignore
)## OS .DS_Store .idea .editorconfig pnpm-lock.yaml .npmrc # Ignored suffix *.log *.md *.svg *.png *.ico *ignore ## Local .husky ## Built-files .cache dist
-
解决与 ESLint 冲突
pnpm add -w eslint-plugin-prettier eslint-config-prettier -D
stylelint
-
安装:
pnpm add -w -D stylelint stylelint-config-standard stylelint-config-prettier stylelint-config-recommended-vue
-
配置(
.stylelintrc.js
)module.exports = { root: true, defaultSeverity: 'error', extends: [ 'stylelint-config-standard', 'stylelint-config-prettier', 'stylelint-config-recommended-vue', ], plugins: ['stylelint-order'], rules: { // 不允许未知函数 'function-no-unknown': null, // 指定类选择器的模式 'selector-class-pattern': null, // 禁止空源码 'no-empty-source': null, // 指定字符串使用单引号 'string-quotes': 'single', // 禁止未知的@规则 'at-rule-no-unknown': [ true, { ignoreAtRules: [ 'tailwind', 'apply', 'variants', 'responsive', 'screen', 'function', 'if', 'each', 'include', 'mixin', ], }, ], // 指定@规则名的大小写 'at-rule-name-case': 'lower', // 指定缩进 indentation: [ 2, { severity: 'warning', }, ], // 禁止未知的伪类选择器 'selector-pseudo-class-no-unknown': [ true, { ignorePseudoClasses: ['global'], }, ], // 禁止未知的伪元素选择器 'selector-pseudo-element-no-unknown': [ true, { ignorePseudoElements: ['v-deep'], }, ], 'order/properties-order': [ 'position', 'top', 'right', 'bottom', 'left', 'z-index', 'display', 'justify-content', 'align-items', 'float', 'clear', 'overflow', 'overflow-x', 'overflow-y', 'margin', 'margin-top', 'margin-right', 'margin-bottom', 'margin-left', 'padding', 'padding-top', 'padding-right', 'padding-bottom', 'padding-left', 'width', 'min-width', 'max-width', 'height', 'min-height', 'max-height', 'font-size', 'font-family', 'font-weight', 'border', 'border-style', 'border-width', 'border-color', 'border-top', 'border-top-style', 'border-top-width', 'border-top-color', 'border-right', 'border-right-style', 'border-right-width', 'border-right-color', 'border-bottom', 'border-bottom-style', 'border-bottom-width', 'border-bottom-color', 'border-left', 'border-left-style', 'border-left-width', 'border-left-color', 'border-radius', 'text-align', 'text-justify', 'text-indent', 'text-overflow', 'text-decoration', 'white-space', 'color', 'background', 'background-position', 'background-repeat', 'background-size', 'background-color', 'background-clip', 'opacity', 'filter', 'list-style', 'outline', 'visibility', 'box-shadow', 'text-shadow', 'resize', 'transition', ], }, overrides: [ { files: ['*.vue', '**/*.vue', '*.html', '**/*.html'], extends: ['stylelint-config-html'], rules: { // 指定关键帧名称的模式 'keyframes-name-pattern': null, // 禁止未知的伪类选择器 'selector-pseudo-class-no-unknown': [ true, { ignorePseudoClasses: ['deep', 'global'], }, ], // 禁止未知的伪元素选择器 'selector-pseudo-element-no-unknown': [ true, { ignorePseudoElements: ['v-deep', 'v-global', 'v-slotted'], }, ], }, }, { files: ['*.less', '**/*.less'], customSyntax: 'postcss-less', extends: ['stylelint-config-standard', 'stylelint-config-recommended-vue'], }, ], }
-
忽略检测(
.stylelintignore
)# .stylelintignore # 旧的不需打包的样式库 *.min.css # 其他类型文件 *.js *.jpg *.woff # 测试和打包目录 /test/ /dist/* /public/* public/* /node_modules/
-
VSCode 安装插件
Stylelint
husky
You can use it to lint your commit messages, run tests, lint code, etc… when you commit or push. Husky supports all Git hooks.
您可以使用它来检测提交消息、运行测试、检测代码等。当你承诺或推动的时候。Husky支持所有Git钩子。
如果没有 npx 命令,执行
cnpm install -g npx
安装
-
安装(自动):
pnpm dlx husky-init && pnpm install
-
只需要用 ESLint 修复此次写的代码,而不去影响其他的代码,此时需要借助 lint-staged 工具。
lint-staged 一般结合 husky 来使用,它可以让 husky 的 hook 触发的命令只作用于 git 暂存区的文件,而不会影响到其他文件。
-
安装:
pnpm add -w lint-staged -D
-
配置(
package.json
){ // "husky": { // "hooks": { // "pre-commit": "lint-staged", // "commit-msg": "npx --no-install commitlint --edit $1" // } // }, "lint-staged": { "*.{js,jsx,ts,tsx}": [ "prettier --write", "eslint --fix" ], "*.vue": [ "prettier --write", "eslint --fix", "stylelint --fix" ], "*.{html,vue,vss,sass,less}": [ "prettier --write", "stylelint --fix" ], "package.json": [ "prettier --write" ], "*.md": [ "prettier --write" ] } }
-
Hook(pre-commit)
npx husky add .husky/pre-commit 'npx lint-staged'
-
-
规范提交
- 安装:
cnpm install -g git-cz commitizen pnpm add -w git-cz -D
- 配置(
package.json
)
{ "config": { "commitizen": { "path": "git-cz" } } }
- 配置 script(
package.json
)
{ "scripts": { "commit": "git-cz" } }
- 自定义git-cz配置(
changelog.config.js
)
/* 修改提示 */ module.exports = { disableEmoji: false, format: '{type}{scope}: {emoji}{subject}', list: ['test', 'feat', 'fix', 'chore', 'docs', 'refactor', 'style', 'ci', 'perf'], maxMessageLength: 64, minMessageLength: 3, questions: ['type', 'scope', 'subject', 'body', 'breaking', 'issues', 'lerna'], scopes: [], types: { chore: { description: 'Build process or auxiliary tool changes', emoji: '🤖', value: 'chore', }, ci: { description: 'CI related changes', emoji: '🎡', value: 'ci', }, docs: { description: 'Documentation only changes', emoji: '✏️', value: 'docs', }, feat: { description: 'A new feature', emoji: '🎸', value: 'feat', }, fix: { description: 'A bug fix', emoji: '🐛', value: 'fix', }, perf: { description: 'A code change that improves performance', emoji: '⚡️', value: 'perf', }, refactor: { description: 'A code change that neither fixes a bug or adds a feature', emoji: '💡', value: 'refactor', }, release: { description: 'Create a release commit', emoji: '🏹', value: 'release', }, style: { description: 'Markup, white-space, formatting, missing semi-colons...', emoji: '💄', value: 'style', }, test: { description: 'Adding missing tests', emoji: '💍', value: 'test', }, messages: { type: "Select the type of change that you're committing:", customScope: 'Select the scope this component affects:', subject: 'Write a short, imperative mood description of the change:\n', body: 'Provide a longer description of the change:\n ', breaking: 'List any breaking changes:\n', footer: 'Issues this commit closes, e.g #123:', confirmCommit: 'The packages that this commit has affected\n', }, }, };
- 提交代码:
pnpm commit
- 安装:
WARNING
商业转载请联系本人,非商业转载请注明出处。