04 / 09

为什么不用 import?

理解 Nuxt Auto Import 的编译机制,以及自动导入的边界。

为什么不用 import?

学习目标

理解 Nuxt 为什么很多 API 不需要手动 import,以及 Auto Import 的工作原理。


一、这个知识解决什么问题?

学习 Vue 时,我们已经习惯了:

import { ref, computed } from 'vue'
import { useRoute } from 'vue-router'

但到了 Nuxt,我们发现:

const count = ref(0)
const route = useRoute()

竟然也能正常运行。于是自然产生一个问题:

为什么不用 import?


二、一起推导

如果 JavaScript 没有 import,变量从哪里来?正常情况下 ref() 应该直接报错 ReferenceError: ref is not defined

说明 Nuxt 一定做了额外的工作。有两种可能:

  • 运行时动态查找:运行效率会变低
  • 编译阶段自动生成 import:最终代码和我们自己写 import 几乎没有区别

Nuxt 最终选择的是:

编译阶段自动生成 import。


三、Nuxt 是怎么工作的?

例如我们写:

const route = useRoute()
const count = ref(0)

Nuxt 编译时扫描代码,发现 useRouteref,自动生成:

import { ref } from "vue"
import { useRoute } from "#app"

这一步不是浏览器完成的,而是 Nuxt 编译器完成的。浏览器最终拿到的代码仍然有完整的 import。


四、脑图

Nuxt Auto Import 脑图:编译器扫描源码并生成标准 ES Module import

两条重要边界:

  1. 能力边界:只有 Nuxt 已登记的 Vue API、Nuxt Composables,以及 composables/ 目录下的自定义函数才能自动导入。
  2. 时间边界:自动导入发生在开发与构建阶段;浏览器拿到的是带完整依赖关系的标准模块代码。

五、哪些东西可以自动导入?

Vue API

ref() / reactive() / computed() / watch() / watchEffect()
onMounted() / onUnmounted() / nextTick()

Nuxt Composables

useRoute() / useRouter() / useFetch() / useAsyncData()
useState() / useRuntimeConfig() / navigateTo()

自定义 Composables

composables/useUser.ts 中定义后,可以直接使用 useUser(),无需 import。


六、容易踩坑

❌ 所有函数都能自动导入

不是。普通工具函数仍然需要 import

❌ Auto Import 会降低性能

不会。Auto Import 是编译阶段完成的,浏览器运行的仍然是正常的 ES Module。

❌ Auto Import 是 JavaScript 特性

不是。这是 Nuxt 提供的框架能力,离开 Nuxt 就没有了。


一句话记忆

不是没有 import,而是 Nuxt 在编译阶段帮我们写好了 import。