mirror of
https://github.com/nuxt/nuxt.git
synced 2025-01-18 09:25:54 +00:00
fix(nuxt3): import top-level files and subdirectory indices (#2774)
This commit is contained in:
parent
8588f749ad
commit
b38e394dfe
@ -12,6 +12,23 @@ Nuxt will automatically read the files in your `plugins` directory and load them
|
|||||||
All plugins in your `plugins/` directory are auto-registered, so you should not add them to your `nuxt.config` separately.
|
All plugins in your `plugins/` directory are auto-registered, so you should not add them to your `nuxt.config` separately.
|
||||||
::
|
::
|
||||||
|
|
||||||
|
## Which files are registered
|
||||||
|
|
||||||
|
Only files at the top level of the `plugins/` directory (or index files within any subdirectories) will be registered as plugins.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
plugins
|
||||||
|
| - myPlugin.ts
|
||||||
|
| - myOtherPlugin
|
||||||
|
| --- supportingFile.ts
|
||||||
|
| --- componentToRegister.vue
|
||||||
|
| --- index.ts
|
||||||
|
```
|
||||||
|
|
||||||
|
Only `myPlugin.ts` and `myOtherPlugin/index.ts` would be registered.
|
||||||
|
|
||||||
## Creating plugins
|
## Creating plugins
|
||||||
|
|
||||||
The only argument passed to a plugin is [`nuxtApp`](/docs/usage/nuxt-app).
|
The only argument passed to a plugin is [`nuxtApp`](/docs/usage/nuxt-app).
|
||||||
|
@ -8,7 +8,23 @@ head.title: Composables directory
|
|||||||
|
|
||||||
Nuxt 3 supports `composables/` directory to automatically import your Vue composables into your application using auto-imports!
|
Nuxt 3 supports `composables/` directory to automatically import your Vue composables into your application using auto-imports!
|
||||||
|
|
||||||
Example: (using named export)
|
## How files are scanned
|
||||||
|
|
||||||
|
Only files at the top level of the `composables/` directory (or index files within any subdirectories) will be scanned for composables.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
composables
|
||||||
|
| - useFoo.ts
|
||||||
|
| - useBar
|
||||||
|
| --- supportingFile.ts
|
||||||
|
| --- index.ts
|
||||||
|
```
|
||||||
|
|
||||||
|
Only `useFoo.ts` and `useBar/index.ts` would be searched for imports - and if the latter is a default export, it would be registered as `useBar` rather than `index`.
|
||||||
|
|
||||||
|
## Example: (using named export)
|
||||||
|
|
||||||
```js [composables/useFoo.ts]
|
```js [composables/useFoo.ts]
|
||||||
import { useState } from '#app'
|
import { useState } from '#app'
|
||||||
@ -18,7 +34,7 @@ export const useFoo = () => {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Example: (using default export)
|
## Example: (using default export)
|
||||||
|
|
||||||
```js [composables/use-foo.ts or composables/useFoo.ts]
|
```js [composables/use-foo.ts or composables/useFoo.ts]
|
||||||
import { useState } from '#app'
|
import { useState } from '#app'
|
||||||
|
@ -104,7 +104,7 @@ export function tryResolvePath (path: string, opts: ResolveOptions = {}) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function resolveFiles (path: string, pattern: string) {
|
export async function resolveFiles (path: string, pattern: string | string[]) {
|
||||||
const files = await globby(pattern, {
|
const files = await globby(pattern, {
|
||||||
cwd: path,
|
cwd: path,
|
||||||
followSymbolicLinks: true
|
followSymbolicLinks: true
|
||||||
|
@ -1,37 +1,42 @@
|
|||||||
import { promises as fsp, existsSync } from 'fs'
|
import { promises as fsp, existsSync } from 'fs'
|
||||||
import { parse as parsePath, join } from 'pathe'
|
import { parse as parsePath } from 'pathe'
|
||||||
import { globby } from 'globby'
|
|
||||||
import { findExports } from 'mlly'
|
import { findExports } from 'mlly'
|
||||||
import { camelCase } from 'scule'
|
import { camelCase } from 'scule'
|
||||||
import { AutoImport } from '@nuxt/schema'
|
import { AutoImport } from '@nuxt/schema'
|
||||||
|
import { resolveFiles } from '@nuxt/kit'
|
||||||
import { filterInPlace } from './utils'
|
import { filterInPlace } from './utils'
|
||||||
|
|
||||||
export async function scanForComposables (dir: string, autoImports: AutoImport[]) {
|
export async function scanForComposables (dir: string, autoImports: AutoImport[]) {
|
||||||
if (!existsSync(dir)) { return }
|
if (!existsSync(dir)) { return }
|
||||||
|
|
||||||
const files = await globby(['*.{ts,js,tsx,jsx,mjs,cjs,mts,cts}'], { cwd: dir })
|
const files = await resolveFiles(dir, [
|
||||||
|
'*.{ts,js,mjs,cjs,mts,cts}',
|
||||||
|
'*/index.{ts,js,mjs,cjs,mts,cts}'
|
||||||
|
])
|
||||||
|
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
files.map(async (file) => {
|
files.map(async (path) => {
|
||||||
const importPath = join(dir, file)
|
|
||||||
|
|
||||||
// Remove original entries from the same import (for build watcher)
|
// Remove original entries from the same import (for build watcher)
|
||||||
filterInPlace(autoImports, i => i.from !== importPath)
|
filterInPlace(autoImports, i => i.from !== path)
|
||||||
|
|
||||||
const code = await fsp.readFile(join(dir, file), 'utf-8')
|
const code = await fsp.readFile(path, 'utf-8')
|
||||||
const exports = findExports(code)
|
const exports = findExports(code)
|
||||||
const defaultExport = exports.find(i => i.type === 'default')
|
const defaultExport = exports.find(i => i.type === 'default')
|
||||||
|
|
||||||
if (defaultExport) {
|
if (defaultExport) {
|
||||||
autoImports.push({ name: 'default', as: camelCase(parsePath(file).name), from: importPath })
|
let name = parsePath(path).name
|
||||||
|
if (name === 'index') {
|
||||||
|
name = parsePath(path.split('/').slice(0, -1).join('/')).name
|
||||||
|
}
|
||||||
|
autoImports.push({ name: 'default', as: camelCase(name), from: path })
|
||||||
}
|
}
|
||||||
for (const exp of exports) {
|
for (const exp of exports) {
|
||||||
if (exp.type === 'named') {
|
if (exp.type === 'named') {
|
||||||
for (const name of exp.names) {
|
for (const name of exp.names) {
|
||||||
autoImports.push({ name, as: name, from: importPath })
|
autoImports.push({ name, as: name, from: path })
|
||||||
}
|
}
|
||||||
} else if (exp.type === 'declaration') {
|
} else if (exp.type === 'declaration') {
|
||||||
autoImports.push({ name: exp.name, as: exp.name, from: importPath })
|
autoImports.push({ name: exp.name, as: exp.name, from: path })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -73,7 +73,10 @@ export async function resolveApp (nuxt: Nuxt, app: NuxtApp) {
|
|||||||
// Resolve plugins
|
// Resolve plugins
|
||||||
app.plugins = [
|
app.plugins = [
|
||||||
...nuxt.options.plugins,
|
...nuxt.options.plugins,
|
||||||
...await resolveFiles(nuxt.options.srcDir, 'plugins/**/*.{js,ts,mjs,cjs}')
|
...await resolveFiles(nuxt.options.srcDir, [
|
||||||
|
'plugins/*.{ts,js,mjs,cjs,mts,cts}',
|
||||||
|
'plugins/*/index.*{ts,js,mjs,cjs,mts,cts}'
|
||||||
|
])
|
||||||
].map(plugin => normalizePlugin(plugin))
|
].map(plugin => normalizePlugin(plugin))
|
||||||
|
|
||||||
// Extend app
|
// Extend app
|
||||||
|
Loading…
Reference in New Issue
Block a user