Carmineprince's Blog
首页
    • HTML
    • CSS
    • JavaScript
    • Vue
    • React
    • TypeScript
    • Node
    • Flutter
    • Electron
    • Python
    • 运维
    • 重学前端
  • 分类
  • 标签
  • 归档

Ziqi Wang

胡思乱想程序员
首页
    • HTML
    • CSS
    • JavaScript
    • Vue
    • React
    • TypeScript
    • Node
    • Flutter
    • Electron
    • Python
    • 运维
    • 重学前端
  • 分类
  • 标签
  • 归档
  • 从0开始搭建一套规范的Vue3.x项目工程环境
    • 技术栈
    • 架构搭建
      • 使用Vite快速初始化项目雏形
      • 修改Vite配置文件`vite.config.ts`
      • 规范目录结构
      • 集成路由工具Vue Router
      • 集成状态管理工具Vuex
      • 按需引入UI框架 Element Plus
      • 集成HTTP工具Axios
      • 集成 CSS 预编译器 Stylus/Sass/Less
    • 代码规范(EditorConfig + Prettier + ESLint)
      • 集成 EditorConfig 配置
      • 集成 Prettier 配置
      • 集成 ESLint 配置
  • 解决vite构建vue3项目报错
  • 解决Vue3中无法使用$ref的问题
  • 项目中手动增加scss支持
  • el-table多选分页保留
  • 解决npm run dev启动两个页面问题
  • PC端和移动端兼容方案
  • SFC-Use-script-setup
  • vue2x面试前回炉重造
  • Vue3+Vite2配置
  • flvjs+vue 视频播放(手动追帧、断开重连、多个视频同时直播)
  • vue平滑滚动到指定位置
  • vant项目使用postcss-pxtorem和amfe-flexible 进行移动端适配
  • vue 使用v-html绑定时,内部元素不会继承外部css的解决方案
  • vue-awesome-swiper缩略图控制循环无效解决方案
  • 如何在Vue项目中优雅的使用svg图标
  • yarn报错及解决方案
  • vue3+ts+vite移动端vw适配方案
  • Vue项目中增加mockjs模拟接口请求
  • Nuxt相关

  • Vue3思考及跟Vue2相比的新变化总结
  • Vue相关
carmineprince
2021-10-20

从0开始搭建一套规范的Vue3.x项目工程环境

# 从0开始搭建一套规范的Vue3.x项目工程环境

[TOC]

搭建一套规范的Vite + Vue3 + TypeScript前端工程化项目环境。

本篇将从一下几个方面展开:

  • 架构搭建
  • 代码规范
  • 提交规范

# 技术栈

  • 编程语言:TypeScript 4.x + JavaScript
  • 构建工具:Vite 2.x
  • 前端框架:Vue 3.x
  • 路由工具:Vue Router 4.x
  • 状态管理:Vuex 4.x
  • UI框架:Element Plus / Vant 3.x
  • HTTP工具:Axios
  • Git Hook 工具:husky + lint-staged
  • 代码规范: EditorConfig + Prettier + ESLint + Airbnb JavaScript Style Guide
  • 提交规范:Commitizen + Commitlint

# 架构搭建

请确保你的电脑上成功安装Node.js,本项目使用Vite构建工具,需要Node.js版本>=12.x。

查看Node.js版本:

node -v
1

使用nvm将Node.js升级到最新的稳定版本:

nvm install stable
1

# 使用Vite快速初始化项目雏形

  • NPM:
npm init @vitejs/app
1
  • Yarn
yarn create @vitejs/app
1

然后按照终端提示完成以下操作:

  1. 输入项目名称

image-20210804101316765

  1. 选择模板

    先选择vue

    image-20210804101522523

    再选择vue-ts

image-20210804101607301

还可以通过附加的命令行选项直接指定项目名和模板,本项目要构建 Vite + Vue3 + TypeScript 项目,则运行:

# npm 6.x
npm init @vitejs/app vite-vue3-starter --template vue-ts

# npm 7+(需要额外的双横线)
npm init @vitejs/app vite-vue3-starter -- --template vue-ts

# yarn
yarn create @vitejs/app vite-vue3-starter --template vue-ts

1
2
3
4
5
6
7
8
9
  1. 进入项目安装依赖
  • NPM:
cd xxx
npm install
1
2
  • Yarn:
cd xxx
yarn
1
2
  1. 在项目中使用yarn 2.x版本
yarn set version berry
1

"Berry" 是 Yarn 2 发布序列的代号

  1. 运行项目
  • NPM:
npm run dev
1
  • Yarn:
yarn run dev
1

image-20210804102438468

如上图,表示 Vite + Vue3 + TypeScript 简单的项目骨架搭建完毕,下面我们来为这个项目集成 Vue Router、Vuex、Element Plus、Axios、Stylus/Sass/Less。

# 修改Vite配置文件vite.config.ts

Vite的配置文件vite.config.ts位于根目录下,项目启动时会自动读取```vite.config.ts``的配置信息。

关于 Vite 更多配置项及用法,请查看 Vite 官网 (opens new window)

  • 基础配置(设置 @ 指向 src 目录、 服务启动端口、打包路径、代理等):
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// 如果编辑器提示 path 模块找不到,则可以安装一下 @types/node -> npm i @types/node -D
import { resolve } from 'path'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      '@': resolve(__dirname, 'src') // 设置 `@` 指向 `src` 目录
    }
  },
  base: './', // 设置打包路径
  server: {
    port: 4000, // 设置服务启动端口号
    open: true, // 设置服务启动时是否自动打开浏览器
    cors: true // 允许跨域

    // 设置代理,根据我们项目实际情况配置
    // proxy: {
    //   '/api': {
    //     target: 'http://xxx.xxx.xxx.xxx:8000',
    //     changeOrigin: true,
    //     secure: false,
    //     rewrite: (path) => path.replace('/api/', '/')
    //   }
    // }
  }
})

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
  • 增加了环境变量配置:
import { defineConfig, loadEnv } from 'vite'
import vue from '@vitejs/plugin-vue'
// 如果编辑器提示 path 模块找不到,则可以安装一下 @types/node -> npm i @types/node -D
import { resolve } from 'path'

// https://vitejs.dev/config/
export default ({ mode }) => {
  return defineConfig({
    plugins: [vue()],
    resolve: {
      alias: {
        '@': resolve(__dirname, 'src') // 设置 `@` 指向 `src` 目录
      }
    },
    base: './', // 设置打包路径
    server: {
      host: '0.0.0.0', // 解决项目启动后use `--host` to expose没有将f
      port: 4000, // 设置服务启动端口号
      open: true, // 设置服务启动时是否自动打开浏览器
      cors: true // 允许跨域

      // 设置代理,根据我们项目实际情况配置
      // proxy: {
      //   '/api': {
      //     target: loadEnv(mode, process.cwd()).VITE_APP_WEB_URL,
      //     changeOrigin: true,
      //     secure: false,
      //     rewrite: (path) => path.replace(/^\/api/, '/api')
      //   }
      // }
    }
  })
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

# 规范目录结构

├── publish/
└── src/
    ├── assets/                    // 静态资源目录
    ├── common/                    // 通用类库目录
    ├── components/                // 公共组件目录
    ├── router/                    // 路由配置目录
    ├── store/                     // 状态管理目录
    ├── style/                     // 通用 CSS 目录
    ├── utils/                     // 工具函数目录
    ├── views/                     // 页面组件目录
    ├── App.vue
    ├── main.ts
    ├── shims-vue.d.ts
├── tests/                         // 单元测试目录
├── index.html
├── tsconfig.json                  // TypeScript 配置文件
├── vite.config.ts                 // Vite 配置文件
└── package.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 集成路由工具Vue Router

  1. 安装支持Vue3的路由工具 vue-router@4
  • NPM:
npm i vue-router@4
1
  • Yarn:
yarn add vue-router@4
1
  1. 创建src/router/index.ts 路由配置文件

在 src 下创建 router 目录,然后在 router 目录里新建 index.ts 文件:

 └── src/
     ├── router/
         ├── index.ts  // 路由配置文件
1
2
3

src/router/index.ts:

import {
    createRouter,
    createWebHashHistory,
    RouteRecordRaw
  } from 'vue-router'
  import Home from '@/views/Home/index.vue'
  
  const routes: Array<RouteRecordRaw> = [
    {
      path: '/',
      name: 'Home',
      component: Home
    },
    {
      path: '/about',
      name: 'About',
      component: () => import('@/views/About/index.vue') // 懒加载组件
    }
  ]
  
  const router = createRouter({
    history: createWebHashHistory(),
    routes
  })
  
  export default router
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
  1. 在 main.ts 文件中挂载路由配置
import { createApp } from 'vue'
import App from './App.vue'

import router from './router/index'

createApp(App).use(router).mount('#app')
1
2
3
4
5
6

# 集成状态管理工具Vuex

  1. 安装支持Vue3的状态管理工具vuex@next
  • NPM:
npm i vuex@next
1
  • Yarn:
yarn add vuex@next
1
  1. 创建 src/store/index.ts 文件

在 src 下创建 store 目录,然后在 store 目录里新建 index.ts 文件:

└── src/
    ├── store/
        ├── index.ts  // store 配置文件
1
2
3

src/store/index.ts:

import { createStore } from 'vuex'

const defaultState = {
  count: 0
}

// Create a new store instance.
export default createStore({
  state() {
    return defaultState
  },
  mutations: {
    increment(state: typeof defaultState) {
      state.count += 1
    }
  },
  actions: {
    increment(context) {
      context.commit('increment')
    }
  },
  getters: {
    double(state: typeof defaultState) {
      return 2 * state.count
    }
  }
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
  1. 在 main.ts 文件中挂载 Vuex 配置
import { createApp } from 'vue'
import App from './App.vue'
import router from './router/index'
import store from './store/index'

createApp(App).use(router).use(store).mount('#app')
1
2
3
4
5
6

# 按需引入UI框架 Element Plus

  1. 安装Element Plus
  • NPM:
npm install element-plus --save
1
  • Yarn:
yarn add element-plus
1
  1. 安装 babel-plugin-import

    借助 babel-plugin-import (opens new window),我们可以只引入需要的组件,以达到减小项目体积的目的。

$ npm install vite-plugin-style-import -D
1

​ 或者

$ yarn add vite-plugin-style-import -D
1
  1. 在main.ts中引入 .scss 样式
import 'element-plus/packages/theme-chalk/src/base.scss'
1
  1. 修改vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import styleImport from 'vite-plugin-style-import'

export default defineConfig({
  plugins: [
    vue(),
    styleImport({
      libs: [{
        libraryName: 'element-plus',
        esModule: true,
        ensureStyleFile: true,
        resolveStyle: (name) => {
          const theName = name.slice(3)
          return `element-plus/packages/theme-chalk/src/${theName}.scss`
        },
        resolveComponent: (name) => {
          return `element-plus/lib/${name}`;
        },
      }]
    })
  ]
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
  1. 在main.ts中全局引用组件
import { createApp } from 'vue'
import { ElButton, ElSelect } from 'element-plus';
import App from './App.vue';
// 如果要使用.scss样式文件,则需要引入base.scss文件
// import 'element-plus/packages/theme-chalk/src/base.scss'

const app = createApp(App)
app.component(ElButton.name, ElButton);
app.component(ElSelect.name, ElSelect);

/* or
 * app.use(ElButton)
 * app.use(ElSelect)
 */

app.mount('#app')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
  1. 在页面内单独引用组件
<template>
	<el-button>test</el-button>
</template>
<script lang="ts">
    import { defineComponent } from 'vue'
    import { ElButton } from 'element-plus'
    export default defineComponent({
        components: {
            [ElButton.name]:ElButton
        }
    })
</script>
1
2
3
4
5
6
7
8
9
10
11
12

# 集成HTTP工具Axios

  1. 安装Axios (Axios跟Vue的版本没有直接关系,安装最新版本即可)
  • NPM:
npm i axios
1
  • Yarn:
yarn add axios
1
  1. 配置Axios

为了使项目的目录结构合理且规范,我们在src下创建utils目录来存储我们常用的工具函数

Axios作为HTTP工具,我们在utils目录下创建request.ts作为Axios配置文件:

└── src/
    ├── utils/
        ├── request.ts  // Axios 配置文件
1
2
3
import Axios from 'axios'
import { ElMessage } from 'element-plus'

// 如果是开发环境不设置baseUrl使用代理处理跨域,
const baseURL =
  <string>import.meta.env.MODE === 'development' ? '' : <string>import.meta.env.VITE_APP_WEB_URL

const axios = Axios.create({
  baseURL,
  timeout: 20000 // 请求超时 20s
})

// 前置拦截器(发起请求之前的拦截)
axios.interceptors.request.use(
  (response) => {
    /**
     * 根据你的项目实际情况来对 config 做处理
     * 这里对 config 不做任何处理,直接返回
     */
    return response
  },
  (error) => {
    return Promise.reject(error)
  }
)

// 后置拦截器(获取到响应时的拦截)
axios.interceptors.response.use(
  (response) => {
    /**
     * 根据你的项目实际情况来对 response 和 error 做处理
     * 这里对 response 和 error 不做任何处理,直接返回
     */
    return response
  },
  (error) => {
    if (error.response && error.response.data) {
      const code = error.response.status
      const msg = error.response.data.message
      ElMessage.error(`Code: ${code}, Message: ${msg}`)
      console.error(`[Axios Error]`, error.response)
    } else {
      ElMessage.error(`${error}`)
    }
    return Promise.reject(error)
  }
)

export default axios
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
  1. 使用Axios
<template></template>
<script lang="ts">
  import { defineComponent } from 'vue'
  import request from '../utils/axios'

  export default defineComponent({
    setup() {
      request
        .get('/users/XPoet')
        .then((res) => {
          console.log('res: ', res)
        })
        .catch((err) => {
          console.log('err: ', err)
        })
    }
  })
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 集成 CSS 预编译器 Stylus/Sass/Less

  1. 安装
  • NPM:
npm i stylus -D
npm i sass -D
npm i less -D
1
2
3
  • Yarn:
yarn add stylus --dev
yarn add sass --dev
yarn add less --dev
1
2
3
  1. 使用
<style lang="scss">
  ...
</style>
1
2
3

# 代码规范(EditorConfig + Prettier + ESLint)

# 集成 EditorConfig 配置

EditorConfig 有助于为不同 IDE 编辑器上处理同一项目的多个开发人员维护一致的编码风格。

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

# Editor configuration, see http://editorconfig.org

# 表示是最顶层的 EditorConfig 配置文件
root = true

[*] # 表示所有文件适用
charset = utf-8 # 设置文件字符集为 utf-8
indent_style = space # 缩进风格(tab | space)
indent_size = 2 # 缩进大小
end_of_line = lf # 控制换行类型(lf | cr | crlf)
trim_trailing_whitespace = true # 去除行首的任意空白字符
insert_final_newline = true # 始终在文件末尾插入一个新行

[*.md] # 表示仅 md 文件适用以下规则
max_line_length = off
trim_trailing_whitespace = false
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# 集成 Prettier 配置

Prettier 是一款强大的代码格式化工具,支持 JavaScript、TypeScript、CSS、SCSS、Less、JSX、Angular、Vue、GraphQL、JSON、Markdown 等语言,基本上前端能用到的文件格式它都可以搞定,是当下最流行的代码格式化工具。

  1. 安装 Prettier
  • NPM:
npm i prettier -D
1
  • Yarn:
yarn add prettier --dev
1
  1. 创建 Prettier 配置文件.prettierrc
{
  "useTabs": false,
  "tabWidth": 2,
  "printWidth": 100,
  "singleQuote": true,
  "trailingComma": "none",
  "bracketSpacing": true,
  "semi": false
}
1
2
3
4
5
6
7
8
9
  1. Prettier 安装且配置好之后,就能使用命令来格式化代码
# 格式化所有文件(. 表示所有文件)

1
2

# 集成 ESLint 配置

ESLint (opens new window) 是一款用于查找并报告代码中问题的工具,并且支持部分问题自动修复。其核心是通过对代码解析得到的 AST(Abstract Syntax Tree 抽象语法树)进行模式匹配,来分析代码达到检查代码质量和风格问题的能力。

  1. 安装 ESLint(推荐只在当前项目中安装)
  • NPM:
npm i eslint -D
1
  • Yarn:
yarn add eslint --dev
1
  1. 配置 ESLint

ESLint 安装成功后,执行 npx eslint --init,然后按照终端操作提示完成一系列设置来创建配置文件。

  • How would you like to use ESLint?(你想如何使用 ESLint?)
#项目搭建#vue3
上次更新: 10/21/2021, 1:52:09 PM
解决vite构建vue3项目报错

解决vite构建vue3项目报错→

最近更新
01
pc端rem配置
03-02
02
使用动态变量ts报错的解决
02-25
03
React Hook详解
02-18
更多文章>
Theme by Vdoing | Copyright © 2021-2022 Carmineprince | 鲁ICP备2021046263号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式