mirror of
https://github.com/nuxt/nuxt.git
synced 2025-02-13 12:18:15 +00:00
feat(kit): add named layer aliases (#30948)
This commit is contained in:
parent
b391f8f03a
commit
5aca9e63c1
@ -18,10 +18,16 @@ One of the core features of Nuxt is the layers and extending support. You can ex
|
||||
|
||||
## Usage
|
||||
|
||||
By default, any layers within your project in the `~~/layers` directory will be automatically registered as layers in your project
|
||||
By default, any layers within your project in the `~~/layers` directory will be automatically registered as layers in your project.
|
||||
|
||||
::note
|
||||
Layer auto-registration was introduced in Nuxt v3.12.0
|
||||
Layer auto-registration was introduced in Nuxt v3.12.0.
|
||||
::
|
||||
|
||||
In addition, named layer aliases to the `srcDir` of each of these layers will automatically be created. For example, you will be able to access the `~~/layers/test` layer via `#layers/test`.
|
||||
|
||||
::note
|
||||
Named layer aliases were introduced in Nuxt v3.16.0.
|
||||
::
|
||||
|
||||
In addition, you can extend from a layer by adding the [extends](/docs/api/nuxt-config#extends) property to your [`nuxt.config`](/docs/guide/directory-structure/nuxt-config) file.
|
||||
|
@ -164,9 +164,25 @@ When publishing the layer as a private npm package, you need to make sure you lo
|
||||
|
||||
## Tips
|
||||
|
||||
### 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.
|
||||
|
||||
```ts [nuxt.config.ts]
|
||||
export default defineNuxtConfig({
|
||||
$meta: {
|
||||
name: 'example',
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
This will produce an alias of `#layers/example` which points to your layer.
|
||||
|
||||
### Relative Paths and Aliases
|
||||
|
||||
When importing using aliases (such as `~/` and `@/`) in a layer components and composables, note that aliases are resolved relative to the user's project paths. As a workaround, you can **use relative paths** to import them. We are working on a better solution for named layer aliases.
|
||||
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.
|
||||
|
||||
Also when using relative paths in `nuxt.config` file of a layer, (with exception of nested `extends`) they are resolved relative to user's project instead of the layer. As a workaround, use full resolved paths in `nuxt.config`:
|
||||
|
||||
|
@ -7,7 +7,7 @@ import { loadConfig } from 'c12'
|
||||
import type { NuxtConfig, NuxtOptions } from '@nuxt/schema'
|
||||
import { globby } from 'globby'
|
||||
import defu from 'defu'
|
||||
import { join } from 'pathe'
|
||||
import { basename, join, relative } from 'pathe'
|
||||
import { isWindows } from 'std-env'
|
||||
import { tryResolveModule } from '../internal/esm'
|
||||
|
||||
@ -18,14 +18,11 @@ export interface LoadNuxtConfigOptions extends Omit<LoadConfigOptions<NuxtConfig
|
||||
|
||||
export async function loadNuxtConfig (opts: LoadNuxtConfigOptions): Promise<NuxtOptions> {
|
||||
// Automatically detect and import layers from `~~/layers/` directory
|
||||
opts.overrides = defu(opts.overrides, {
|
||||
_extends: await globby('layers/*', {
|
||||
onlyDirectories: true,
|
||||
cwd: opts.cwd || process.cwd(),
|
||||
}),
|
||||
});
|
||||
const localLayers = await globby('layers/*', { onlyDirectories: true, cwd: opts.cwd || process.cwd() })
|
||||
opts.overrides = defu(opts.overrides, { _extends: localLayers });
|
||||
|
||||
(globalThis as any).defineNuxtConfig = (c: any) => c
|
||||
const result = await loadConfig<NuxtConfig>({
|
||||
const { configFile, layers = [], cwd, config: nuxtConfig, meta } = await loadConfig<NuxtConfig>({
|
||||
name: 'nuxt',
|
||||
configFile: 'nuxt.config',
|
||||
rcFile: '.nuxtrc',
|
||||
@ -35,13 +32,17 @@ export async function loadNuxtConfig (opts: LoadNuxtConfigOptions): Promise<Nuxt
|
||||
...opts,
|
||||
})
|
||||
delete (globalThis as any).defineNuxtConfig
|
||||
const { configFile, layers = [], cwd } = result
|
||||
const nuxtConfig = result.config!
|
||||
|
||||
// Fill config
|
||||
nuxtConfig.rootDir = nuxtConfig.rootDir || cwd
|
||||
nuxtConfig._nuxtConfigFile = configFile
|
||||
nuxtConfig._nuxtConfigFiles = [configFile]
|
||||
nuxtConfig.alias ||= {}
|
||||
|
||||
if (meta?.name) {
|
||||
const alias = `#layers/${meta.name}`
|
||||
nuxtConfig.alias[alias] ||= nuxtConfig.rootDir
|
||||
}
|
||||
|
||||
const defaultBuildDir = join(nuxtConfig.rootDir!, '.nuxt')
|
||||
if (!opts.overrides?._prepare && !nuxtConfig.dev && !nuxtConfig.buildDir && existsSync(defaultBuildDir)) {
|
||||
@ -74,6 +75,18 @@ export async function loadNuxtConfig (opts: LoadNuxtConfigOptions): Promise<Nuxt
|
||||
|
||||
// Filter layers
|
||||
if (!layer.configFile || layer.configFile.endsWith('.nuxtrc')) { continue }
|
||||
|
||||
// Add layer name for local layers
|
||||
if (layer.cwd && cwd && localLayers.includes(relative(cwd, layer.cwd))) {
|
||||
layer.meta ||= {}
|
||||
layer.meta.name ||= basename(layer.cwd)
|
||||
}
|
||||
|
||||
// Add layer alias
|
||||
if (layer.meta?.name) {
|
||||
const alias = `#layers/${layer.meta.name}`
|
||||
nuxtConfig.alias[alias] ||= layer.config.rootDir || layer.cwd
|
||||
}
|
||||
_layers.push(layer)
|
||||
}
|
||||
|
||||
|
@ -0,0 +1 @@
|
||||
export const foo = 'bar'
|
@ -0,0 +1 @@
|
||||
export default defineNuxtConfig({})
|
5
packages/kit/test/layer-fixture/nuxt.config.ts
Normal file
5
packages/kit/test/layer-fixture/nuxt.config.ts
Normal file
@ -0,0 +1,5 @@
|
||||
export default defineNuxtConfig({
|
||||
$meta: {
|
||||
name: 'layer-fixture',
|
||||
},
|
||||
})
|
28
packages/kit/test/load-nuxt-config.spec.ts
Normal file
28
packages/kit/test/load-nuxt-config.spec.ts
Normal file
@ -0,0 +1,28 @@
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { loadNuxtConfig } from '@nuxt/kit'
|
||||
|
||||
describe('loadNuxtConfig', () => {
|
||||
it('should add named aliases for local layers', async () => {
|
||||
const cwd = fileURLToPath(new URL('./layer-fixture', import.meta.url))
|
||||
const config = await loadNuxtConfig({ cwd })
|
||||
for (const alias in config.alias) {
|
||||
config.alias[alias] = config.alias[alias]!.replace(cwd, '<rootDir>')
|
||||
}
|
||||
expect(config.alias).toMatchInlineSnapshot(`
|
||||
{
|
||||
"#build": "<rootDir>/.nuxt",
|
||||
"#internal/nuxt/paths": "<rootDir>/.nuxt/paths.mjs",
|
||||
"#layers/layer-fixture": "<rootDir>",
|
||||
"#layers/test": "<rootDir>/layers/test",
|
||||
"#shared": "<rootDir>/shared",
|
||||
"@": "<rootDir>",
|
||||
"@@": "<rootDir>",
|
||||
"assets": "<rootDir>/assets",
|
||||
"public": "<rootDir>/public",
|
||||
"~": "<rootDir>",
|
||||
"~~": "<rootDir>",
|
||||
}
|
||||
`)
|
||||
})
|
||||
})
|
Loading…
Reference in New Issue
Block a user