Создание авторских слоев Nuxt

Nuxt предоставляет мощную систему, которая позволяет расширять файлы по умолчанию, конфигурации и многое другое.

Слои Nuxt - это мощная возможность, которую вы можете использовать для совместного использования и переиспользования частичных приложений Nuxt в монорепозитории или из git-репозитория или пакета npm. Структура слоев практически идентична стандартному приложению Nuxt, что упрощает их создание и поддержку.

Узнать больше Docs > Getting Started > Layers.

Базовая директория слоев Nuxt должена содержать файл nuxt.config.ts, указывающий на то, что это слой.

base/nuxt.config.ts
export default defineNuxtConfig({})

Кроме того, некоторые другие файлы в директории слоя будут автоматически сканироваться и использоваться Nuxt для проекта, расширяющего этот слой.

  • components/* - Расширение компонентов по умолчанию
  • composables/* - Расширение композаблов по умолчанию
  • layouts/* - Расширение лэйаутов по умолчанию
  • pages/* - Расширение страниц по умолчанию
  • plugins/* - Расширение плагинов по умолчанию
  • server/* - Расширение серверных эндпоинтов и middleware по умолчанию
  • utils/* - Расширение утилит по умолчанию
  • nuxt.config.ts- Расширение конфигурации nuxt по умолчанию
  • app.config.ts - Расширение конфигурации приложения по умолчанию

Базовый пример

export default defineNuxtConfig({
  extends: [
    './base'
  ]
})

Начальный шаблон

Для начала вы можете инициализировать слой с помощью шаблона Nuxt Layer Starter. Это создаст базовую структуру, на которую вы сможете опираться. Для начала выполните эту команду в терминале:

Terminal
npm create nuxt -- --template layer nuxt-layer

Следуйте инструкциям в README для выполнения следующих шагов.

Публикация слоев

Вы можете публиковать и делиться слоями, используя либо удаленный источник, либо npm-пакет.

Git-репозиторий

Вы можете использовать git-репозиторий, чтобы поделиться своим слоем Nuxt. Некоторые примеры:

nuxt.config.ts
export default defineNuxtConfig({
  extends: [
    'github:username/repoName',        // Удаленный источник GitHub
    'github:username/repoName/base',   // Удаленный источник GitHub в директории /base
    'github:username/repoName#dev',    // Удаленный источник GitHub из ветки dev
    'github:username/repoName#v1.0.0', // Удаленный источник GitHub с тегом v1.0.0
    'gitlab:username/repoName',        // Пример удаленного источника GitLab
    'bitbucket:username/repoName',     // Пример удаленного источника Bitbucket
  ]
})
Если вы хотите расширить приватный удаленный источник, вам нужно добавить переменную окружения GIGET_AUTH=<token> для предоставления токена.
Если вы хотите расширить удаленный источник из самостоятельно размещенного инстанса GitHub или GitLab, вам нужно указать его URL с помощью переменной окружения GIGET_GITHUB_URL=<url> или GIGET_GITLAB_URL=<url> - или напрямую настроить его с помощью опции auth в вашем nuxt.config.
Bear in mind that if you are extending a remote source as a layer, you will not be able to access its dependencies outside of Nuxt. For example, if the remote layer depends on an eslint plugin, this will not be usable in your eslint config. That is because these dependencies will be located in a special location (node_modules/.c12/layer_name/node_modules/) that is not accessible to your package manager.
При использовании удаленных источников git, если слой имеет зависимости npm и вы хотите установить их, вы можете сделать это, указав install: true в опциях слоя.
nuxt.config.ts
export default defineNuxtConfig({
  extends: [
    ['github:username/repoName', { install: true }]
  ]
})

Пакет npm

Вы можете опубликовать слои Nuxt в виде пакета npm, содержащего файлы и зависимости, которые вы хотите расширить. Это позволит вам поделиться конфигурацией с другими, использовать ее в нескольких проектах или в частном порядке.

Для расширения из пакета npm необходимо убедиться, что модуль опубликован в npm и установлен в проект пользователя как devDependency. Затем вы можете использовать имя модуля для расширения текущей конфигурации nuxt:

nuxt.config.ts
export default defineNuxtConfig({
  extends: [
    // скоуп node модуля
    '@scope/moduleName',
    // или просто имя модуля
    'moduleName'
  ]
})

Чтобы опубликовать директорию слоя как пакет npm, необходимо убедиться, что в файле package.json указаны правильные свойства. Это обеспечит включение файлов при публикации пакета.

package.json
{
  "name": "my-theme",
  "version": "1.0.0",
  "type": "module",
  "main": "./nuxt.config.ts",
  "dependencies": {},
  "devDependencies": {
    "nuxt": "^3.0.0"
  }
}
Убедитесь, что любая зависимость, импортируемая в слой, явно добавлена в dependencies. Зависимость nuxt и все, что используется только для тестирования слоя перед публикацией, должны оставаться в поле devDependencies.

Теперь вы можете приступить к публикации модуля на npm - как публично, так и приватно.

При публикации слоя в виде приватного пакета npm необходимо убедиться, что вы вошли в систему, чтобы аутентифицироваться в npm для загрузки модуля node.

Советы

Named Layer Aliases

Auto-scanned layers (from your ~~/layers directory) automatically create aliases. For example, you can access your ~~/layers/test layer via #layers/test.

If you want to create named layer aliases for other layers, you can specify a name in the configuration of the layer.

nuxt.config.ts
export default defineNuxtConfig({
  $meta: {
    name: 'example',
  },
})

This will produce an alias of #layers/example which points to your layer.

Относительные пути и алиасы

When importing using global aliases (such as ~/ and @/) in a layer components and composables, note that these aliases are resolved relative to the user's project paths. As a workaround, you can use relative paths to import them, or use named layer aliases.

Также при использовании относительных путей в файле nuxt.config слоя (за исключением вложенных extends) они разрешаются относительно проекта пользователя, а не слоя. В качестве обходного пути используйте полные разрешенные пути в nuxt.config:

nuxt.config.ts
import { fileURLToPath } from 'url'
import { dirname, join } from 'path'

const currentDir = dirname(fileURLToPath(import.meta.url))

export default defineNuxtConfig({
  css: [
    join(currentDir, './assets/main.css')
  ]
})

Многослойная поддержка модулей Nuxt

Вы можете использовать внутренний массив nuxt.options._layers для поддержки пользовательской многослойной обработки ваших модулей.

modules/my-module.ts
export default defineNuxtModule({
  setup(_options, nuxt) {
    for (const layer of nuxt.options._layers) {
      // Вы можете проверить существование пользовательской директории, чтобы расширить ее для каждого слоя
      console.log('Пользовательское расширение для', layer.cwd, layer.config)
    }
  }
})

Примечания:

  • Более ранние элементы в массиве _layers имеют более высокий приоритет и переопределяют более поздние
  • Проект пользователя является первым элементом в массиве _layers

Углубляясь в тему

Загрузка конфигурации и поддержка расширений осуществляется с помощью unjs/c12, слияние - с помощью unjs/defu и поддержка удаленных git источников - с помощью unjs/giget. Ознакомьтесь с документацией и исходным кодом, чтобы узнать больше.

Ознакомьтесь с нашими текущими разработками, чтобы внести дополнительные улучшения в поддержку слоев на GitHub.