创建项目 - 使用Vite

Vite 需要 Node.js 版本 >= 12.0.0

使用 Vite 创建项目,运行命令后,根据提示输入项目名,然后选择 vue + ts 即可:

  1. # 使用 NPM:
  2. npm init @vitejs/app
  3. # 使用 Yarn:
  4. yarn create @vitejs/app

也可以在命令行参数中传入 项目名称 和 vue-ts 模板:

  1. # npm 6.x
  2. npm init @vitejs/app my-vue-app --template vue-ts
  3. # npm 7+, 需要额外的双横线:
  4. npm init @vitejs/app my-vue-app -- --template vue-ts
  5. # yarn
  6. yarn create @vitejs/app my-vue-app --template vue-ts

更多模板可以查看:

生成的项目模板如下。与 Vue-Cli 项目结构上的区别在于:

  • index.html 放在了根目录。
  • 配置文件为 vite.config.ts 文件。

image.png

运行 yarnyarn dev 即可运行项目。

Vite 配置

Vite 的配置文件命名为 vite.config.ts ,存放在项目根目录下。就像Vue-cli的vue.config.js一样。
想要了解所有的配置,可以参考 配置 - Vite

resolve.alias - 路径别名

设置 @ 指向 src 文件夹,设置 ~ 指向 assets 文件夹。使用path模块确保路径正确。

  1. import { defineConfig } from "vite";
  2. import vue from "@vitejs/plugin-vue";
  3. import { resolve } from "path";
  4. const pathResolve = (dir: string): string => {
  5. return resolve(__dirname, ".", dir);
  6. };
  7. export default defineConfig({
  8. resolve: {
  9. alias: {
  10. "@": pathResolve("src"),
  11. "~": pathResolve("./src/assets")
  12. }
  13. },
  14. plugins: [vue()]
  15. });

引入path有可能会遇到 找不到模块“path”或其相应的类型声明。 的报错。
运行 yarn add @types/node ,添加node模块的ts声明即可。

与此同时,记得在 tsconfig.json 文件中也设置路径别名,这样编辑器才能识别并给出语法提示:
顺便给 node_modules 添加exclude属性,不检测node包。

  1. {
  2. "compilerOptions": {
  3. // ...
  4. // 设置解析非相对模块名称的基本目录
  5. "baseUrl": ".",
  6. // 设置模块名到基于baseUrl的路径映射,可以设置路径别名的语法提示
  7. "paths": {
  8. "@/*": ["src/*"],
  9. "~/*": ["src/assets/*"],
  10. },
  11. },
  12. "exclude": ["node_modules/*"]
  13. }

css - 预处理器 Scss

Vite内置支持scss、less、stylus等css预处理器,但是预处理器本身依赖必须安装:

  1. # .scss and .sass
  2. yarn add sass -D

现在我们在 assets 文件夹中添加一个 style 文件夹,用来放一些公共的样式文件,以及scss的变量、@mixin声明。我们创建一个 _mixins.scss_vars.scss
image.png
scss的变量、@mixin的声明必须要import到别的scss文件中才能生效。
但是每个文件都引入声明很麻烦,而且声明文件并不会占用代码的大小,因此可以在vite.config.ts中配置每个scss都自动引入这两个声明文件:

  1. // vite.config.ts
  2. export default defineConfig({
  3. css: {
  4. preprocessorOptions: {
  5. scss: {
  6. // 给每个scss文件注入var和mixins
  7. additionalData: `@import "~/style/vars";@import "~/style/mixins";`,
  8. },
  9. },
  10. },
  11. })

注意这里引入时,用了alias配置的~路径,且引入的文件省略了 _ 开头和 .scss 结尾。这里的原理是scss预处理器原本就有的机制(scss在引入以 _ 开头的文件时,可省略下划线和.scss后缀)。

Less

安装less和less-loader

  1. # less and less-loader
  2. yarn add less less-loader

less和less-loader要放在package.json文件里的devDependencies里

env - 环境变量与模式

Vite自动读取.env的环境变量,只是读取方式有些差异。

环境变量

我们先在 根目录 下创建三个.env文件

  1. # .env 公用环境变量
  2. VITE_TITLE='Vue3项目Title'
  3. VITE_TITLE_SUFFIX='Title 后缀'
  4. # .env.development 开发环境变量
  5. NODE_ENV=development
  6. VITE_BASE_URL='http://www.baidu.com'
  7. # .env.production 生产环境变量
  8. NODE_ENV=production
  9. VITE_BASE_URL='https://www.google.com'

注意:所有环境变量都要以 VITE_ 作为前缀,这样Vite才会读取。这样是为了防止污染原本的环境变量。

Vite 使用环境变量的方法有些特殊,不再是使用process.env来访问。
Vite 在一个特殊的 import.meta.env 对象上暴露环境变量。

  1. const title = import.meta.env.VITE_TITLE // Vue3项目Title

TypeScript智能提示(类型定义)

Vite 会默认为 import.meta.env 内建变量提供类型定义。但随着自定义环境变量越来越多,你可能需要在代码编辑时获取对应环境变量的智能提示。
src 下创建一个 typings 文件夹,用来放 d.ts 的类型声明。在 typings 中创建 env.d.ts 文件。

  1. // src/typings/env.d.ts
  2. interface ImportMetaEnv {
  3. VITE_TITLE: string
  4. VITE_TITLE_SUFFIX: string
  5. VITE_BASE_URL: string
  6. // 更多环境变量...
  7. }

现在你就可以获取到新增的环境变量对应的语法提示了
image.png

更多模式

有时你的生产环境可能不止一个。你希望他们打包时可以区别环境变量,但是打包出来的结构、配置又是一样的。假设你现在需要一个 staging 环境。

Vite 打包时,你可以传递 --mode 选项来覆盖命令使用的模式:

  1. vite build --staging

配置到 package.json 中:

  1. // package.json
  2. {
  3. "scripts": {
  4. "dev": "vite",
  5. "build": "vue-tsc --noEmit && vite build",
  6. "build-staging": "vue-tsc --noEmit && vite build --staging",
  7. "serve": "vite preview"
  8. },
  9. }

现在要给对应模式在 根目录 下创建一个 .env.staging 文件:

  1. # .env.staging
  2. NODE_ENV=production
  3. VITE_BASE_URL='https://www.staging.com'

现在一切都完成了,你既可以按照生产模式打包,也能够区分环境变量了。
注意:
NODE_ENV 在生产环境时应始终使用 production 值。

ESLint - 代码检查

安装ESLint及其依赖:

  1. # 安装vue3所需的ts+eslint依赖
  2. yarn add eslint eslint-plugin-vue @typescript-eslint/parser @typescript-eslint/eslint-plugin @vue/eslint-config-typescript -D

根目录 下创建 .eslintrc.js 文件,配置ESLint:

  1. // .eslintrc.js
  2. module.exports = {
  3. extends: [
  4. // add more generic rulesets here, such as:
  5. 'plugin:vue/vue3-recommended',
  6. '@vue/typescript/recommended',
  7. ],
  8. parser: 'vue-eslint-parser',
  9. parserOptions: {
  10. parser: '@typescript-eslint/parser',
  11. ecmaVersion: 2020,
  12. sourceType: 'module',
  13. },
  14. plugins: ['@typescript-eslint'],
  15. rules: {
  16. // override/add rules settings here, such as:
  17. // 是否禁止非空断言
  18. '@typescript-eslint/no-non-null-assertion': ['off'],
  19. // 是否禁止非必要且多余的类型声明
  20. '@typescript-eslint/no-inferrable-types': ['off'],
  21. // 是否禁止require()
  22. '@typescript-eslint/no-var-requires': ['off'],
  23. // interface声明每行是否必须加分号
  24. '@typescript-eslint/member-delimiter-style': ['off'],
  25. // 是否禁止any类型
  26. '@typescript-eslint/no-explicit-any': ['off'],
  27. // 是否禁止空函数出现
  28. '@typescript-eslint/no-empty-function': ['warn'],
  29. // 关掉避免shims-vue声明报错
  30. '@typescript-eslint/ban-types': ['off'],
  31. '@typescript-eslint/explicit-module-boundary-types': ['off'],
  32. // 是否禁止this赋值别名,仅允许 解构赋值 和 变量名self
  33. '@typescript-eslint/no-this-alias': [
  34. 'error',
  35. {
  36. allowDestructuring: true, // Allow `const { props, state } = this`; false by default
  37. allowedNames: ['self', 'that'], // Allow `const self = this`; `const that = this`; `[]` by default
  38. },
  39. ],
  40. 'vue/no-v-html': ['off'],
  41. 'vue/no-multiple-template-root': ['off'],
  42. },
  43. }

rules 模块可以根据自己的习惯、风格等进行修改,具体修改方式自行百度即可。最简单的就是改成off、warn、error,分别代表 关闭、警告、报错。

代码格式化配置

根目录 下创建 .prettierrc.js 文件:

  1. // prettierrc.js
  2. module.exports = {
  3. tabWidth: 2, // 缩进字节数
  4. useTabs: false, // 缩进不使用tab,使用空格
  5. printWidth: 100, // 超过最大值换行
  6. semi: false, // 在每个语句的末尾添加分号
  7. singleQuote: true, // 使用单引号而不是双引号
  8. trailingComma: 'es5', // 多行时尽可能打印尾随逗号<none|es5|all>
  9. bracketSpacing: true, // 对象文字中打印括号之间的空格
  10. endOfLine: 'auto', // 对象文字中打印括号之间的空格
  11. arrowParens: 'avoid', // 在单个箭头函数参数周围加上括号<avoid|always>
  12. jsxBracketSameLine: true,
  13. htmlWhitespaceSensitivity: 'css', // 指定HTML文件的全局空格敏感度 <css|strict|ignore>
  14. }

VSCode设置vuter插件配置:

  1. // VSCode setting.json
  2. {
  3. "[vue]": {
  4. "editor.defaultFormatter": "octref.vetur"
  5. },
  6. "vetur.validation.template": false,
  7. "vetur.format.defaultFormatter.html": "js-beautify-html",
  8. // 格式化插件的配置
  9. "vetur.format.options.tabSize": 2,
  10. "vetur.format.defaultFormatterOptions": {
  11. "js-beautify-html": {
  12. // 属性强制折行对齐
  13. // "wrap_attributes": "force-aligned"
  14. "wrap_attributes": "force-expand-multiline"
  15. },
  16. // ieg公众号配置
  17. "prettier": {
  18. "tabWidth": 2, // 缩进字节数
  19. "useTabs": false, // 缩进不使用tab,使用空格
  20. "printWidth": 100, // 超过最大值换行
  21. "semi": true, // 在每个语句的末尾添加分号
  22. "singleQuote": false, // 使用单引号而不是双引号
  23. "trailingComma": "none", // 多行时尽可能打印尾随逗号<none|es5|all>
  24. "bracketSpacing": true, // 对象文字中打印括号之间的空格
  25. "endOfLine": "auto", // 对象文字中打印括号之间的空格
  26. "arrowParens": "always", // 在单个箭头函数参数周围加上括号<avoid|always>
  27. "jsxBracketSameLine": true,
  28. "htmlWhitespaceSensitivity": "ignore" // HTML文件的空格敏感度 <css|strict|ignore>
  29. }
  30. },
  31. }

项目结构

现在项目已经初步搭建完成了,现在项目结构应该长这样:
image.png