很多小伙伴苦于无法搭建一个规范的前端项目,导致后续开辟不规范,今天给各人带来一个基于Vite6+TypeScript+Vue3+ESlint9+Prettier的搭建教程。
环境依赖版本
- node:v18.20.0
- vite:^6.0.5
- typescript:~5.6.2
- vue:^3.5.13
- eslint: ^9.14.0,
- vite-plugin-checker: ^0.8.0"
一、基础配置
最新版vue官方已放弃webpack作为构建工具,vue官方之前一直是以webpack,但是近期我发现vue官网已经更新了相关内容,目前开始主推vite作为脚手架构建的工具,使用官方推荐的脚手架会更加方便,脚手架可自行选择ts、pinia 、router等相关配置,不用再像之前一样重新到尾举行安装,简朴又方便!!!
官方所在:https://cn.vuejs.org/guide/quick-start.html
1、初始化项目
留意:此处使用node版本需要>18.3
运行指令后接下来就是根据需要安装所需的功能
初始化完成的结构如图所示
2、代码质量风格的统一
eslint可以包管项目的质量,prettier可以包管项目的统一格式、风格。
每个公司的开辟规则各有差别,此处根据各自的需求自行配置,下方是我常用的风格配置(仅供参考)
2.1、配置prettier
eslint prettier插件安装、用来办理与eslint的辩论、安装prettier
- pnpm add eslint-plugin-prettier eslint-config-prettier prettier -D
复制代码
- {
- "$schema": "https://json.schemastore.org/prettierrc",
- "semi": true,
- "tabWidth": 2,
- "singleQuote": true,
- "printWidth": 150,
- "bracketSpacing": true,
- "arrowParens": "always",
- "endOfLine": "lf",
- "trailingComma": "all",
- "bracketSameLine": false,
- "embeddedLanguageFormatting": "auto",
- "useTabs": false,
- "htmlWhitespaceSensitivity": "ignore"
- }
复制代码 2.2、配置eslint
- “off” 或 0 - 关闭规则
- “warn” 或 1 - 打开规则作为警告(不影响退出代码)
- “error” 或 2 - 打开规则作为错误(触发时退出代码为 1)
- // eslint vue插件安装
- pnpm add eslint eslint-plugin-vue -D
- //eslint 识别ts语法
- pnpm add @typescript-eslint/parser
- //eslint ts默认规则补充
- pnpm add @typescript-eslint/eslint-plugin -D
复制代码 自 ESLint v9.0.0 以后,平面配置文件格式一直是默认的配置文件格式。配置文件格式已从 eslintrc 更改为 flat config。默认环境下,ESLint CLI 将搜刮 eslint.config.(js | cjs | mjs) 而不是 .eslintrc.* 文件。假如未找到 eslint.config.js 文件,CLI 会将其视为错误,而且不会运行。
以下是官方给出的具体介绍。https://eslint.org/docs/latest/use/configure/migration-guide
可参考以下文章:
探索 Antfu ESLint 配置:一款极为便捷的 ESLint 设置方案
ESLint 扁平化配置使用指南
- import pluginVue from 'eslint-plugin-vue';
- import typescriptEslint from '@typescript-eslint/eslint-plugin';
- import prettier from 'eslint-plugin-prettier';
- import vueTsEslintConfig from '@vue/eslint-config-typescript';
- import skipFormatting from '@vue/eslint-config-prettier/skip-formatting';
- import vueEslintParser from 'vue-eslint-parser';
- import tsEslintParser from '@typescript-eslint/parser';
- export default [
- {
- name: 'app/files-to-lint',
- files: ['**/*.{ts,mts,tsx,vue,js,jsx}'],
- },
- {
- name: 'app/files-to-ignore',
- ignores: ['**/dist/**', '**/dist-ssr/**', '**/coverage/**', 'node_modules'],
- // plugins: ['vue', '@typescript-eslint', 'prettier'],
- },
- ...pluginVue.configs['flat/essential'],
- ...vueTsEslintConfig(),
- skipFormatting,
- {
- name: 'app/plugins',
- plugins: {
- vue: pluginVue,
- '@typescript-eslint': typescriptEslint,
- prettier,
- },
- },
- {
- name: 'app/parser-config-vue',
- languageOptions: {
- parser: vueEslintParser,
- },
- },
- {
- name: 'app/parser-config-ts',
- files: ['**/*.{ts,mts,tsx}'],
- languageOptions: {
- parser: tsEslintParser,
- parserOptions: {
- ecmaVersion: 'latest',
- sourceType: 'module',
- ecmaFeatures: {
- jsx: true,
- },
- },
- },
- },
- {
- name: 'app/custom-rules',
- rules: {
- 'no-console': process.env.NODE_ENV === 'production' ? 'off' : 'off',
- 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
- 'key-spacing': [
- 'error',
- {
- beforeColon: false,
- afterColon: true,
- },
- ],
- 'space-in-parens': ['error', 'never'],
- 'object-curly-spacing': ['error', 'always'],
- 'object-curly-newline': [
- 'error',
- {
- minProperties: 4,
- multiline: true,
- consistent: true,
- },
- ],
- 'vue/object-curly-spacing': ['error', 'always'],
- 'max-len': 'off',
- 'no-multi-spaces': 'error',
- 'no-return-assign': 'off',
- semi: ['error', 'always'],
- eqeqeq: 'error',
- 'jsx-quotes': ['off', 'prefer-single'],
- 'jsx-a11y/click-events-have-key-events': 'off',
- 'jsx-a11y/no-noninteractive-element-interactions': 'off',
- 'import/prefer-default-export': 'off',
- 'import/extensions': 'off',
- 'import/no-unresolved': 'off',
- 'no-multiple-empty-lines': [
- 'error',
- {
- max: 2,
- maxEOF: 1,
- },
- ],
- 'no-param-reassign': 'off',
- 'vue/eqeqeq': ['error', 'always'],
- 'vue/html-end-tags': 'error',
- 'vue/no-spaces-around-equal-signs-in-attribute': 'error',
- 'vue/multi-word-component-names': 'off',
- 'vue/no-template-shadow': 'error',
- 'vue/require-prop-types': 'error',
- 'vue/require-explicit-emits': 'error',
- 'vue/mustache-interpolation-spacing': ['error', 'always'],
- 'vue/no-multi-spaces': [
- 'error',
- {
- ignoreProperties: false,
- },
- ],
- 'vue/html-closing-bracket-newline': [
- 'error',
- {
- singleline: 'never',
- multiline: 'always',
- },
- ],
- 'vue/html-self-closing': 'off',
- 'vue/block-lang': 'off',
- 'vue/html-indent': [
- 'error',
- 2,
- {
- attribute: 1,
- baseIndent: 1,
- closeBracket: 0,
- alignAttributesVertically: true,
- ignores: ['VExpressionContainer'],
- },
- ],
- 'vue/html-closing-bracket-spacing': [
- 'error',
- {
- startTag: 'never',
- endTag: 'never',
- selfClosingTag: 'always',
- },
- ],
- 'vue/max-attributes-per-line': [
- 'error',
- {
- singleline: 3,
- multiline: 1,
- },
- ],
- 'vue/attribute-hyphenation': 'off',
- '@typescript-eslint/no-shadow': 'off',
- '@typescript-eslint/no-explicit-any': 'off',
- '@typescript-eslint/no-unused-vars': 'error',
- '@typescript-eslint/ban-ts-comment': 'off',
- '@typescript-eslint/indent': 'off',
- },
- },
- ];
复制代码 2.3、配置typescript
- {
- "extends": "@vue/tsconfig/tsconfig.dom.json",
- "exclude": ["src/**/__tests__/*", "node_modules/**"],
- "compilerOptions": {
- "target": "ES2020",
- "useDefineForClassFields": true,
- "module": "ESNext",
- "lib": ["ES2020", "DOM", "DOM.Iterable"],
- "skipLibCheck": true,
- /* Bundler mode */
- "moduleResolution": "node",
- "allowImportingTsExtensions": true,
- "resolveJsonModule": true,
- "isolatedModules": true,
- "noEmit": true,
- "jsx": "preserve",
- "allowJs": true,
- /* Linting */
- "strict": true,
- "noUnusedLocals": true,
- "noUnusedParameters": true,
- "noFallthroughCasesInSwitch": true,
- /* Paths */
- "baseUrl": ".",
- "paths": {
- "@/*": ["./src/*"]
- }
- },
- "files": [],
- "references": [
- {
- "path": "./tsconfig.node.json"
- },
- {
- "path": "./tsconfig.app.json"
- }
- ]
- }
复制代码 3、配置代码检查器
vite-plugin-checker 是一个 Vite 插件,它能够在工作线程中运行 TypeScript、ESLint、vue-tsc、Stylelint 等多种静态代码检查工具,以提高开辟效率并确保代码质量。
- pnpm add vite-plugin-checker -D
复制代码
- import { fileURLToPath, URL } from 'node:url';
- import { defineConfig } from 'vite';
- import vue from '@vitejs/plugin-vue';
- import vueJsx from '@vitejs/plugin-vue-jsx';
- import checker from 'vite-plugin-checker';
- import vueDevTools from 'vite-plugin-vue-devtools';
- // https://vite.dev/config/
- export default defineConfig({
- base: './', // 配置服务器的检索方式
- plugins: [
- vue(),
- vueJsx(),
- vueDevTools(),
- checker({
- eslint: {
- useFlatConfig: true,
- lintCommand: 'eslint "./src/**/*.{ts,tsx,vue}"',
- },
- overlay: {
- initialIsOpen: false,
- },
- typescript: true,
- vueTsc: true,
- }),
- ],
- resolve: {
- alias: {
- '@': fileURLToPath(new URL('./src', import.meta.url)),
- },
- },
- // 配置外部 ip 访问与端口
- server: {
- host: '0.0.0.0',
- port: 9999,
- },
- });
复制代码 4、修改路由配置信息
假如公司对应服务没有做相关的路由映射,需要将src/router/index.ts中的createWebHistory替换成createWebHashHistory,假如有请忽略这一步调~
如下所示
二、重置浏览器默认样式
normalize.css 是一个用于重置浏览器默认样式的库,使得差别浏览器之间的渲染更加一致
- import './assets/main.css';
- import { createApp } from 'vue';
- import { createPinia } from 'pinia';
- import App from './App.vue';
- import router from './router';
- import 'normalize.css';
- const app = createApp(App);
- app.use(createPinia());
- app.use(router);
- app.mount('#app');
复制代码 三、安装样式预处理器
各人可以自行安装自己熟悉的预处理器(less、sass、stylus……),此处我选择自己常用的sass
tip:vite内置了常用的预处理器支持无需,安装配置sass-loader 即可使用
四、ui组件库安装
市面上的ui组件库有很多,此处我只提供我最常用的两种组件库举行配置
假如是搭建背景管理系统,此处可看element-plus配置。
假如是搭建移动端h5,此处发起可看vant组件库
1、element-plus组件库配置
官方文档配置:https://element-plus.org/zh-CN/guide/quickstart.html
- pnpm add element-plus
- pnpm add -D unplugin-vue-components unplugin-auto-import
复制代码
- import { fileURLToPath, URL } from 'node:url';
- import { defineConfig } from 'vite';
- import vue from '@vitejs/plugin-vue';
- import vueJsx from '@vitejs/plugin-vue-jsx';
- import checker from 'vite-plugin-checker';
- import vueDevTools from 'vite-plugin-vue-devtools';
- import AutoImport from 'unplugin-auto-import/vite';
- import Components from 'unplugin-vue-components/vite';
- import { ElementPlusResolver } from 'unplugin-vue-components/resolvers';
- // https://vite.dev/config/
- export default defineConfig({
- base: './', // 设置打包路径
- plugins: [
- vue(),
- vueJsx(),
- vueDevTools(),
- AutoImport({
- resolvers: [ElementPlusResolver()],
- }),
- Components({
- resolvers: [ElementPlusResolver()],
- }),
- checker({
- eslint: {
- useFlatConfig: true,
- lintCommand: 'eslint "./src/**/*.{ts,tsx,vue}"',
- },
- overlay: {
- initialIsOpen: false,
- },
- typescript: true,
- vueTsc: true,
- }),
- ],
- resolve: {
- alias: {
- '@': fileURLToPath(new URL('./src', import.meta.url)),
- },
- },
- server: {
- host: '0.0.0.0',
- port: 9999,
- },
- });
复制代码 2、vant组件库配置
官方文档配置: https://vant-ui.github.io/vant/#/zh-CN/quickstart
- pnpm add vant
- pnpm add @vant/auto-import-resolver unplugin-vue-components unplugin-auto-import -D
复制代码
- import { fileURLToPath, URL } from 'node:url';
- import { defineConfig } from 'vite';
- import vue from '@vitejs/plugin-vue';
- import vueJsx from '@vitejs/plugin-vue-jsx';
- import checker from 'vite-plugin-checker';
- import vueDevTools from 'vite-plugin-vue-devtools';
- import AutoImport from 'unplugin-auto-import/vite';
- import Components from 'unplugin-vue-components/vite';
- import { VantResolver } from '@vant/auto-import-resolver';
- // https://vite.dev/config/
- export default defineConfig({
- base: './', // 设置打包路径
- plugins: [
- vue(),
- vueJsx(),
- vueDevTools(),
- AutoImport({
- resolvers: [VantResolver()],
- }),
- Components({
- resolvers: [VantResolver()],
- }),
- checker({
- eslint: {
- useFlatConfig: true,
- lintCommand: 'eslint "./src/**/*.{ts,tsx,vue}"',
- },
- overlay: {
- initialIsOpen: false,
- },
- typescript: true,
- vueTsc: true,
- }),
- ],
- resolve: {
- alias: {
- '@': fileURLToPath(new URL('./src', import.meta.url)),
- },
- },
- server: {
- host: '0.0.0.0',
- port: 9999,
- },
- });
复制代码 五、二次封装axios
新增src/service/index.ts文件
- import Axios from 'axios';
- import type { AxiosInstance, InternalAxiosRequestConfig, AxiosResponse } from 'axios';
- const axios: AxiosInstance = Axios.create({
- baseURL: 'XXX',
- timeout: 20000,
- withCredentials: true,
- });
- axios.interceptors.request.use(
- (config: InternalAxiosRequestConfig) => {
- return config;
- },
- (error) => {
- // pendingRequest.clear();
- console.log(error);
- return Promise.reject(error);
- },
- );
- // 请求结束关闭loading
- axios.interceptors.response.use(
- (response: AxiosResponse) => {
- // console.log(response);
- return response.data || {};
- },
- (err) => {
- console.log('err', err);
- return Promise.reject(err);
- },
- );
- export function get<T>(url: string, params?: any): Promise<T> {
- return axios.get(url, { params });
- }
- export function post<T>(url: string, data?: any): Promise<T> {
- return axios.post(url, data);
- }
- export default axios;
复制代码 六、配置环境变量
1、创建配置文件
根目录创建三个配置文件,更多环境一样云云操作。
注: 界说的变量必须以VITE_开头
- VITE_APP_ENV = 'development';
- VITE_APP_API_URL = /api / xxx务后地服本端 / xxx测试 / xxx生产都行;
复制代码
- VITE_APP_ENV = 'test';
- VITE_APP_API_URL = xxx测试域名;
复制代码
- VITE_APP_ENV = 'production';
- VITE_APP_API_URL = xxx生产域名;
复制代码 2、使用变量
- const baseUrl = import.meta.env.VITE_BASE_URL;
复制代码
- // 使用loadEnv方法加载环境变量
- import { defineConfig, loadEnv } from 'vite';
- //...
- export default ({ mode }) => {
- console.log('加载的环境变量', loadEnv(mode, process.cwd()).VITE_BASE_URL);
- return defineConfig({
- //...
- });
- };
复制代码 3、修改package.json启动下令
- "scripts": {
- "dev": "vite --mode development",
- "build": "vite build --mode production",
- },
复制代码 七、拓展实用插件(按需安装配置)
此处推荐一些我常用的工具库,各人可以参考按需安装。相关使用方法网上一搜一大堆,这边就不多余再演示了
1、dayjs 时间处理
Day.js是一个极简的JavaScript库, 可以为现代浏览器解析、验证、操作和显示日期和时间,文件巨细只有2KB左右。Day.js对国际化有很大的支持。
2、qs
qs是一个流行的查询参数序列化和解析库。
- pnpm add qs
- // 如果项目配置了typescript需安装
- pnpm add @types/qs -D
复制代码 3、lodash实用工具库
Lodash 是一个一致性、模块化、高性能的 JavaScript 实用工具库。它提供了一套从数组、数字、对象、字符串、日期等常见数据类型中提取值的函数,以及很多其他实勤奋能。Lodash 旨在通过提高抽象程度来减少代码量,提高代码的可维护性。
- pnpm add lodash
- // 如果项目配置了typescript需安装
- pnpm add @types/lodash -D
复制代码 4、big.js(涉及计算相关)
big.js 是一个用于任意精度十进制算术的小型快速 JavaScript 库。 它允许你创建、操作和比较大数字,这些数字的精度凌驾了 JavaScript 原生 Number 类型所能提供的范围。主要可以用于处理需要高精度计算的场景,例如金额计算、科学计算、密码学等等。
- pnpm add big.js
- // 如果项目配置了typescript需安装
- pnpm add @types/big.js -D
复制代码 5、js-cookie
是一个简朴、轻量级的 JavaScript API 库,用于处理浏览器 cookies。它允许你创建、读取、删除和操作 cookie,而不需要担心浏览器的兼容性问题。
- pnpm add js-cookie
- // 如果项目配置了typescript需安装
- pnpm add @types/js-cookie -D
复制代码 6、postcss-plugin-px2rem
postcss-plugin-px2rem 是一个 PostCSS 插件,它可以主动 将 CSS 文件中的像素单位(px)转换为相对单位(rem),以实现响应式结构和移动端适配。这个插件特殊适用于需要根据差别分辨率的移动设备举行适配的场景。
- pnpm add -D postcss-plugin-px2rem autoprefixer
复制代码
- import autoprefixer from 'autoprefixer'
- import postcssPluginPx2rem from 'postcss-plugin-px2rem';
- import { defineConfig } from 'vite';
- // https://vitejs.dev/config/
- export default defineConfig({
- plugins: [
- ...
- ],
- resolve: {
- ...
- },
- css: {
- postcss: {
- plugins: [
- autoprefixer,
- postcssPluginPx2rem({
- remUnit: 108,
- rootValue: 108, // 换算基数,1rem 相当于多少 px
- unitPrecision: 5, // 允许 REM 单位增长到的十进制数字
- propWhiteList: [], // 白名单,指定哪些属性不转换为 rem
- propBlackList: [], // 黑名单,指定哪些属性需要转换为 rem
- exclude: /(node_module)/, // 排除的文件夹或文件
- selectorBlackList: [], // 要忽略并保留为 px 的选择器
- mediaQuery: false, // 允许在媒体查询中转换 px
- minPixelValue: 3 // 设置要替换的最小像素值
- }),
- ],
- },
- },
- });
复制代码 7、@vitejs/plugin-legacy(兼容旧浏览器,移动端项目重点推荐!!!)
公司合作的一些客户自带的客户端浏览器版本超级无敌老旧(此处内涵某些银行 |