Vue 3 + Typescript + Vite2.0 搭建移动端 代码规范以及注意的点


<!--
 * @Descripttion: Vue 3 + Typescript + Vite2.0 项目简介
-->

# Vue 3 + Typescript + Vite + vant3 搭建移动端通用架子
 pc 管理系统请参考移步:VUE VBEN ADMIN2.0 (vite2.0+vue3+ts+antd-design-vue) github 地址:git clone https://github.com/anncwb/vue-vben-admin.git vue-vben-admin-2.0 项目文档:https://vvbin.cn/doc-next/ element-plus(支持 vue3) 文档:https://element-plus.gitee.io/#/zh-CN/component/installation
 vite2.0 中文文档:https://cn.vitejs.dev/ vue3 官方文档:https://v3.cn.vuejs.org/api/ Typescript 官方文档:https://www.tslang.cn/docs/home.html vant3 官方文档:https://vant-contrib.gitee.io/vant/v3/#/zh-CN/home
vue-i18n@next 国际化配置文档:https://vue-i18n.intlify.dev/introduction.html ### 初始化项目 [yarn 和 npm 的区别不赘述]
 npm init @vitejs/app or yarn create @vitejs/app ---> 输入项目名称 ---> 选择 vue-ts [vue3+TS] ### 安装依赖
 npm i or cnpm i ### 启动项目
 cnpm run dev ### 安装相关依赖 yarn 或者 cnpm npm 命令都行
 yarn add xxx npm i vue-i18n@next -S or cnpm i vue-i18n@next -S npm i vue-router@4 -S or cnpm i vue-router@4 -S npm i vuex@next -S or cnpm i vuex@next -S ### 注意问题
 node api 报错 比如配置文件使用 require node.js 不是内置对象的一部分,如果想用 typescript 写 Node.js,则需要引入第三方声明文件 解决办法:npm i @types/node -D or cnpm i @types/node -D tsconfig.json types 中配置 node 字段 ### 代码规范
 vscode 提示无法在只读编辑器中编辑 json 文件 File → Preferences → Settings --> Eslint Eslint 官方文档:https://eslint.org/docs/rules/ prettier 官方文档:https://prettier.io/docs/en/configuration.html eslint-plugin-vue 官方文档:https://eslint.vuejs.org/user-guide/#usage 自动修复 eslint 报错
npm i eslint-plugin-vue -D or cnpm i eslint-plugin-vue -D vscode Vetur 插件 ---> vue 高亮插件 vscode ESlint 插件 ---> Eslint 插件用于根据工程目录的.eslintrc.js 配置文件在编辑器中显示一些错误提示,后面的自定格式化根据这里的错误提示进行格式化操作 如果是 vue-cli 创建的项目 创建的时候把 Linter/Formatter 选上(默认已选上) 下一步选择 Eslint+Prettier --> Lint on save // eslint 配置项,保存时自动修复 "editor.codeActionsOnSave": { "source.fixAll.eslint": true }, // 默认使用 prettier 格式化支持的文件 "editor.defaultFormatter": "esbenp.prettier-vscode", // 自动设定 eslint 工作区 "eslint.workingDirectories": [ { "mode": "auto" } ], "explorer.confirmDelete": false, "diffEditor.ignoreTrimWhitespace": true, "eslint.codeAction.showDocumentation": { "enable": true }, "editor.codeActionsOnSave": { "source.fixAll.eslint": true }, "eslint.format.enable": true, "eslint.validate": ["javascript", "vue", "html","jsx", "javascriptreact"], "editor.suggest.snippetsPreventQuickSuggestions": false, "files.associations": { "\*.vue": "html" }, "editor.formatOnSave": true //由于 prettier 不能格式化 vue 文件 template 所以使用 js-beautify-html 格式化 "vetur.format.defaultFormatter.html": "js-beautify-html", "vetur.format.defaultFormatterOptions": { "js-beautify-html": { "wrap*attributes": "force-aligned" //属性强制折行对齐 } }, "prettier.singleQuote": true, //使用单引号而不是双引号 "prettier.jsxBracketSameLine": true, //将>多行 JSX 元素放在最后一行的末尾,而不是单独放在下一行 "prettier.printWidth": 120, // 超过最大值换行 "prettier.tabWidth": 2, // 缩进字节数 "prettier.useTabs": true, // 缩进使用 tab "prettier.semi": false, // 句尾添加分号 "prettier.singleQuote": true, // 使用单引号代替双引号 "prettier.proseWrap": "preserve", // 默认值。因为使用了一些折行敏感型的渲染器(如 GitHub comment)而按照 markdown 文本样式进行折行 "prettier.arrowParens": "avoid", // (x) => {} 箭头函数参数只有一个时是否要有小括号。avoid:省略括号 "prettier.bracketSpacing": true, // 在对象,数组括号与文字之间加空格 "{ foo: bar }"
"prettier.endOfLine": "auto", // 结尾是 \n \r \n\r auto "prettier.htmlWhitespaceSensitivity": "ignore", "prettier.ignorePath": ".prettierignore", // 不使用 prettier 格式化的文件填写在项目的.prettierignore 文件中 "prettier.requireConfig": false, // Require a "prettierconfig" to format prettier "prettier.trailingComma": "none", // 在对象或数组最后一个元素后面是否加逗号 /* 每种语言默认的格式化规则 \_/
"[html]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, "[css]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, "[scss]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, "[javascript]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, "[vue]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, "[json]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, 安装插件让 ESLint 支持 TypeScript npm i typescript @typescript-eslint/parser @typescript-eslint/eslint-plugin -D 当我们执行 npm run format 时还会报各种奇怪的错误 如:error: Delete ⏎ (prettier/prettier) at src/pages/xxx 等;这是因为 prettier 配置和 vscode 编辑器 prettier 配置冲突导致的 在 rules 中配置下覆盖掉就可以了 出现了下面的警告:} expected css(css lcurlyexpected), 解决方案:settings.json 中配置如下 "files.associations": { "_.vue": "vue", "_.tpl": "html" }, ### git 提交代码钩子校验
 npm i husky lint-staged -D or cnpm i husky lint-staged -D ## package.json 中配置 GitHub 文档:https://github.com/typicode/husky

"husky": { "hooks": { "pre-commit": "lint-staged", "pre-push": "lint-staged" } }, "lint-staged": { "\*.{js,jsx,md,html,css}": [ "prettier --write", "git add" ] } ### vm vw 布局适配方案 以及 css 预处理器 {这边先选择 less} UI 选型 {自己封装常用的 or 选择一种功能比较齐全的移动端 UI 库}
 cnpm i postcss-viewport-units postcss-px-to-viewport postcss-write-svg autoprefixer -D cnpm i less -D cnpm i vant@next -S cnpm i vite-plugin-imp -D // 按需加载 GitHub 文档:https://github.com/onebay/vite-plugin-imp vant 官方网站:https://vant-contrib.gitee.io/vant/v3/#/zh-CN
其实在 Vite 中无须考虑按需引入的问题。Vite 在构建代码时,会自动通过 Tree Shaking 移除未使用的 ESM 模块。而 Vant 3.0 内部所有模块都是基于 ESM 编写的,天然具备按需引入的能力。现阶段遗留的问题是,未使用的组件样式无法被 Tree Shaking 识别并移除,后续 vant 团队会考虑通过 Vite 插件的方式进行支持 ### 环境变量和打包命令配置
 根目录下新建文件 .env.development (开发) .env.test (测试) .env.production (生产) package.json 中配置打包命令 "build:dev": "vue-tsc --noEmit && vite build --mode development", "build:test": "vue-tsc --noEmit && vite build --mode test", "build:prod": "vue-tsc --noEmit && vite build --mode production" 打包命令 cnpm run build:dev // 本地包 cnpm run build:test // 测试包 cnpm run build:prod // 生产包 ### 使用 http-server 开启一个本地服务器 预览效果
 npm install http-server -g cd dist http-server -c-1(只输入 http-server 的话,更新了代码后,页面不会同步更新)ctrl + c 即可关闭 ### 调试工具
 cnpm i vconsole -S 在 main.ts 引入 import Vconsole from 'vconsole'; new Vconsole(); ### PWA
 参考文档:https://github.com/antfu/vite-plugin-pwa cnpm i vite-plugin-pwa -D 配置 vite.config.ts 文件 import { VitePWA } from 'vite-plugin-pwa' plugins:[ VitePWA({ manifest: {}, workbox: { skipWaiting: true, clientsClaim: true } }) ] ### 组件样式按需加载配置
 参考文档:https://github.com/anncwb/vite-plugin-style-import 配置 vite.config.ts 文件 cnpm i vite-plugin-style-import -D import styleImport from 'vite-plugin-style-import' css:{ preprocessorOptions:{ less:{ modifyVars:{}, javascriptEnabled: true } } }, plugins:[ styleImport({ libs:[ { libraryName: 'ant-design-vue', esModule: true, resolveStyle: name => `ant-design-vue/es/${name}/style/index` } ] }) ] ### 生产环境生成 .gz 文件.
 [content-encoding:gzip] 压缩代码,在传输的时候用 gzip 压缩,提高资源访问速度。后端以 nginx 为例的话,在 nginx.conf 需要开启 gizp 服务: gzip on; //开启 gzip 压缩功能 这样你就可以在 network 查看到 content-encoding:gzip 这个选项 参考文档:https://github.com/anncwb/vite-plugin-compression cnpm i vite-plugin-compression -D 配置 vite.config.ts 文件 import viteCompression from 'vite-plugin-compression' plugins:[ viteCompression({ verbose: true, disable: false, threshold: 10240, algorithm: 'gzip', ext: '.gz' }) ] ### 国际化配置
 安装 js-cookie cnpm i js-cookie -S cnpm i @types/js-cookie -D 参考文档:https://www.npmjs.com/package/js-cookie cnpm i vue-i18n@next -S ### http 请求库
 cnpm i axios -S ### normalize.css 更好的 reset.css 方案
 cnpm i normalize.css -S 参考文档:https://github.com/necolas/normalize.css

项目环境以及打包命令配置

项目根目录下创建 .env.test  【测试环境】 .env.development  【开发环境】  .env.production 【生产环境】

分别对应内容

NODE_ENV=test VITE_APP_BASE_URL='https://www.test.com/'
NODE_ENV=development VITE_APP_BASE_URL='api'
NODE_ENV=production VITE_APP_BASE_URL='https://www.prod.com/'

文件里获取  console.log(import.meta.env.VITE_APP_BASE_URL, '环境变量')

package.json文件下面配置

    "build:dev": "vue-tsc --noEmit && vite build --mode development", "build:test": "vue-tsc --noEmit && vite build --mode test", "build:prod": "vue-tsc --noEmit && vite build --mode production"

关于代码规范:都可以自定义规则以下是自己简单的配置规则(提供参考具体查看对应官方文档配置属性)

.eslintignore文件

*.sh node_modules *.md *.woff *.ttf .vscode .idea dist /public /docs .husky .local /bin Dockerfile

.eslintrc.js文件

/* * @Descripttion: eslint代码规范 */ module.exports = { parser: 'vue-eslint-parser', parserOptions: { parser: '@typescript-eslint/parser', ecmaVersion: 2020, sourceType: 'module', ecmaFeatures: { jsx: true } }, extends: [ 'plugin:vue/vue3-recommended', 'plugin:@typescript-eslint/recommended', 'prettier/@typescript-eslint', 'plugin:prettier/recommended' ], rules: { '@typescript-eslint/ban-ts-ignore': 'off', '@typescript-eslint/explicit-function-return-type': 'off', '@typescript-eslint/no-explicit-any': 'off', '@typescript-eslint/no-var-requires': 'off', '@typescript-eslint/no-empty-function': 'off', 'vue/custom-event-name-casing': 'off', 'no-use-before-define': 'off', // 'no-use-before-define': [
        // 'error',
        // {
        // functions: false,
        // classes: true,
        // },
        // ],
        '@typescript-eslint/no-use-before-define': 'off', // '@typescript-eslint/no-use-before-define': [
        // 'error',
        // {
        // functions: false,
        // classes: true,
        // },
        // ],
        '@typescript-eslint/ban-ts-comment': 'off', '@typescript-eslint/ban-types': 'off', '@typescript-eslint/no-non-null-assertion': 'off', '@typescript-eslint/explicit-module-boundary-types': 'off', '@typescript-eslint/no-unused-vars': [ 'error', { argsIgnorePattern: '^h$', varsIgnorePattern: '^h$' } ], 'no-unused-vars': [ 'error', { argsIgnorePattern: '^h$', varsIgnorePattern: '^h$' } ], 'space-before-function-paren': 'off', quotes: ['error', 'single'], 'comma-dangle': ['error', 'never'], "no-console": process.env.NODE_ENV === "production" ? "error" : "off", "no-debugger": process.env.NODE_ENV === "production" ? "error" : "off" } }

.prettierignore文件

/dist/* .local .output.js /node_modules/**

**/*.svg **/*.sh /public/*

.prettierrc.js文件

/* * @Descripttion: prettier.config.js or .prettierrc.js package.json 中配置prettier属性 */

// 如果vscode配置中有的这边可以不用再配置
module.exports = { useTabs: false, vueIndentScriptAndStyle: true, quoteProps: 'as-needed', jsxSingleQuote: false, arrowParens: 'always', htmlWhitespaceSensitivity: 'strict', endOfLine: 'lf', printWidth: 200, // 换行字符串阈值
    tabWidth: 2, // 设置工具每一个水平缩进的空格数
    singleQuote: true, // 用单引号
    semi: false, // 句末是否加分号
    trailingComma: 'none', // 最后一个对象元素加逗号
    bracketSpacing: true, // 对象,数组加空格
    jsxBracketSameLine: false, // jsx > 是否另起一行
    disableLanguages: ["vue"] // 不格式化vue文件,vue文件的格式化单独设置
}

postcss.config.js文件

/* * @Descripttion: postcss.config.js */ module.exports = { plugins: { autoprefixer: { /* PostCSS plugin to parse CSS and add vendor prefixes to CSS rules */
            /* 配置文档链接:https://github.com/postcss/autoprefixer#options */ overrideBrowserslist: [ 'last 2 versions' // 最后两个版本
 ] }, 'postcss-viewport-units': { /* vw兼容方案 */
            /* 配置文档链接:https://github.com/springuper/postcss-viewport-units#options */ }, 'postcss-px-to-viewport': { /* 将px单位转换为视口单位的 (vw, vh, vmin, vmax) */
            /* 配置文档链接:https://github.com/evrone/postcss-px-to-viewport/blob/master/README_CN.md#%E9%85%8D%E7%BD%AE%E5%8F%82%E6%95%B0 */ viewportWidth: 375, viewportUnit: 'vw', unitPrecision: 3, minPixelValue: 1, // 小于或等于`1px`不转换为视窗单位,你也可以设置为你想要的值
            mediaQuery: false, // selectorBlackList: ['.vant'], // 以xxx开头
            include: [], // 包括
            exclude: [] // 排除
 }, 'postcss-write-svg': { /* 在retina屏绘制1px细线 */
            /* 配置文档链接:https://github.com/jonathantneal/postcss-write-svg#options */ }, } }

tsconfig.json文件

{ "compilerOptions": { "target": "esnext", "module": "esnext", "moduleResolution": "node", "strict": true, "jsx": "preserve", "sourceMap": true, "resolveJsonModule": true, "esModuleInterop": true, "lib": ["esnext", "dom", "ES2015.promise"], "types": ["vite/client", "node"], "typeRoots": ["./node_modules/@types/", "./src/types"], "paths": { "@": ["./src"] } }, "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"], "exclude": ["node_modules"] }

vite.config.ts配置

/* * @Descripttion: vite.config.ts vite2.0 */ import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import viteCompression from 'vite-plugin-compression' const path = require('path') const resolve = (dir: string) => path.join(__dirname, dir) // https://vitejs.dev/config/
export default defineConfig({ base: process.env.NODE_ENV === 'production' ? './' : '/', plugins: [ vue(), // 默认情况下,小于1501字节的文件不会被压缩
 viteCompression({ // 是否在控制台输出压缩结果
      verbose: true, // 是否禁用
      disable: false, // 体积大于 threshold 才会被压缩,单位 b
      threshold: 10240, // 压缩算法
      algorithm: 'gzip', // 生成的压缩包后缀
      ext: '.gz', // 压缩后是否删除源文件
      deleteOriginFile: false }) ], // 别名
 resolve: { alias: { '@': resolve('src'), // 解决vue-i18n警告You are running the esm-bundler build of vue-i18n.
      'vue-i18n': 'vue-i18n/dist/vue-i18n.cjs.js' } }, // 代理解决dev模式跨域
 server: { host: '0.0.0.0', // https: false,
    port: 9999, //启动端口
    open: true, // 是否自动打开浏览器
    cors: true, proxy: { // 如果是 /api 打头,则访问地址如下
      '/api': { target: 'http://jsonplaceholder.typicode.com', changeOrigin: true, // ws: true,
        rewrite: (path) => path.replace(/^\/api/, '') } } }, css: { preprocessorOptions: { less: { modifyVars: { // Used for global import to avoid the need to import each style file separately
          // reference: Avoid repeated references
          hack: `true; @import (reference) "${resolve('src/assets/style/index.less')}";` }, javascriptEnabled: true } } }, build: { target: 'es2015', outDir: 'dist', // 生产环境移除 console
 terserOptions: { compress: { drop_console: process.env.NODE_ENV === 'production' ? true : false, drop_debugger: process.env.NODE_ENV === 'production' ? true : false } } } })

vscode  setting json配置:

{ "workbench.colorTheme": "Atom One Dark", "workbench.iconTheme": "vscode-icons", "git.ignoreWindowsGit27Warning": true, "[html]": { "editor.defaultFormatter": "HookyQR.beautify" }, "[javascript]": { "editor.defaultFormatter": "HookyQR.beautify" }, "[json]": { "editor.defaultFormatter": "vscode.json-language-features" }, "fileheader.customMade": { "Descripttion": "", "version": "", "Author": "lhl", "Date": "Do not edit", "LastEditors": "lhl", "LastEditTime": "Do not Edit" }, "fileheader.cursorMode": { "name": "", "test": "test font", "msg": "", "param": "", "return": "" }, "explorer.confirmDelete": false, "diffEditor.ignoreTrimWhitespace": true, "eslint.codeAction.showDocumentation": { "enable": true }, "editor.codeActionsOnSave": { "source.fixAll.eslint": true }, "eslint.workingDirectories": [{ "mode": "auto" }], "editor.defaultFormatter": "esbenp.prettier-vscode", "eslint.format.enable": true, "eslint.validate": ["javascript", "vue", "html", "typescript"], "editor.suggest.snippetsPreventQuickSuggestions": false, "files.associations": { "*.vue": "vue", "*.tpl": "html" }, "vetur.format.defaultFormatter.html": "js-beautify-html", "vetur.format.defaultFormatterOptions": { "js-beautify-html": { "wrap_attributes": "force-aligned" } }, "prettier.singleQuote": true, "prettier.printWidth": 200, "prettier.tabWidth": 2, "prettier.useTabs": true, "prettier.semi": false, "prettier.proseWrap": "preserve", "prettier.arrowParens": "avoid", "prettier.bracketSpacing": true, "prettier.endOfLine": "auto", "prettier.htmlWhitespaceSensitivity": "ignore", "prettier.ignorePath": ".prettierignore", "prettier.requireConfig": false, "prettier.trailingComma": "none", "editor.formatOnSave": false, "[dart]": { "editor.formatOnSave": true, "editor.formatOnType": true, "editor.rulers": [ 80 ], "editor.selectionHighlight": false, "editor.suggest.snippetsPreventQuickSuggestions": false, "editor.suggestSelection": "first", "editor.tabCompletion": "onlySnippets", "editor.wordBasedSuggestions": false } }

package.json文件

{ "name": "vite-project", "version": "0.0.0", "scripts": { "dev": "vite", "build": "vue-tsc --noEmit && vite build", "serve": "vite preview", "build:dev": "vue-tsc --noEmit && vite build --mode development", "build:test": "vue-tsc --noEmit && vite build --mode test", "build:prod": "vue-tsc --noEmit && vite build --mode production" }, "dependencies": { "@types/js-cookie": "^2.2.6", "@vant/area-data": "^1.0.0", "axios": "^0.21.1", "js-cookie": "^2.2.1", "normalize.css": "^8.0.1", "vant": "^3.0.12", "vconsole": "^3.4.0", "vue": "^3.0.5", "vue-i18n": "^9.0.0", "vue-router": "^4.0.5", "vuex": "^4.0.0" }, "devDependencies": { "@types/js-cookie": "^2.2.6", "@types/node": "^14.14.37", "@typescript-eslint/eslint-plugin": "^4.20.0", "@typescript-eslint/parser": "^4.20.0", "@vitejs/plugin-vue": "^1.2.1", "@vue/compiler-sfc": "^3.0.5", "autoprefixer": "^10.2.5", "eslint": "^7.23.0", "eslint-config-prettier": "^8.1.0", "eslint-plugin-prettier": "^3.3.1", "eslint-plugin-vue": "^7.8.0", "husky": "^6.0.0", "less": "^4.1.1", "lint-staged": "^10.5.4", "postcss-px-to-viewport": "^1.1.1", "postcss-viewport-units": "^0.1.6", "postcss-write-svg": "^3.0.1", "prettier": "^2.2.1", "typescript": "^4.1.3", "vite": "^2.1.5", "vite-plugin-compression": "^0.2.4", "vite-plugin-imp": "^2.0.5", "vue-tsc": "^0.0.15" }, "husky": { "hooks": { "pre-commit": "lint-staged", "pre-push": "lint-staged" } }, "lint-staged": { "*.{js,jsx,md,html,css}": [ "prettier --write", "git add" ] } }

以上代码纯属自己整理和测试,未经允许请勿随意转载,若有不正请及时告知!!

EditorConfig for Visual Studio Code (有喜爱的可以配置上这个下载vscode插件即可配置)

根目录下创建  .editorconfig文件 

配置参考:https://marketplace.visualstudio.com/items?itemName=EditorConfig.EditorConfig


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM