前语

Vue 3 正式版现已发布有一段时间了,跟着 Vite 脚手架注定成为下一代前端东西链,许多用户都想根据 Vite 来构建 Vue 项目,假如想根据 Vite 构建 Vue 3 项目,社区模板彻底满意您的需求,假如想构建 Vite 3 + Vue 3 + JavaScript 项目,那社区模板不太能满意您的需求,由于社区模板提供 Vue 3 项目几乎是根据 Vite 2 + TypeScript 构建,对于不熟悉 TypeScript 言语的用户不是很友爱,因此接下来从 0 开端手把手带我们建立一套标准的 Vite 3 + Vue 3 + JavaScript 前端工程化项目环境。

本文章篇幅较长,从以下几个方面打开:

  • 根底建立
  • 代码标准
  • 提交标准
  • 主动布置

本项目完好代码托管在 GitHub 库房,欢迎点亮小星星

技能栈

  • ⚡️ Vite 3 – 构建东西(便是快!)
  • Vue 3 – 渐进式 JavaScript 框架
  • Vue Router – 官方路由管理器
  • Pinia – 值得你喜欢的 Vue Store
  • TDesign – TDesign 适配桌面端的组件库
  • Less – CSS 预处理器
  • Axios – 一个根据 promise 的网络恳求库,能够用于浏览器和 node.js
  • Husky + Lint-Staged – Git Hook 东西
  • ️ EditorConfig + ESLint + Prettier + Stylelint – 代码标准
  • Commitizen + Commitlint – 提交标准
  • GitHub Actions – 主动布置

根底建立

构建项目雏形

确保你装置了最新版别的 Node.js,然后在指令行中运转以下指令:

# npm 6.x
npm create vite@latest vite-vue-js-template --template vue
# npm 7+, extra double-dash is needed:
npm create vite@latest vite-vue-js-template -- --template vue
# yarn
yarn create vite vite-vue-js-template --template vue
# pnpm
pnpm create vite vite-vue-js-template --template vue

这一指令将会装置并履行 create-vite,它是一个根本模板快速发动项目东西。

从 0 建立 Vite 3 + Vue 3 前端工程化项目

在项目被创立后,通过以下过程装置依靠并发动开发服务器:

# 打开项目
cd <your-project-name>
# 装置依靠
npm install
# 发动项目
npm run dev

从 0 建立 Vite 3 + Vue 3 前端工程化项目

Vite 根底装备

Vite 装备文件 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,
    },
});

关于 Vite 更多装备项及用法,请检查 Vite 官网 vitejs.dev/config/ 。

标准目录结构

├── 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

集成 Vue Router 路由东西

装置依靠

npm i vue-router@4

创立路由装备文件

src/router 目录下新建 index.js 文件与 modules 文件夹

└── src/
    ├── router/
    	├── modules/  // 路由模块
        ├── index.js  // 路由装备文件

关于路由表,主张根据功用的不同来拆分到 modules 文件夹中,优点是:

  • 方便后期维护

  • 减少 Git 合并代码抵触可能性

export default [
  {
    path: '/',
    name: 'home',
    component: () => import('@/views/HomeView.vue'),
  },
  {
    path: '/about',
    name: 'about',
    component: () => import('@/views/AboutView.vue'),
  },
];
import { createRouter, createWebHistory } from 'vue-router';
import baseRouters from './modules/base';
const routes = [...baseRouters];
const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes,
  scrollBehavior() {
    return {
      el: '#app',
      top: 0,
      behavior: 'smooth',
    };
  },
});
export default router;

根据路由装备的实际状况,需求在 src 下创立 views 目录,用来存储页面组件。

挂载路由装备

main.js 文件中挂载路由装备

import { createApp } from 'vue';
import App from './App.vue';
import router from './router';
createApp(App).use(router).mount('#app');

集成 Pinia 大局状态管理东西

装置依靠

npm i pinia

创立库房装备文件

src/store 目录下新建 index.js 文件与 modules 文件夹

└── src/
    ├── store/
    	├── modules/  // 库房模块
        ├── index.js  // 库房装备文件
import { defineStore } from 'pinia';
export const useCounterStore = defineStore('counter', {
  state: () => ({
    count: 1,
  }),
  actions: {
    accumulate() {
      this.count++;
    },
  },
});
import { createPinia } from 'pinia';
const store = createPinia();
export default store;
export * from './modules/counter';

开发中需求将不同功用所对应的状态,拆分到不同的 modules,优点好像路由模块相同。

挂载 Pinia 装备

main.js 文件中挂载 Vuex 装备

import { createApp } from 'vue';
import App from './App.vue';
import store from './store';
import router from './router';
createApp(App).use(router).use(store).mount('#app');

集成 TDesign Vue Next 组件库

装置依靠

npm i tdesign-vue-next

根底运用

import { createApp } from 'vue';
import TDesign from 'tdesign-vue-next';
// 引进组件库大局款式资源
import 'tdesign-vue-next/es/style/index.css';
const app = createApp(App);
app.use(TDesign);

按需引进

运用 unplugin-vue-componentsunplugin-auto-import 来完结主动导入:

npm install unplugin-vue-components unplugin-auto-import -D

在 Vite 对应的装备文件 vite.config.js 增加上述插件:

import AutoImport from 'unplugin-auto-import/vite';
import Components from 'unplugin-vue-components/vite';
import { TDesignResolver } from 'unplugin-vue-components/resolvers';
export default {
  plugins: [
    AutoImport({
      resolvers: [TDesignResolver({
        library: 'vue-next'
      })],
    }),
    Components({
      resolvers: [TDesignResolver({
        library: 'vue-next'
      })],
    }),
  ],
};

集成 Axios HTTP 东西

装置依靠

npm i axios

恳求装备

utils 目录下创立 request.js 文件,装备好适合自己事务的恳求阻拦和响应阻拦:

└── src/
    ├── api  // 接口
    ├── utils/
        ├── request.js  // axios 恳求库二次封装
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);
  },
);
// 导出常用函数
/**
 * @param {string} url
 * @param {object} data
 * @param {object} params
 */
export const post = (url, data = {}, params = {}) => {
  return instance({
    method: 'post',
    url,
    data,
    params,
  });
};
/**
 * @param {string} url
 * @param {object} params
 */
export const get = (url, params = {}) => {
  return instance({
    method: 'get',
    url,
    params,
  });
};
/**
 * @param {string} url
 * @param {object} data
 * @param {object} params
 */
export const put = (url, data = {}, params = {}) => {
  return instance({
    method: 'put',
    url,
    params,
    data,
  });
};
/**
 * @param {string} url
 * @param {object} params
 */
export const _delete = (url, params = {}) => {
  return instance({
    method: 'delete',
    url,
    params,
  });
};
export default instance;

之后在 api 文件夹中以事务模型对接口进行拆分,举个例子,将一切跟用户相关接口封装在 User 类中,此类称效果户模型。

User 类中比方有登录、注册、获取用户信息等办法,假如有事务逻辑变化,只需求批改相关办法即可。

import { post } from '@/utils/request';
export default class User {
  /**
   * 登录
   * @param {String} username 用户名
   * @param {String} password 密码
   * @returns
   */
  static async login(username, password) {
    return post('/login', {
      username,
      password,
    });
  }
}

把每个事务模型独立成一个 js 文件,声明一个类通过其特点和办法来完结这个模型相关的数据获取,这样能够大大提高代码的可读性与可维护性

模仿演示

在需求运用接口的当地,引进对应的事务模型文件,参阅如下:

<script>
import User from '@/api/user';
export default {
  data() {
    return {
      username: '',
      password: '',
    };
  },
  methods: {
    async login() {
      const res = await User.login(this.username, this.password);
      console.log(res);
    },
  },
};
</script>

集成 CSS 预处理器 Less

本项目运用 CSS 预处理器 Less,直接装置为开发依靠即可。

Vite 内部已帮咱们集成了相关的 loader,不需求额定装备。

装置依靠

npm i less -D

怎么运用

<style></style> 款式标签中引证 lang="less" 即可。

<style lang="less"></style>

CSS 命名标准引荐 BEM 命名标准

参阅链接:CSS BEM 书写标准

大局款式

src/style 目录下创立 variables.less 大局款式文件:

└── src/
    ├── style/
        ├── variables.less  // 大局款式文件

vite.config.js 装备文件中新增CSS 预处理器相关装备即可完结 less 大局款式:

import { resolve } from 'path';
export default defineConfig({
    css: {
      preprocessorOptions: {
        less: {
          modifyVars: {
            hack: `true; @import (reference) "${resolve('src/style/variables.less')}";`,
          },
          math: 'strict',
          javascriptEnabled: true,
        },
      },
    },
});

款式穿透

官方文档

在 Vue3 中,改动了以往款式穿透的语法,假如继续运用 ::v-deep/deep/>>> 等语法的话,会呈现一个正告,下面是新的语法:

/* 深度选择器 */
:deep(selector) {
  /* ... */
}
/* 插槽选择器 */
:slotted(selector) {
  /* ... */
}
/* 大局选择器 */
:global(selector) {
  /* ... */
}

至此,一个根据 JavaScript + Vite3 + Vue3 + Vue Router + Pinia + Axios + Less 的前端项目开发环境建立完毕。

项目托管在 GitHub 库房,需求的同学能够去下载下来,参阅学习。

接下来增加代码标准束缚、提交标准束缚、单元测验、主动布置等,让其更完善、更健壮。

代码标准

跟着前端使用逐步变得大型化和复杂化,在同一个项目中有多个人员参与时,每个人的前端能力程度不等,他们往往会用不同的编码风格和习惯在项目中写代码,长此下去,势必会让项目的健壮性越来越差。处理这些问题,理论上讲,口头约定和代码检查都能够,可是这种方法无法实时反馈,而且交流本钱过高,不行灵活,更要害的是无法把控。不以规矩,不能成方圆,咱们不得不在项目运用一些东西来束缚代码标准。

本文解说怎么运用 EditorConfig + ESLint + Prettier + Stylelint 组合来完结代码标准化。

这样做带来优点:

  • 处理团队之间代码不标准导致的可读性差和可维护性差的问题。
  • 处理团队成员不同修改器导致的编码标准不一致问题。
  • 提早发现代码风格问题,给出对应标准提示,及时批改。
  • 减少代码检查过程中反反复复的批改过程,节约时间。
  • 主动格局化,一致编码风格,从此和脏乱差的代码说再会。

集成 EditorConfig 装备

EditorConfig 首要用于一致不同 IDE 修改器的编码风格。

在项目根目录下增加 .editorconfig 文件:

# 表明是最顶层的 EditorConfig 装备文件
root = true
# 表明一切文件适用
[*]
# 缩进风格(tab | space)
indent_style = space
# 操控换行类型(lf | cr | crlf)
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 = 2

很多 IDE 中会默许支撑此装备,可是也有些不支撑,如:VSCode、Atom、Sublime Text 等。

具体列表能够参阅官网,假如在 VSCode 中运用需求装置 EditorConfig for VS Code 插件。

从 0 建立 Vite 3 + Vue 3 前端工程化项目

集成 ESLint 装备

ESLint 是针对 EScript 的一款代码检测东西,它能够检测项目中编写不标准的代码,假如写出不契合标准的代码会被正告。

由此咱们就能够借助于 ESLint 强壮的功用来一致团队的编码标准。

装置依靠

  • 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 解析器
npm i eslint eslint-define-config eslint-config-airbnb-base eslint-plugin-import eslint-plugin-vue vue-eslint-parser -D

装置插件

Visual Studio Code 修改器运用 ESLint 装备需求下载插件 ESLint

从 0 建立 Vite 3 + Vue 3 前端工程化项目

JetBrains 系列修改器(WebStorm、IntelliJ IDEA 等)则不必额定装置插件。

创立 ESLint 装备文件

在项目根目录创立 .eslintrc.js 文件,并填入以下内容:

const { defineConfig } = require('eslint-define-config');
module.exports = defineConfig({
  root: true,
  env: {
    browser: true,
    node: true,
    jest: true,
    es6: true,
  },
  plugins: ['vue'],
  parser: 'vue-eslint-parser',
  parserOptions: {
    ecmaVersion: 'latest',
    sourceType: 'module',
    allowImportExportEverywhere: true,
    ecmaFeatures: {
      jsx: true,
    },
  },
  extends: [
    'eslint-config-airbnb-base',
    'eslint:recommended',
    'plugin:vue/vue3-essential',
    'plugin:vue/vue3-recommended',
    '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',
    // 制止不必要的转义字符
    'no-useless-escape': 0,
    // 禁用 continue 句子
    'no-continue': 0,
    // 强制运用一致的缩进
    indent: ['error', 2, { SwitchCase: 1 }],
    // 强制运用骆驼拼写法命名约定
    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',
    // 只强制目标解构,不强制数组解构
    'prefer-destructuring': ['error', { object: true, array: false }],
  },
});

关于更多装备项信息,请前往 ESLint 官网检查 ESLint-Configuring

创立 ESLint 过滤规矩

在项目根目录增加一个 .eslintignore 文件,内容如下:

dist
node_modules
!.prettierrc.js
components.d.ts
auto-imports.d.ts

集成 Prettier 装备

Prettier 是一款强壮的代码格局化东西,支撑 JavaScript、TypeScript、CSS、SCSS、Less、JSX、Angular、Vue、GraphQL、JSON、Markdown 等言语,根本上前端能用到的文件格局它都能够搞定,是当下最盛行的代码格局化东西。

装置依靠

npm i prettier -D

装置插件

Visual Studio Code 修改器运用 Prettier 装备需求下载插件 Prettier – Code formatter

从 0 建立 Vite 3 + Vue 3 前端工程化项目

JetBrains 系列修改器(WebStorm、IntelliJ IDEA 等)则不必额定装置插件,可直接运用 Prettier 装备。

创立 Prettier 装备文件

Prettier 支撑多种格局的装备文件,比方 .json.yml.yaml.js等。

在项目根目录创立 .prettierrc.js 文件,并填入以下内容:

module.exports = {
  // 一行最多 120 字符
  printWidth: 120,
  // 运用 2 个空格缩进
  tabWidth: 2,
  // 不运用缩进符,而运用空格
  useTabs: false,
  // 行尾需求有分号
  semi: true,
  // 运用单引号
  singleQuote: true,
  // 目标的 key 仅在必要时用引号
  quoteProps: 'as-needed',
  // jsx 不运用单引号,而运用双引号
  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,
};

关于更多装备项信息,请前往 Prettier 官网检查 Prettier-Options

创立 Prettier 过滤规矩

在项目根目录增加一个 .prettierignore 文件,内容如下:

## OS
.DS_Store
.idea
.editorconfig
pnpm-lock.yaml
.npmrc

# Ignored suffix
*.log
*.md
*.svg
*.png
*.ico
*ignore

## Local
.husky

## Built-files
.cache
dist

处理 Prettier 和 ESLint 抵触

本项目中的 ESLint 装备运用了 Airbnb JavaScript 风格攻略校验,其规矩之一是代码完毕后边要加分号,而在 Prettier 装备文件中加了代码完毕后边不加分号装备项,然后抵触了。

处理两者抵触问题,需求用到 eslint-plugin-prettiereslint-config-prettier

  • eslint-plugin-prettier 将 Prettier 的规矩设置到 ESLint 的规矩中
  • eslint-config-prettier 封闭 ESLint 中与 Prettier 中会发生抵触的规矩

最终形成优先级:Prettier 装备规矩 > ESLint 装备规矩

装置依靠

npm i eslint-plugin-prettier eslint-config-prettier -D

批改 ESLint 装备文件

批改 .eslintrc.js 文件,在 extends 中增加 plugin:prettier/recommended 规矩(此规矩一定要加在最终)。

module.exports = {
  extends: [
    'airbnb-base',
    'eslint:recommended',
    'plugin:vue/vue3-essential',
    'plugin:vue/vue3-recommended',
    'plugin:prettier/recommended'
  ],
}

主动格局化代码

Visual Studio Code 在 settings.json 设置文件中,增加以下代码:

{
  "editor.codeActionsOnSave": {
    "source.fixAll": true,
    "source.fixAll.eslint": true
  }
}

WebStorm 打开设置窗口,按如下操作,最终点击 Apply -> OK

从 0 建立 Vite 3 + Vue 3 前端工程化项目

集成 Stylelint 装备

Stylelint 是一个强壮、先进的 CSS 代码检查器(linter),能够帮助你躲避 CSS 代码中的过错并保持一致的编码风格。

装置依靠

  • Stylelint – Stylelint 本体
  • stylelint-less – Stylelint Less 规矩
  • stylelint-config-prettier – 封闭 Stylelint 中与 Prettier 中会发生抵触的规矩
  • stylelint-config-standard – Stylelint 官方引荐规矩
  • stylelint-config-recess-order – 对 CSS 声明进行排序
  • stylelint-order – CSS 特点顺序规矩插件
npm i stylelint stylelint-less stylelint-config-prettier stylelint-config-standard stylelint-config-recess-order stylelint-order -D

装置插件

Visual Studio Code 修改器运用 Stylelint 装备需求下载插件 Stylelint

从 0 建立 Vite 3 + Vue 3 前端工程化项目

JetBrains 系列修改器(WebStorm、IntelliJ IDEA 等)则不必额定装置插件。

创立 Stylelint 装备文件

在项目根目录创立 .stylelintrc.js 文件,并填入以下内容:

module.exports = {
  root: true,
  defaultSeverity: 'error',
  plugins: ['stylelint-order', 'stylelint-less'],
  extends: [
    'stylelint-config-standard', // the standard shareable config for Stylelint
    'stylelint-config-html/html', // the shareable html config for Stylelint.
    'stylelint-config-html/vue', // the shareable vue config for Stylelint.
    'stylelint-config-recess-order', // use the clean order for properties
    'stylelint-config-prettier', // turn off any rules that conflict with Prettier
  ],
  rules: {
    // 制止在掩盖高特异性选择器之后呈现低特异性选择器
    'no-descending-specificity': null,
    // 制止空源码
    'no-empty-source': null,
    // 制止字体族中缺少泛型族要害字
    'font-family-no-missing-generic-family-keyword': null,
    // 制止不知道的@规矩
    'at-rule-no-unknown': [
      true,
      {
        ignoreAtRules: [
          'tailwind',
          'apply',
          'variants',
          'responsive',
          'screen',
          'function',
          'if',
          'each',
          'include',
          'mixin',
        ],
      },
    ],
    // 不答应不知道函数
    'function-no-unknown': null,
    // 不答应不知道单位
    'unit-no-unknown': [true, { ignoreUnits: ['rpx'] }],
    // 不答应选择器运用供应商前缀
    'selector-no-vendor-prefix': null,
    // 指定要害帧名称的方法
    'keyframes-name-pattern': null,
    // 指定类选择器的方法
    'selector-class-pattern': null,
    // 不答应值运用供应商前缀
    'value-no-vendor-prefix': null,
    // 要求或制止在规矩之前的空行
    'rule-empty-line-before': ['always', { ignore: ['after-comment', 'first-nested'] }],
    // 指定字符串运用单引号
    'string-quotes': 'single',
    // 指定@规矩名的巨细写
    'at-rule-name-case': 'lower',
    // 指定缩进
    indentation: [2, { severity: 'warning' }],
  },
  ignoreFiles: ['**/*.js', '**/*.jsx', '**/*.tsx', '**/*.ts'],
};

创立 Stylelint 过滤规矩

在项目根目录增加一个 .stylelintignore 文件,内容如下:

# .stylelintignore
# 旧的不需打包的款式库
*.min.css
# 其他类型文件
*.js
*.jpg
*.woff
# 测验和打包目录
/test/
/dist/*
/public/*
public/*
/node_modules/

启用 Vue 文件支撑

Stylelint v14 版别默许不支撑 vue 文件中的 style 代码主动检测,概况检查官方搬迁攻略

装置依靠

  • stylelint-config-html – 解析 vue 文件
  • postcss-html – 运用 stylelint-config-html 依靠的模块
  • postcss-less – 对 less 文件进行解析
npm i stylelint-config-html postcss-html postcss-less -D

批改 Stylelint 装备文件

批改 .stylelintrc.js 文件,增加如下装备:

module.exports = {
  overrides: [
    {
      files: ['*.vue', '**/*.vue', '*.html', '**/*.html'],
      customSyntax: 'postcss-html',
      rules: {
        // 制止不知道的伪类选择器
        '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',
      rules: {
        'less/color-no-invalid-hex': true,
        'less/no-duplicate-variables': true,
      },
    },
  ],
};

批改 Visual Studio Code 作业区装备

Visual Studio Code 在 settings.json 设置文件中,增加以下代码:

{
  "stylelint.validate": ["css", "less", "postcss", "scss", "vue", "sass", "html"]
}

集成 husky 和 lint-staged

在项目中已集成 ESLint 和 Prettier,在编码时,这些东西能够对代码进行实时校验,在一定程度上能有用标准所写代码,但有些人可能觉得这些限制很麻烦,然后选择视“提示”而不见,仍旧按自己编程风格来写代码,或许干脆禁用掉这些东西,开发完结就直接把代码提交到了库房,铢积寸累,ESLint 也就形同虚设。

所以,还需求做一些限制,让没通过 ESLint 检测和批改的代码制止提交,然后保证库房代码都是契合标准的。

为了处理这个问题,需求用到 Git Hook,在本地履行 git commit 的时候,就对所提交的代码进行 ESLint 检测和批改(即履行 eslint --fix),假如这些代码没通过 ESLint 规矩校验,则制止提交。

完结这一功用,需求借助 husky + lint-staged 。

装备 husky

留意:本项目运用 husky 6.x 版别,6.x 版别装备方法跟之前版别有较大差异,当发现装备办法不一致时,一切以 husky 官网为准。

运用 husky-init 指令快速在项目初始化 husky 装备:

# 初始化库房
git init
# 初始化
npx husky-init
# 装置依靠
npm install

husky 包含很多 hook(钩子),常用有:pre-commitcommit-msg

运用 pre-commit 来触发 ESLint 指令,批改 .husky/pre-commit 文件触发指令:

eslint --fix ./src --ext .vue,.js,.ts

pre-commit hook 文件效果是:当履行 git commit -m "xxx" 时,会先对 src 目录下一切的 .vue.js.ts 文件履行 eslint --fix 指令,假如 ESLint 通过,成功 commit,不然停止 commit

可是又存在一个问题:有时候明明只改动了一两个文件,却要对一切的文件履行 eslint --fix

假如这是一个前史项目,在半途装备了 ESLint 规矩,那么在提交代码时,也会对其他未批改的“前史”文件都进行检查,可能会造成很多文件呈现 ESLint 过错,显然这不是咱们想要的结果。

所以只需求用 ESLint 批改此次写的代码,而不去影响其他的代码,此时需求借助 lint-staged 东西。

装备 lint-staged

lint-staged 一般结合 husky 来运用,它能够让 husky 的 hook 触发的指令只效果于 git 暂存区的文件,而不会影响到其他文件。

装置依靠

npm i lint-staged -D

新增装备

package.json 里增加 lint-staged 装备项:

{
  "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"
    ]
  },
}

批改触发指令

批改 .husky/pre-commit 文件触发指令为:

npx lint-staged

从 0 建立 Vite 3 + Vue 3 前端工程化项目

通过以上装备之后,就能够在每次提交之前对一切代码进行格局化,保证线上代码的标准性。

提交标准

多人协作项目中,在提交代码环节,也存在一种状况:不能保证每个人对提交信息的准确描绘,因此会呈现提交信息紊乱、风格不一致的状况。

假如 git commit 的描绘信息精准,在后期维护和 Bug 处理时会变得有据可查,项目开发周期内还能够根据标准的提交信息快速生成开发日志,然后方便咱们追踪项目和把控进展。

社区最盛行、最闻名、最受认可的 Angular 团队提交标准:

从 0 建立 Vite 3 + Vue 3 前端工程化项目

参阅链接: Angular Style Commit Message Conventions

Commit Message 格局标准

commit message 由 Header、Body、Footer 组成。

<Header>
<Body>
<Footer>

Header

Header 部分包括三个字段 type(必需)、scope(可选)和 subject(必需)。

<type>(<scope>): <subject>

type

type 用于阐明 commit 的提交类型(有必要是以下几种之一)。

描绘
feat 新增功用
fix 批改问题
docs 文档改动
style 代码格局(不影响功用,例如空格、分号等格局批改)
refactor 代码重构
perf 改进功能
test 测验
build 改动项目构建或外部依靠(例如 scopes: webpack、gulp、npm 等)
ci 更改继续集成软件的装备文件和 package 中的 scripts 指令,例如 scopes: Travis, Circle 等
chore 改动构建流程或辅助东西
revert 代码回退

scope

scope 用于指定本次 commit 影响的规模。

scope 根据项目而定,例如在事务项目中能够根据菜单或许功用模块划分,假如是组件库开发,则能够根据组件划分。

subject

subject 是本次 commit 的简练描绘,长度约定在 50 个字符以内,通常遵从以下几个标准:

  • 用动词最初,第一人称现在时表述,例如:change 替代 changed 或 changes
  • 第一个字母小写
  • 结束不加句号(.)

Body

body 是对本次 commit 的详细描绘,能够分红多行。

跟 subject 类似,用动词最初,body 应该阐明批改的原因和更改前后的行为比照。

Footer

假如本次提交的代码是突破性的改动或封闭缺点,则 Footer 必需,不然能够省掉。

  • 突破性的改动

    当时代码与上一个版别有突破性改动,则 Footer 以 BREAKING CHANGE 最初,后边是对变化的描绘、以及变化的理由。

  • 封闭缺点

    假如当时提交是针对特定的 issue,那么能够在 Footer 部分填写需求封闭的单个 issue 或一系列 issues。

参阅例子

  • feat

    feat(browser): onUrlChange event (popstate/hashchange/polling)
    Added new event to browser:
    - forward popstate event if available
    - forward hashchange event if popstate not available
    - do polling when neither popstate nor hashchange available
    Breaks $browser.onHashChange, which was removed (use onUrlChange instead)
    
  • fix

    fix(compile): couple of unit tests for IE9
    Older IEs serialize html uppercased, but IE9 does not...
    Would be better to expect case insensitive, unfortunately jasmine does
    not allow to user regexps for throw expectations.
    Closes #392
    Breaks foo.bar api, foo.baz should be used instead
    
  • style

    style(location): add couple of missing semi colons
    
  • chore

    chore(release): v3.4.2
    

集成 cz-git 完结标准提交

一款工程性更强,轻量级,高度自定义,标准输出格局的 commitizen 适配器

官方网站:cz-git

从 0 建立 Vite 3 + Vue 3 前端工程化项目

装置依靠

npm install -D cz-git

指定适配器

批改 package.json 文件,增加 config 指定运用的适配器

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

自定义装备(可选)

cz-git 与 commitlint 进行联动给予校验信息,所以能够编写于 commitlint 装备文件之中。

例如:(⇒ 装备模板)

/** @type {import('cz-git').UserConfig} */
module.exports = {
  extends: ['@commitlint/config-conventional'],
  rules: {},
  prompt: {
    useEmoji: false,
    emojiAlign: 'center',
    allowCustomIssuePrefixs: false,
    allowEmptyIssuePrefixs: false,
  },
};

本项目装备文件可参阅:commitlint.config.js

大局运用

大局装置的优点在于:在任何项目下都能够运用 czgit cz 指令发动指令行东西,生成标准化 commit message

装置大局依靠

npm install -g cz-git commitizen

大局装备适配器类型

echo '{ "path": "cz-git" }' > ~/.czrc

自定义装备(可选)

方法一: 修改 ~/.czrc 文件以 json 方法增加装备,例如:

{
  "path": "cz-git",
  "useEmoji": true
}

方法二:与 commitlint 配合,在 $HOME 途径下创立装备文件 (↓ 装备模板)

集成 commitlint 验证标准提交

在“代码标准”章节中提到,虽然拟定了标准,但在多人协作的项目中,总有些人仍旧我行我素。

因此提交代码这个环节,也增加一个限制:只让契合 Angular 标准的 commit message 通过

此功用需借助 @commitlint/config-conventional@commitlint/cli 东西来完结。

装置

  • @commitlint/cli – Commitlint 本体
  • @commitlint/config-conventional – 通用提交标准
npm i @commitlint/cli @commitlint/config-conventional -D

装备

在项目根目录创立 commitlint.config.js 文件,并填入以下内容:

module.exports = {
  extends: ['@commitlint/config-conventional']
}

运用 husky 指令在 .husky 目录下创立 commit-msg 文件,并在此履行验证指令:

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

从 0 建立 Vite 3 + Vue 3 前端工程化项目

本项目完好代码托管在 GitHub 库房,欢迎点亮小星星

主动布置

本章节将介绍怎么运用 CI(Continuous Integration 继续集成)服务来完结项目布置作业。

常见的 CI 东西有 GitHub Actions、GitLab CI、Travis CI、Circle CI 等。

本项目运用 GitHub Actions 来完结这一操作。

参阅链接:GitHub Actions 入门教程

创立 GitHub 库房

由于 GitHub Actions 只对 GitHub 库房有用,所以创立 GitHub 库房来托管项目代码。

从 0 建立 Vite 3 + Vue 3 前端工程化项目

  • master 分支存储项目源代码
  • gh-pages 分支存储打包后的静态文件

创立 GitHub Token

创立一个有 repoworkflow 权限的 GitHub Token

从 0 建立 Vite 3 + Vue 3 前端工程化项目

留意:新生成的 Token 只会显现一次。

从 0 建立 Vite 3 + Vue 3 前端工程化项目

增加 Actions secret

将上述创立的 Token 增加到 GitHub 库房中的 Secrets 里,并将这个新增的 secret 命名为 VITE_VUE_DEPLOY

过程:库房 -> Settings -> Secrets -> Actions -> New repository secret

从 0 建立 Vite 3 + Vue 3 前端工程化项目

留意:新创立的 secret VITE_VUE_DEPLOY 在 Actions 装备文件中要用到,两个当地需保持一致!

批改 package.json

打开 package.json 文件,新增 homepage 字段,表明该使用发布后的根目录(拜见官方文档)。

"homepage": "https://[username].github.io/github-actions-demo",

上面代码中,将 [username] 替换成你的 GitHub 用户名,拜见范例。

创立 Actions 装备文件

(1)在项目根目录下创立 .github 目录。

(2)在 .github 目录下创立 workflows 目录。

(3)在 workflows 目录下创立 deploy.yml 文件。

从 0 建立 Vite 3 + Vue 3 前端工程化项目

name: Vite Vue Deploy
on:
  push:
    # master 分支有 push 时触发
    branches: [master]
jobs:
  deploy:
    # 指定虚拟机环境
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [14.x, 16.x]
    steps:
      - name: Checkout
        # 拉取 GitHub 库房代码
        uses: actions/checkout@v3
      - name: Use Node.js ${{ matrix.node-version }}
        # 设定 Node.js 环境
        uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.node-version }}
      - name: Install
        # 装置依靠
        run: npm install
      - name: Build
        # 打包
        run: npm run build
      - name: Deploy
        uses: JamesIves/github-pages-deploy-action@v4
        with:
          # 布置打包目录
          folder: dist
          # 密钥名
          token: ${{ secrets.VITE_VUE_DEPLOY }}
          # 分支
          branch: gh-pages

通过此链接 ElanYoung.github.io/vite-vue-js… 即可访问本项目

文章总结

本文从技能选项到架构建立、从代码标准束缚到提交信息标准束缚,一步一步带领我们怎么从一个最简单的前端项目骨架到标准的前端工程化环境,根本涵盖前端项目开发的整个流程,特别适合刚触摸前端工程化的同学学习。

因篇幅较长,所触及技能点较多,难免会呈现过错,期望我们多多指正,谢谢我们!

参阅出处

  • XPoet:从 0 开端手把手带你建立一套标准的 Vue3.x 项目工程环境