这篇文章是我在 Nuxt Nation 2023 大会上关于"解密 Nuxt 层"演讲的辅助文章。
如果你曾使用过 Nuxt 2,你会知道 Nuxt 的默认设置非常简洁。Nuxt 3 也保持了这一特点。但我们可以通过扩展 Nuxt,让它为我们实现更多功能!
Nuxt 分为运行时上下文和构建时上下文。我们可以通过 Nuxt 插件来改变和扩展 Nuxt 的运行时行为,通过 Nuxt 模块来改变和扩展 Nuxt 的构建时行为。以下是对这两者的简要回顾:
useNuxtApp()
可组合函数包装在默认的 Nuxt 3 中。它帮助我们访问 Nuxt 的共享运行时上下文。它有默认的方法、钩子和属性。但 Nuxt 允许我们添加自定义的属性和方法!我们可以使用 Nuxt 插件来实现这一点。
Nuxt 模块帮助我们进入构建过程的不同阶段。结果是,我们扩展了 Nuxt 的构建时上下文。看看 Nuxt 模块的签名,export default defineNuxtModule((options, nuxt) => { /*...*/ }。第二个参数 - nuxt - 这里只是构建时上下文。在终端打印 nuxt,可以看到所有通过 nuxt.config 文件添加到 Nuxt 的默认和自定义(如果有)选项。
是什么
Nuxt Layers是在Nuxt 3中引入的一个功能,它允许以模块化的方式扩展和组织Nuxt应用程序。
您可以使用它在 monorepo 中或从 git 存储库或 npm 包中共享和重用部分 Nuxt 应用程序。层结构几乎与标准 Nuxt 应用程序相同,这使得它们易于创作和维护。
最小的 Nuxt 层目录应包含一个文件来指示它是一个层。nuxt.config.ts
export default defineNuxtConfig({})
特点
核心功能
- Nuxt Layers是一种机制,允许你扩展默认的Nuxt应用程序以重用组件、实用程序和配置
- Nuxt Layer的结构几乎与标准的Nuxt应用程序相同,使其易于编写和维护
用例
- 它们用于使用nuxt.config和app.config在项目之间共享可重用的配置预设
- 你可以创建组件库、实用程序和可组合的库
层扩展
可以通过向nuxt.config.ts
文件添加extends
属性来扩展层
Module vs Layers
除了显而易见的差异之外,Nuxt 模块和层之间还有一些功能重叠。如果你使用 Nuxt 模块进行特定用例,如添加:
- Nuxt 页面
- 组件库
- Nuxt 插件
- 服务器路由
- 状态管理(Pinia, Vuex)等
虽然我们可以使用 Nuxt 模块来实现上述所有功能,但我们也可以使用 Nuxt 层来实现相同的功能。编写 Nuxt 模块有一个陡峭的学习曲线。编写 Nuxt 模块要求你了解 @nuxt/kit
,它提供的所有方法,它们的签名,何时以及如何使用它们等。而编写 Nuxt 层感觉非常像编写你的标准 Nuxt 应用程序,因为这正是它的本质!以下是两者之间的其他关键差异:
区别
Modules:
- 是扩展Nuxt核心的底层
- 主要与集成和引入外部库到 Nuxt 中有关
- 扩展方式是 nuxt.config/modules
- 需要对
@nuxt/kit
有深入的了解才能编写Nuxt模块
Layers:
- 是帮助我们隔离可重用的 Nuxt 部分的高级构造,如 Nuxt 页面、布局、组件、可组合等
- 不能像 Nuxt 模块那样内联编写在 nuxt.config 中
- 没有像 Nuxt 目录结构那样的约定驱动的目录名称
- 感觉与编写标准 Nuxt 应用程序相同
扩展 Nuxt
到目前为止,我们使用 Nuxt 模块和插件来扩展默认的 Nuxt。但随着 Nuxt 3 的发布,现在我们有了 Nuxt 层来以全新的方式扩展 Nuxt!
我们可以使用 Nuxt 应用程序的 nuxt.config
文件中的
:::highlight-text
---
text: extends: 键添加 Nuxt 层
---
:::
。这与我们
:::highlight-text
---
text: 使用 modules: 键添加 Nuxt 模块
---
:::
非常相似。
应用的nuxt.config.ts
export default defineNuxtConfig({
extends: [
// monorepo or external NPM package as a layer
'@scope/moduleName',
// local layers
'../layers/base'
],
modules: []
})
Nuxt 层可以物理存在于任何地方,只要它们有一个 nuxt.config 文件。Nuxt 层可以是:
一个layer可以是
- 本地目录,
- 在线代码仓库,例如Github、Gitlab、BitBucket等
- 在线发布的NPM包
- 可以在本地访问的monorepo 包,无需在线发布任何内容。
了解可分层部件
Nuxt 将自动扫描层目录中的某些其他文件并将其用于扩展该层的项目。
components/*
- 扩展默认组件composables/*
- 扩展默认可组合项pages/*
- 扩展默认页面server/*
- 扩展默认服务器端点和中间件utils/*
- 扩展默认实用程序nuxt.config.ts
- 扩展默认的 nuxt 配置app.config.ts
- 扩展默认应用程序配置
除了/composables
, /components
, /pages
, /server
和nuxt.config
文件之外, 也可以包含 /layouts
, /middelware
, /public
, /plugins
app.vue
& app.config
放到Nuxt Layers.
原理
Nuxt 层功能在后台使用
:::highlight-text
---
text: c12
---
:::
和
:::highlight-text
---
text: defu
---
:::
包。Nuxt 应用程序的 nuxt.config
文件使用 extends: 键指向层的 nuxt.config 文件并合并为一个。因此,在你的 Nuxt 应用程序中使用多个不同的层并不意味着我们同时运行多个 Nuxt 应用程序。
配置加载和扩展支持由unjs/c12处理,使用unjs/defu合并,并使用unjs/giget支持远程 git 源。
目录的根目录中必须有一个nuxt.config文件才能被视为可以扩展到另一个 Nuxt 应用程序的Nuxt Layer。
例子
创建layer
Nuxt 提供了一个nuxi命令来初始化具有基本结构的入门模板。
npx nuxi init --template layer nuxt-ui-layer
与 Nuxt Modules一样,您也需要一个 Nuxt 应用程序来测试您的layer。此nuxi命令将在您的图层中生成一个.playground项目。这个游乐场充当您的目标 Nuxt 应用程序,您可以在其中使用和自定义您的图层。所以请随意亲自尝试一下。检查
发布
- 将layer 转换为 monorepo 包
- 发布层
- Nuxt 项目中添加 layer
可以使用git仓库去导入// 项目中导入 export default defineNuxtConfig({ extends: [ 'github:username/repoName', // GitHub Remote Source 'github:username/repoName/base', // GitHub Remote Source within /base directory 'github:username/repoName#dev', // GitHub Remote Source from dev branch 'github:username/repoName#v1.0.0', // GitHub Remote Source from v1.0.0 tag 'gitlab:username/repoName', // GitLab Remote Source example 'bitbucket:username/repoName', // Bitbucket Remote Source example ] })
发布npm包// 项目中导入 export default defineNuxtConfig({ extends: [ // Node Module with scope '@scope/moduleName', // or just the module name 'moduleName' ] })
主项目通过导入layer npm包后可以看到已经注册响应的组件了。
总结
层会对我们构建 Nuxt 应用程序的方式产生重大影响。但是,当我们使用 Nuxt 3 构建大型应用程序时,如何考虑层。想象一下,如果这些层是实际 Nuxt 项目的一部分。然后我们可以将每一层分为以下类别之一:
分类
- 平台层:抽象 UI 库、主题、身份验证、数据提供程序甚至可重用的 Nuxt 布局。
- 功能特定层:让我们以电子商务应用程序为例。我们可以为每个功能设置一层,例如:
PDP(产品详细信息页面),
PLP(产品列表页面),
查看,
帐号等 - 应用程序层:层不限于特性或功能。他们可以将整个应用程序抽象到其中。例如,博客、登陆页面、营销活动应用程序。它们可以重复用于从基础层创建多变体网站。
博客
示例仓库