创建项目 - 使用Vite
Vite 需要 Node.js 版本 >= 12.0.0
使用 Vite 创建项目,运行命令后,根据提示输入项目名,然后选择 vue + ts 即可:
# 使用 NPM:npm init @vitejs/app# 使用 Yarn:yarn create @vitejs/app
也可以在命令行参数中传入 项目名称 和 vue-ts 模板:
# npm 6.xnpm init @vitejs/app my-vue-app --template vue-ts# npm 7+, 需要额外的双横线:npm init @vitejs/app my-vue-app -- --template vue-ts# yarnyarn create @vitejs/app my-vue-app --template vue-ts
更多模板可以查看:
生成的项目模板如下。与 Vue-Cli 项目结构上的区别在于:
- index.html 放在了根目录。
- 配置文件为 vite.config.ts 文件。

运行 yarn 、yarn dev 即可运行项目。
Vite 配置
Vite 的配置文件命名为 vite.config.ts ,存放在项目根目录下。就像Vue-cli的vue.config.js一样。
想要了解所有的配置,可以参考 配置 - Vite 。
resolve.alias - 路径别名
设置 @ 指向 src 文件夹,设置 ~ 指向 assets 文件夹。使用path模块确保路径正确。
import { defineConfig } from "vite";import vue from "@vitejs/plugin-vue";import { resolve } from "path";const pathResolve = (dir: string): string => {return resolve(__dirname, ".", dir);};export default defineConfig({resolve: {alias: {"@": pathResolve("src"),"~": pathResolve("./src/assets")}},plugins: [vue()]});
引入path有可能会遇到 找不到模块“path”或其相应的类型声明。 的报错。
运行 yarn add @types/node ,添加node模块的ts声明即可。
与此同时,记得在 tsconfig.json 文件中也设置路径别名,这样编辑器才能识别并给出语法提示:
顺便给 node_modules 添加exclude属性,不检测node包。
{"compilerOptions": {// ...// 设置解析非相对模块名称的基本目录"baseUrl": ".",// 设置模块名到基于baseUrl的路径映射,可以设置路径别名的语法提示"paths": {"@/*": ["src/*"],"~/*": ["src/assets/*"],},},"exclude": ["node_modules/*"]}
css - 预处理器 Scss
Vite内置支持scss、less、stylus等css预处理器,但是预处理器本身依赖必须安装:
# .scss and .sassyarn add sass -D
现在我们在 assets 文件夹中添加一个 style 文件夹,用来放一些公共的样式文件,以及scss的变量、@mixin声明。我们创建一个 _mixins.scss 和 _vars.scss。
scss的变量、@mixin的声明必须要import到别的scss文件中才能生效。
但是每个文件都引入声明很麻烦,而且声明文件并不会占用代码的大小,因此可以在vite.config.ts中配置每个scss都自动引入这两个声明文件:
// vite.config.tsexport default defineConfig({css: {preprocessorOptions: {scss: {// 给每个scss文件注入var和mixinsadditionalData: `@import "~/style/vars";@import "~/style/mixins";`,},},},})
注意这里引入时,用了alias配置的~路径,且引入的文件省略了 _ 开头和 .scss 结尾。这里的原理是scss预处理器原本就有的机制(scss在引入以 _ 开头的文件时,可省略下划线和.scss后缀)。
Less
安装less和less-loader
# less and less-loaderyarn add less less-loader
less和less-loader要放在package.json文件里的devDependencies里
env - 环境变量与模式
环境变量
我们先在 根目录 下创建三个.env文件
# .env 公用环境变量VITE_TITLE='Vue3项目Title'VITE_TITLE_SUFFIX='Title 后缀'# .env.development 开发环境变量NODE_ENV=developmentVITE_BASE_URL='http://www.baidu.com'# .env.production 生产环境变量NODE_ENV=productionVITE_BASE_URL='https://www.google.com'
注意:所有环境变量都要以 VITE_ 作为前缀,这样Vite才会读取。这样是为了防止污染原本的环境变量。
Vite 使用环境变量的方法有些特殊,不再是使用process.env来访问。
Vite 在一个特殊的 import.meta.env 对象上暴露环境变量。
const title = import.meta.env.VITE_TITLE // Vue3项目Title
TypeScript智能提示(类型定义)
Vite 会默认为 import.meta.env 内建变量提供类型定义。但随着自定义环境变量越来越多,你可能需要在代码编辑时获取对应环境变量的智能提示。
在 src 下创建一个 typings 文件夹,用来放 d.ts 的类型声明。在 typings 中创建 env.d.ts 文件。
// src/typings/env.d.tsinterface ImportMetaEnv {VITE_TITLE: stringVITE_TITLE_SUFFIX: stringVITE_BASE_URL: string// 更多环境变量...}
更多模式
有时你的生产环境可能不止一个。你希望他们打包时可以区别环境变量,但是打包出来的结构、配置又是一样的。假设你现在需要一个 staging 环境。
Vite 打包时,你可以传递 --mode 选项来覆盖命令使用的模式:
vite build --staging
配置到 package.json 中:
// package.json{"scripts": {"dev": "vite","build": "vue-tsc --noEmit && vite build","build-staging": "vue-tsc --noEmit && vite build --staging","serve": "vite preview"},}
现在要给对应模式在 根目录 下创建一个 .env.staging 文件:
# .env.stagingNODE_ENV=productionVITE_BASE_URL='https://www.staging.com'
现在一切都完成了,你既可以按照生产模式打包,也能够区分环境变量了。
注意:NODE_ENV 在生产环境时应始终使用 production 值。
ESLint - 代码检查
安装ESLint及其依赖:
# 安装vue3所需的ts+eslint依赖yarn add eslint eslint-plugin-vue @typescript-eslint/parser @typescript-eslint/eslint-plugin @vue/eslint-config-typescript -D
根目录 下创建 .eslintrc.js 文件,配置ESLint:
// .eslintrc.jsmodule.exports = {extends: [// add more generic rulesets here, such as:'plugin:vue/vue3-recommended','@vue/typescript/recommended',],parser: 'vue-eslint-parser',parserOptions: {parser: '@typescript-eslint/parser',ecmaVersion: 2020,sourceType: 'module',},plugins: ['@typescript-eslint'],rules: {// override/add rules settings here, such as:// 是否禁止非空断言'@typescript-eslint/no-non-null-assertion': ['off'],// 是否禁止非必要且多余的类型声明'@typescript-eslint/no-inferrable-types': ['off'],// 是否禁止require()'@typescript-eslint/no-var-requires': ['off'],// interface声明每行是否必须加分号'@typescript-eslint/member-delimiter-style': ['off'],// 是否禁止any类型'@typescript-eslint/no-explicit-any': ['off'],// 是否禁止空函数出现'@typescript-eslint/no-empty-function': ['warn'],// 关掉避免shims-vue声明报错'@typescript-eslint/ban-types': ['off'],'@typescript-eslint/explicit-module-boundary-types': ['off'],// 是否禁止this赋值别名,仅允许 解构赋值 和 变量名self'@typescript-eslint/no-this-alias': ['error',{allowDestructuring: true, // Allow `const { props, state } = this`; false by defaultallowedNames: ['self', 'that'], // Allow `const self = this`; `const that = this`; `[]` by default},],'vue/no-v-html': ['off'],'vue/no-multiple-template-root': ['off'],},}
rules 模块可以根据自己的习惯、风格等进行修改,具体修改方式自行百度即可。最简单的就是改成off、warn、error,分别代表 关闭、警告、报错。
代码格式化配置
在 根目录 下创建 .prettierrc.js 文件:
// prettierrc.jsmodule.exports = {tabWidth: 2, // 缩进字节数useTabs: false, // 缩进不使用tab,使用空格printWidth: 100, // 超过最大值换行semi: false, // 在每个语句的末尾添加分号singleQuote: true, // 使用单引号而不是双引号trailingComma: 'es5', // 多行时尽可能打印尾随逗号<none|es5|all>bracketSpacing: true, // 对象文字中打印括号之间的空格endOfLine: 'auto', // 对象文字中打印括号之间的空格arrowParens: 'avoid', // 在单个箭头函数参数周围加上括号<avoid|always>jsxBracketSameLine: true,htmlWhitespaceSensitivity: 'css', // 指定HTML文件的全局空格敏感度 <css|strict|ignore>}
VSCode设置vuter插件配置:
// VSCode setting.json{"[vue]": {"editor.defaultFormatter": "octref.vetur"},"vetur.validation.template": false,"vetur.format.defaultFormatter.html": "js-beautify-html",// 格式化插件的配置"vetur.format.options.tabSize": 2,"vetur.format.defaultFormatterOptions": {"js-beautify-html": {// 属性强制折行对齐// "wrap_attributes": "force-aligned""wrap_attributes": "force-expand-multiline"},// ieg公众号配置"prettier": {"tabWidth": 2, // 缩进字节数"useTabs": false, // 缩进不使用tab,使用空格"printWidth": 100, // 超过最大值换行"semi": true, // 在每个语句的末尾添加分号"singleQuote": false, // 使用单引号而不是双引号"trailingComma": "none", // 多行时尽可能打印尾随逗号<none|es5|all>"bracketSpacing": true, // 对象文字中打印括号之间的空格"endOfLine": "auto", // 对象文字中打印括号之间的空格"arrowParens": "always", // 在单个箭头函数参数周围加上括号<avoid|always>"jsxBracketSameLine": true,"htmlWhitespaceSensitivity": "ignore" // HTML文件的空格敏感度 <css|strict|ignore>}},}
项目结构
现在项目已经初步搭建完成了,现在项目结构应该长这样:
