本文主要是介绍Vue3+Vite+Ts 项目实战 01 Vite 创建项目、ESLint+TS+GitCommit配置、Vue3新特性介绍,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
前置声明:
- Vue3 和 Vite 还在持续更新,中文文档仍未全部完善,该笔记的内容在未来可能过时,建议多参考英文文档,使用最新版本。
- 本案例使用的后端 API 服务,基于 Express 搭建,使用 json 文件管理数据,Git 仓库和使用文档。
- 本案例旨在学习 Vite 和 Vue3 搭建配置应用,并没有开发完整的业务功能。
项目初始化
使用 Vite 创建项目
Vite 官方中文文档 (vitejs.dev)
官方声明:Vite 需要 Node.js 版本 >= 12.0.0。然而,有些模板需要依赖更高的 Node 版本才能正常运行,当你的包管理器发出警告时,请注意升级你的 Node 版本。
本例使用时 Node.js 12 版本执行 build 命令报错,于是改用 Node.js 16 版本,切换版本记得重新
npm install
避免有依赖没有更新。
# 创建
npm init vite@latest
√ Project name: ... shop-admin # 项目名称
√ Select a framework: » vue # 选择框架
√ Select a variant: » vue-ts # 选择 vue 或 vue-tscd ./shop-admin
git init
npm install
npm run dev
访问 http://localhost:3000/
初始目录结构说明
├─ public # 存放不需要编译构建的静态资源
│ └─ favicon.ico
├─ src # 存放需要编译构建的文件
│ ├─ assets
│ │ └─ logo.png # 需要编译构建的静态资源
│ ├─ components
│ │ └─ HelloWorld.vue
│ ├─ App.vue
│ ├─ env.d.ts # ts 类型声明
│ └─ main.ts # 启动入口文件
├─ .gitignore # git 忽略文件
├─ index.html # 单页文件的模板文件
├─ package-lock.json
├─ package.json
├─ README.md
├─ tsconfig.json # ts 配置文件
├─ tsconfig.node.json
└─ vite.config.ts # vite 配置文件
package.json
:
{"scripts": {// 启动开发服务器"dev": "vite",// 构建生产环境产物:校验 ts 类型,通过后执行 vite 打包命令"build": "vue-tsc --noEmit && vite build",// 本地预览生产构建产物:以前需要将打包文件配置到 nginx 等服务器中才能预览,vite 简化了这个流程"preview": "vite preview"},
}
关于构建失败的原因
本笔记编写时,运行 npm run build
会报大量错误:
Cannot access ambient const enums when the '--isolatedModules' flag is provided.
原因是 Vite 官方建议配置 TypeScript 的编译器选项:isolatedModules 为 true
。
{"compilerOptions": {"target": "esnext","useDefineForClassFields": true,"module": "esnext","moduleResolution": "node","strict": true,"jsx": "preserve","sourceMap": true,"resolveJsonModule": true,// "isolatedModules": true,"esModuleInterop": true,"lib": ["esnext", "dom"]},"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],"references": [{ "path": "./tsconfig.node.json" }]
}
由于这个导致的编译报错,Issue 并没有得到解决,暂时只能先将其设置为 false
或删除这个选项。
添加自定义目录结构
在 src
目录下添加一些文件夹:
├─ api # API 接口封装
├─ styles # 全局样式
├─ utils # 工具模块
├─ plugins # 插件
├─ views # 路由页面
├─ router # 路由模块
├─ store # vuex 容器模块
├─ layout # 公共布局组件
└─ composables # 项目中提取出来的组合式 API 函数模块
代码规范和 ESLint
在 Vite 创建的项目中默认没有集成 ESLint,并且目前官方也没有任何和 ESLint 相关的内容,所以需要手动集成配置 ESLint。
基础配置
# 安装 eslint(当前版本 8.5.0)
npm i eslint -D
# 初始化 eslint 配置文件
npm init @eslint/config# 如何使用 ESLint
? How would you like to use ESLint? ...
# 检查语法 找到问题 强制代码规范
> To check syntax, find problems, and enforce code style
# 项目中使用的 JS 模块规范
√ What type of modules does your project use? · esm
# 前端框架
√ Which framework does your project use? · vue
# 是否使用 TS
√ Does your project use TypeScript? · No / Yes
# 代码运行环境
√ Where does your code run? · browser
# 代码规范
? How would you like to define a style for your project? ...
# 使用一个流行的代码规范
> Use a popular style guide
> Standard: https://github.com/standard/standard
# 配置文件生成 js 类型的文件
√ What format do you want your config file to be in? · JavaScript
# ...
生成的 eslint 配置文件:
// .eslintrc.js
module.exports = {env: {browser: true,es2021: true},extends: ['plugin:vue/essential','standard'],parserOptions: {ecmaVersion: 'latest',parser: '@typescript-eslint/parser',sourceType: 'module'},plugins: ['vue','@typescript-eslint'],rules: {}
}
本人基于个人习惯,修改了两条规则:
rules: {// 要求或禁止函数圆括号之前有一个空格'space-before-function-paren': [2, {anonymous: 'always',named: 'never',asyncArrow: 'always'}],// 要求组件名(文件名)必须是多单词的'vue/multi-word-component-names': 0
}
package.json
中添加验证脚本:
"scripts": {...// 检查代码和自动修复"lint": "eslint src/**/*.{js,jsx,vue,ts,tsx} --fix"
},
npm run lint
运行 eslint 验证:
# App.vue 和 components/HelloWorld.vue 验证失败,template 只能包含一个根节点
error The template root requires exactly one element vue/no-multiple-template-root
这个规则适用于 Vue 2,Vue 3 没有这个限制。查看 eslint 配置文件中使用的插件 plugin:vue/assential
,来自 eslint-plugin-vue
包,查看 eslint-plugin-vue\lib
目录(官方介绍):
├─ base.js
├─ essential.js # 当前配置的验证规则
├─ no-layout-rules.js
├─ recommended.js
├─ strongly-recommended.js
# 以上是 Vue2 的验证规则
# 以下是 Vue3 的验证规则
├─ vue3-essential.js
├─ vue3-recommended.js
└─ vue3-strongly-recommended.js
将 eslint 配置为 Vue 3 的验证规则(本文使用最严格的):
// .eslintrc.js
module.exports = {...extends: [// 'plugin:vue/essential',// 使用 vue3 规则'plugin:vue/vue3-strongly-recommended','standard'],...
}
编译宏和 defineProps、defineEmits、no-undef 规则警告
再次运行 npm run lint
:
# HelloWorld.vue 报错
error 'defineProps' is not defined no-undef
defineProps
和 defineEmits
是 Vue3 定义的编译宏(compiler macros),只能在 <script setup>
中(最外层)使用,它们不需要导入,在处理 <script setup>
会被编译掉。
但在 eslint 检查的时候被当作未被定义的变量报错,可以显示的在文件中导入:
import { defineProps, defineEmits } from 'vue'
或将它们声明为 eslint 检查时的全局变量:
// .eslintrc.js
module.exports = {globals: {defineProps: "readonly",defineEmits: "readonly",defineExpose: "readonly",withDefaults: "readonly"},...
}
也可以使用 eslint-plugin-vue 官方解决办法(源码与上面配置全局变量一样):
// .eslintrc.js
module.exports = {env: {browser: true,es2021: true,// 添加:'vue/setup-compiler-macros': true},...
}
如果 vscode 报错Environment key "vue/setup-compiler-macros" is unknown
,请检查 eslint-plugin-vue
下是否有这个规则,如果没有则可能版本太老,可以更新版本(本文安装的版本是8.5.0)。
再次运行 npm run lint
,没有报错了。
编辑器集成
编辑器集成主要实现两个功能:
- 如何看到不符合规范的错误提示
- 如何按照项目中的 ESLint 规则要求进行格式化
实现步骤:
1、卸载/禁用 vetur 插件(Vue2 插件)
2、安装 volar 插件(Vue Language Features - 相当于支持 Vue3 的 vetur,且支持 TypeScript 提示)
3、安装 ESLint 插件
只要安装并启用了这个插件,就会自动查找项目中的 eslint 配置规范,并给出验证提示。
同时 ESLint 插件提供了格式化工具,但是需要手动配置才可以,打开文件-首选项-设置(快捷键 Ctrl+,
),找到扩展-ESLint,勾选 Format: Enable
,启用 ESLint 格式化工具:
也可以直接修改 vscode 的 settings.json
,添加 "eslint.format.enable": true
。
然后继续配置 eslint.validate
选项指定 eslint 可以检查的文件类型(默认只检查 .js
和 .jsx
文件):
{"eslint.format.enable": true,"eslint.validate": ["javascript","javascriptreact","typescript","vue"],...
}
接着将文件格式化工具选为 ESLint,打开要格式化的文件,右键代码视图-使用…格式化文档-配置默认格式化程序…,选择 ESLint。
配置完成后,就可以使用 Alt+Shift+F
格式化文档了。
PS:安装、启用 ESLint 插件,修改配置文件,都会重新向 IDE 注册,可能会导致延迟甚至不显示,最好改动之后重载一下:
Ctrl+P
,键入>reload
配置 git pre-commit hook
配置 pre-commit 钩子,将 lint 命令加入到开发构建流程,在 git 提交之前执行 lint 验证,防止不符合规范的代码提交到 git 仓库。
使用工具:okonet/lint-staged
npx mrm@2 lint-staged
# 会安装两个 npm 包
# husky - 提供 git 钩子功能,拦截 git 命令
# lint-staged - 获取 git 暂存区中的代码进行lint验证
执行完成后,会修改 package.json
:
1、安装了两个 npm 包
- husky - 提供 git 钩子功能
- lint-staged - 获取 git 暂存区中的代码进行lint验证
2、添加一个脚本
安装依赖后执行 prepare,执行 huskey 命令,安装钩子,确保每个 clone 项目的人一旦安装依赖就会将 husky 钩子初始化到本地,从而保证每个人在提交 git 之前都能执行 lint 验证。
npx mrm@2 lint-staged
执行完成后也会执行husky install
,所以要在.git
所在目录下执行,否则会报错找不到.git
。
husky install
会初始化 husky 的钩子:
- 通过配置
.git/config
中的hooksPath
修改 hooks 目录(默认.git/hooks
)- 在项目根目录下创建
.husky
文件夹,用于存放自定义钩子执行文件
"scripts": {..."prepare": "husky install"
},
3、添加了 lint-staged 配置
可以在此基础上修改,自定义自己的 lint 命令:
"lint-staged": {// 执行 eslint 命令验证 js 文件"*.js": "eslint --cache --fix"
}
修改为:
"lint-staged": {// 提交指定文件时执行 lint 脚本进行验证,如果有 fix 修复的内容会自动 git add"*.{js,jsx,vue,ts,tsx}": ["npm run lint"]
}
现在执行 git commit
命令时,会先进行 lint 检查暂存区的代码,如果有代码不符合规范,则不会执行 git commit
。
注意:保证团队都会执行 pre-commit 钩子的前提是:
- 执行
husky install
初始化.husky
文件夹和配置 git hooks 目录地址- 项目包含
.husky/pre-commit
钩子执行文件,所以要确保这个文件会提交到 git 仓库
在开发和构建时进行代码规范校验
其实就是将 ESLint 集成到 vite 开发的编译构建过程中,以提供实时的 ESLint 验证。
当前 Vite 还没有提供 ESLint 相关的插件,可以自己开发一个插件,也可以使用别人开发好的。
官网导航 Links - Awesome Vite 列出了一些 Vite 相关的优质资源,推荐使用 gxmari007/vite-plugin-eslint
# 安装
npm install vite-plugin-eslint --save-dev
vite 配置文件中加载插件:
// vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import eslintPlugin from 'vite-plugin-eslint'// https://vitejs.dev/config/
export default defineConfig({plugins: [vue(),eslintPlugin({/* 配置选项 */// 禁用 eslint 缓存cache: false})]
})
cache
缓存功能建议关掉,因为有时将验证失败的代码修复后,eslint 可能仍会读取缓存中的结果,而且 eslint 只会验证当前修改的文件,而不是全部文件,所以不使用缓存影响不大。
重新启动 npm run dev
。
现在开发阶段的编译构建代码时,命令行工具和页面都会验证并提示失败信息。而且在构建生产环境时(npm run build
)也会验证。
Git Commit 规范
提交规范介绍
参考:Commit message 和 Change log 编写指南 - 阮一峰
Git 每次提交代码,都要写 Commit message 说明本次提交的具体含义。
git commit -m 'hello world'
Git 本身并没有要求 Commit message 的格式,如果随意编写,当有一天你需要在历史记录中通过 Commit message 检索历史中的一次提交记录,就会很麻烦。
统一团队 Git Commit message 标准,便于后续代码 review,版本发布以及日志自动化生成等等,详细参阅阮一峰的文章。
目前最流行的是 Angular提交规范
相关工具:
- 撰写工具(commitizen) - 帮助编写符合规范的 Commit message。(当习惯规范后就不需要这个工具了)
- 验证工具(commitlint) - 配置 git hooks,在提交前使用工具验证 Commit message 是否符合规范
- 日志生成工具(conventional-changelog) - 通过 git 元数据生成日志,一般开源项目会使用
配置 commitlint 验证工具
# windows 下安装 cli 和 常用规范
npm install --save-dev @commitlint/config-conventional @commitlint/cli
# 配置 commitlint 使用常用规范
# 建议手动创建 commitlint.config.js 文件并填充内容,命令可能创建的并不是 utf8 编码的文件,eslint 会报错 `Parsing error: Invalid character`
echo "module.exports = {extends: ['@commitlint/config-conventional']}" > commitlint.config.js# 安装和初始化 husky(上面配置 eslint 校验钩子时已经完成)
# npm i husky -D
# npx husky install# 创建 commit-msg 钩子
npx husky add .husky/commit-msg 'npx --no -- commitlint --edit "$1"'
如果使用命令无法创建 ./husky/commit-msg
文件,可以手动创建并填充以下内容:
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"npx --no -- commitlint --edit $1
执行提交命令测试:
git add .
git commit -m 'commitlint 配置巴拉巴拉巴拉'
验证失败:
规范 message:
git commit -m 'chore: commitlint 配置巴拉巴拉巴拉'
验证成功:
Vite 中的 TS 环境说明
Vite 在创建项目时已经配置好了 TypeScript 环境,详细参考官方文档。
下面列出需要注意的几点。
TypeScript 类型检查
Vite 仅执行 .ts
文件的转译工作,并 不 执行任何类型检查。
let count: number = 100
count = 200
// 不会报错
count = 'hello'
dev
开发阶段,Vite 假设 IDE 配置了类型检查功能,Vite 本身不负责这个任务。build
构建阶段,会通过vue-tsc --noEmit
命令进行类型检查
由于官方 vue-tsc(使用 esbuild 将 TypeScript 转译到 JavaScript)还不支持监听功能,所以暂时没有很好的插件支持开发阶段进行实时类型验证。
类型声明
Vite 创建项目时会生成一个 src/env.d.ts
类型声明文件(之前的版本是两个文件 shimes-vue.d.ts
和 vite-env.d.ts
):
/// <reference types="vite/client" />declare module '*.vue' {import type { DefineComponent } from 'vue'// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-typesconst component: DefineComponent<{}, {}, any>export default component
}
第一行用于添加客户端代码环境中的类型声明,为了保险起见,建议按照官方说明,将 vite/client
添加到 tsconfig
中的 compilerOptions.types
下:
{"compilerOptions": {"types": ["vite/client"]}
}
后面的内容是为 .vue
资源文件添加类型声明,因为 TypeScript 默认不识别 .vue
文件,所以在使用 TypeScript 的项目中导入 Vue 组件,必须在后面加上 .vue
后缀。
Vue 3 中的 TS 支持
Vue 官方文档《搭配 TypeScript 使用 Vue》中介绍了如何将 TypeScript 集成到项目中、推荐配置等一些 Vite 创建项目时已经完成的内容,下面提取几个关于 TS 使用的部分。
1、在单文件组件中使用 TypeScript,需要在 <script>
标签上加上 lang="ts"
属性。如果使用 JSX 则添加 lang="tsx"
。
2、为了让 TypeScript 正确地推导出组件选项内的类型,我们需要通过 defineComponent()
这个全局 API 来定义组件。
import { defineComponent } from 'vue'export default defineComponent({// 启用了类型推导props: {name: String,msg: { type: String, required: true }},data() {return {count: 1}},mounted() {this.name // 类型:string | undefinedthis.msg // 类型:stringthis.count // 类型:number}
})
3、当没有结合 <script setup>
使用组合式 API 时,defineComponent()
也支持对传递给 setup()
的 prop 的推导
import { defineComponent } from 'vue'export default defineComponent({// 启用了类型推导props: {message: String},// 不需要声明 props 参数的类型setup(props) {props.message // 类型:string | undefined}
})
4、Vue3 提供 PropType
辅助工具用来标记更复杂的 prop 类型
import { defineComponent, PropType } from 'vue'interface Book {title: stringauthor: stringyear: number
}export default defineComponent({props: {book: {// 提供相对 `Object` 更确定的类型type: Object as PropType<Book>,required: true},// 也可以标记函数callback: Function as PropType<(id: number) => void>},mounted() {this.book.title // stringthis.book.year // number// TS Error: argument of type 'string' is not// assignable to parameter of type 'number'this.callback?.('123')}
})
5、ref 会根据初始化时的值推导其类型,也可以手动传入类型。
<template><h1 ref="title">{{ msg }}</h1><HelloWorldref="hellowWorld"msg="Hello Vue 3 + TypeScript + Vite"/>
</template><script lang="ts">
import { defineComponent, onMounted, ref } from 'vue'
import HelloWorld from '../components/HelloWorld.vue'export default defineComponent({components: { HelloWorld },setup () {// 自动推断const msg = ref('Hello H1')// 指定 HTML 元素类型const title = ref<HTMLHeadElement>()// 指定实例类型const hellowWorld = ref<InstanceType<typeof HelloWorld>>()onMounted(() => {console.log(title.value?.innerHTML)console.log(hellowWorld.value?.$props.msg)})return {msg,title,hellowWorld}}
})
</script>
6、reactive 与 ref 一样,computed 计算属性也会自动推断类型。
7、原生 DOM 事件处理函数建议为 event 添加类型标注
<script setup lang="ts">
function handleChange(event: Event) {console.log((event.target as HTMLInputElement).value)
}
</script><template><input type="text" @change="handleChange" />
</template>
Vue 3 中的 <script setup>
语法
Vue 3 支持三种写法编写组件的逻辑:
- Option API(选项式 API)
- Composition API(组合式 API)
- <script setup>(Composition API 的语法糖)
选项式 API
选项式 API 就是 Vue2 采用的风格
<template><h1>{{ msg }}</h1><buttontype="button"@click="increment">count is: {{ count }}</button>
</template><script lang="ts">
import { defineComponent } from 'vue'export default defineComponent({name: 'HelloWorld',props: {msg: {type: String,default: ''}},data () {return {count: 0}},mounted () {console.log('Mounted')},methods: {increment () {this.count++}}
})
</script>
组合式 API
组合式 API 可以将相关的逻辑封装到一起,以便提取为单独的模块
<script lang="ts">
import { defineComponent, ref } from 'vue'export default defineComponent({name: 'HelloWorld',props: {msg: {type: String,default: ''}},setup () {const count = ref(0)const increment = () => {count.value++}return {count,increment}}
})
</script>
<script setup>
使用组合式 API 编写的业务增多后会发现代码大量集中在 setup()
函数中,一些简单的业务需要编写更多的代码,基于这个原因,Vue 3 后来又推出了 <script setup>
语法,它是组合式 API 的语法糖。
<!--1. 可以认为 <script setup> 中的代码都会包裹在 setup() 函数中2. 并且只能使用组合式 API3. 不需要 export 导出对象4. 声明的变量和 props 会自动暴露出来,不需要 return
-->
<script setup lang="ts">
import { ref } from 'vue'/* 定义 props */
const props = defineProps({msg: {type: String,default: ''}
})
console.log(props.msg)
// 模板中也可以通过 props.msg 访问
// 建议:变量取名 props,模板中使用 props 访问,便于阅读/* 定义对外发布的自定义事件 */
const emit = defineEmits(['increment'])/* 定义 data 和 methods */
const count = ref(0)
const increment = () => {count.value++// 对外发布事件emit('increment')
}</script>
导入的组件可以直接使用,会自动推断组件的名字:
<script setup>
import MyComponent from './MyComponent.vue'
import Foo from './Bar.vue'
</script><template><MyComponent /><Foo />
</template>
支持顶层的 await
:
<script setup>
const post = await fetch(`/api/post/1`).then((r) => r.json())
</script>
可以与 <script>
一起使用,<script setup>
中的内容会转化成 export default {}
代码与 <script>
中的代码合并在一起。
<script>
// 代码会追加到 <script setup> 生成的 export default {} 代码前
runSideEffectOnce()// 如果也导出了对象,则会和 <script setup> 生成的 export default {} 导出的对象合并在一起
export default {inheritAttrs: false,customOptions: {}
}
</script><script setup>
// ...
</script>
更多内容请参考官方文档。
<script setup> 中的编译宏
<script setup>
语法糖中使用的 defineProps() 和 defineEmits(),以及 defineExpose()
和 withDefaults()
)不需要单独 import
就可以使用(且只能在 <script setup>
中使用)。
它们实际上被定义成了编译宏,可以理解为已经内置的 API。
单文件组件在编译 <script setup>
时会自动处理,将它们替换成对应的代码。
ESLint 默认不识别它们,可以配置 ESLint 的 globals
,将它们作为全局 API 识别(参考前面的《编译宏和 defineProps、defineEmits、no-undef 规则警告》)。
配置转换 JSX 和 TSX
官方文档:渲染函数 & JSX | Vue.js (vuejs.org)
Vue3 可以通过官方插件 @vue/babel-plugin-jsx 提供 JSX 支持,详细使用请查看文档。
Vite 创建的项目默认不支持 JSX,需要单独配置。
Vite 官方提供 @vitejs/plugin-vue-jsx 插件配置 JSX 支持,内部实际上就是使用的 @vue/babel-plugin-jsx
# 安装插件
npm i -D @vitejs/plugin-vue-jsx
配置插件:
// vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import eslintPlugin from 'vite-plugin-eslint'
import vueJsx from '@vitejs/plugin-vue-jsx'// https://vitejs.dev/config/
export default defineConfig({plugins: [vue(),eslintPlugin({/* 配置选项 */// 禁用 eslint 缓存cache: false}),vueJsx({/* 配置选项 */})]
})
测试:
<!-- src\components\HelloWorld.vue -->
<template><comp />
</template><script setup lang="tsx">
const comp = <h1>Hello World</h1>
</script>
// src\components\Foo.tsx
// 选项式 API
import { defineComponent } from 'vue'export default defineComponent({props: {msg: {type: String,required: true}},render () {return <h2>{this.msg}</h2>}
})
// src\components\Bar.tsx
// 组合式 API
import { defineComponent } from 'vue'interface PropsType {msg: string
}export default defineComponent({props: {msg: {type: String,required: true}},setup() {// 官方还没有未这种方式的 props 参数添加类型推断// 需要手动声明 TS 类型return (props: PropsType) => <h2>{props.msg}</h2>}
})
<!-- src\App.vue -->
<script setup lang="ts">
import HelloWorld from './components/HelloWorld.vue'
import Foo from './components/Foo'
import Bar from './components/Bar'
</script><template><HelloWorld /><Foo msg="Hello Foo" /><Bar msg="Hello Bar" />
</template>
Vite 中配置别名
Vite 创建的项目默认没有配置 @
别名,需要手动配置。
// vite.config.ts
...
import path from 'path'// https://vitejs.dev/config/
export default defineConfig({...resolve: {// https://vitejs.dev/config/#resolve-aliasalias: [{find: '@',replacement: path.join(__dirname, 'src')}]}
})
此时 import path from 'path'
可能报错:
这是因为 path 是 node.js 模块,遵循 CommonJS 规范,没有默认导出 export default
,实际上 Babel 在转换的时候为这类模块自动添加了 module.exports.default
,IDE 发出提示只是类型检查没有识别。
可以根据提示,配置 TypeScript 的 allowSyntheticDefaultImports
为 true
,是其识别这类模块导入操作。
注意 vite.config.ts
的 TypeScript 配置在 tsconfig.node.json
中:
// tsconfig.node.json
{"compilerOptions": {"composite": true,"module": "esnext","moduleResolution": "node",// 允许处理默认 import"allowSyntheticDefaultImports": true},"include": ["vite.config.ts"]
}
PS:也可以通过安装
@types/node
来识别。
现在可以这样导入 .vue
文件:
// JS 中使用
import HelloWorld from '@/components/HelloWorld.vue'// HTML 中使用
<img src="@/assets/logo.png">// css 中使用
background: url(@/assets/logo.png);
但是导入 .tsx
文件,TypeScript 会报错:
// 找不到模块“@/components/Foo”或其相应的类型声明。
import Foo from '@/components/Foo' // 省略了 .tsx 后缀// 导入路径不能以“.tsx”扩展名结束。考虑改为导入“@/components/Bar.js”。
import Bar from '@/components/Bar.tsx'
所以还需要配置 TypeScript 的导入映射(baseUrl
和 paths
):
// tsconfig.json
{"compilerOptions": {...// https://www.typescriptlang.org/tsconfig#paths// 必须定义 baseUrl"baseUrl": ".",// paths 设置相对于 baseUrl 的一系列映射路径"paths": {"@/*": ["src/*"]}},...
}
至于使用 .tsx
显式扩展名报错的问题,不使用扩展名即可。
关于 Vite 中导入 .vue
组件必带后缀的问题
Vite 默认不会忽略 .vue
扩展名,虽然可以通过配置忽略,但官方不建议这样做,理由是**“会影响 IDE 和类型支持”**,参考 resolve.extensions
尤大在 Vite Issue #178 中也声明,导入 .vue
文件不能省略后缀本就是**“故意设计”**的,并且在下一个主要版本中,还将停止在 Vue CLI 中支持无扩展名的 Vue 导入。
所以建议导入 Vue 组件的时候还是带着 .vue
扩展名。
这篇关于Vue3+Vite+Ts 项目实战 01 Vite 创建项目、ESLint+TS+GitCommit配置、Vue3新特性介绍的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!