创建项目 - 使用Vite
Vite 需要 Node.js 版本 >= 12.0.0
使用 Vite 创建项目,运行命令后,根据提示输入项目名,然后选择 vue + ts 即可:
# 使用 NPM:
npm init @vitejs/app
# 使用 Yarn:
yarn create @vitejs/app
也可以在命令行参数中传入 项目名称 和 vue-ts 模板:
# npm 6.x
npm init @vitejs/app my-vue-app --template vue-ts
# npm 7+, 需要额外的双横线:
npm init @vitejs/app my-vue-app -- --template vue-ts
# yarn
yarn 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 .sass
yarn add sass -D
现在我们在 assets
文件夹中添加一个 style
文件夹,用来放一些公共的样式文件,以及scss的变量、@mixin声明。我们创建一个 _mixins.scss
和 _vars.scss
。
scss的变量、@mixin的声明必须要import到别的scss文件中才能生效。
但是每个文件都引入声明很麻烦,而且声明文件并不会占用代码的大小,因此可以在vite.config.ts中配置每个scss都自动引入这两个声明文件:
// vite.config.ts
export default defineConfig({
css: {
preprocessorOptions: {
scss: {
// 给每个scss文件注入var和mixins
additionalData: `@import "~/style/vars";@import "~/style/mixins";`,
},
},
},
})
注意这里引入时,用了alias配置的~路径,且引入的文件省略了 _
开头和 .scss
结尾。这里的原理是scss预处理器原本就有的机制(scss在引入以 _
开头的文件时,可省略下划线和.scss后缀)。
Less
安装less和less-loader
# less and less-loader
yarn 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=development
VITE_BASE_URL='http://www.baidu.com'
# .env.production 生产环境变量
NODE_ENV=production
VITE_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.ts
interface ImportMetaEnv {
VITE_TITLE: string
VITE_TITLE_SUFFIX: string
VITE_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.staging
NODE_ENV=production
VITE_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.js
module.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 default
allowedNames: ['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.js
module.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>
}
},
}
项目结构
现在项目已经初步搭建完成了,现在项目结构应该长这样: