diff --git a/docs/content/2.guide/3.directory-structure/5.composables.md b/docs/content/2.guide/3.directory-structure/5.composables.md index eeaa2cd0fa6..43eb781288d 100644 --- a/docs/content/2.guide/3.directory-structure/5.composables.md +++ b/docs/content/2.guide/3.directory-structure/5.composables.md @@ -98,7 +98,7 @@ export { utils } from './nested/utils.ts' ```ts [nuxt.config.ts] export default defineNuxtConfig({ - autoImports: { + imports: { dirs: [ // Scan top-level modules 'composables', diff --git a/docs/content/bridge/1.overview.md b/docs/content/bridge/1.overview.md index dc2d62e0c50..eab7c11bd35 100644 --- a/docs/content/bridge/1.overview.md +++ b/docs/content/bridge/1.overview.md @@ -278,7 +278,7 @@ export default defineNuxtConfig({ // scriptSetup: false, // Disable composables auto importing - // autoImports: false, + // imports: false, // Do not warn about module incompatibilities // constraints: false diff --git a/examples/advanced/config-extends/base/nuxt.config.ts b/examples/advanced/config-extends/base/nuxt.config.ts index 8bcb917dc5b..b52d458e0ec 100644 --- a/examples/advanced/config-extends/base/nuxt.config.ts +++ b/examples/advanced/config-extends/base/nuxt.config.ts @@ -1,7 +1,7 @@ import { defineNuxtConfig } from 'nuxt' export default defineNuxtConfig({ - autoImports: { + imports: { dirs: ['utils'] }, publicRuntimeConfig: { diff --git a/packages/kit/src/auto-import.ts b/packages/kit/src/auto-import.ts index 673774d1ef8..58a2a8d56d0 100644 --- a/packages/kit/src/auto-import.ts +++ b/packages/kit/src/auto-import.ts @@ -5,17 +5,17 @@ import { assertNuxtCompatibility } from './compatibility' export function addAutoImport (imports: Import | Import[]) { assertNuxtCompatibility({ bridge: true }) - useNuxt().hook('autoImports:extend', (autoImports) => { - autoImports.push(...(Array.isArray(imports) ? imports : [imports])) + useNuxt().hook('imports:extend', (_imports) => { + _imports.push(...(Array.isArray(imports) ? imports : [imports])) }) } -export function addAutoImportDir (_autoImportDirs: string | string[]) { +export function addAutoImportDir (dirs: string | string[]) { assertNuxtCompatibility({ bridge: true }) - useNuxt().hook('autoImports:dirs', (autoImportDirs: string[]) => { - for (const dir of (Array.isArray(_autoImportDirs) ? _autoImportDirs : [_autoImportDirs])) { - autoImportDirs.push(dir) + useNuxt().hook('imports:dirs', (_dirs: string[]) => { + for (const dir of (Array.isArray(dirs) ? dirs : [dirs])) { + _dirs.push(dir) } }) } diff --git a/packages/nuxt/package.json b/packages/nuxt/package.json index 072d682ae22..8728eac48e3 100644 --- a/packages/nuxt/package.json +++ b/packages/nuxt/package.json @@ -48,7 +48,7 @@ "globby": "^13.1.2", "h3": "^0.7.15", "hash-sum": "^2.0.0", - "hookable": "^5.1.1", + "hookable": "^5.1.2", "knitwork": "^0.1.2", "magic-string": "^0.26.2", "mlly": "^0.5.14", diff --git a/packages/nuxt/src/core/nuxt.ts b/packages/nuxt/src/core/nuxt.ts index f28d634238e..2f3ba9a41ed 100644 --- a/packages/nuxt/src/core/nuxt.ts +++ b/packages/nuxt/src/core/nuxt.ts @@ -8,7 +8,7 @@ import escapeRE from 'escape-string-regexp' import pagesModule from '../pages/module' import metaModule from '../head/module' import componentsModule from '../components/module' -import autoImportsModule from '../auto-imports/module' +import importsModule from '../imports/module' /* eslint-enable */ import { distDir, pkgDir } from '../dirs' import { version } from '../../package.json' @@ -162,7 +162,7 @@ export async function loadNuxt (opts: LoadNuxtOptions): Promise { options.appDir = options.alias['#app'] = resolve(distDir, 'app') options._majorVersion = 3 options._modules.push(pagesModule, metaModule, componentsModule) - options._modules.push([autoImportsModule, { + options._modules.push([importsModule, { transform: { include: options._layers .filter(i => i.cwd && i.cwd.includes('node_modules')) diff --git a/packages/nuxt/src/core/templates.ts b/packages/nuxt/src/core/templates.ts index 15201d8e795..3fa41de712a 100644 --- a/packages/nuxt/src/core/templates.ts +++ b/packages/nuxt/src/core/templates.ts @@ -110,7 +110,7 @@ export { } } } -const adHocModules = ['router', 'pages', 'auto-imports', 'meta', 'components'] +const adHocModules = ['router', 'pages', 'imports', 'meta', 'components'] export const schemaTemplate: NuxtTemplate = { filename: 'types/schema.d.ts', getContents: ({ nuxt }) => { diff --git a/packages/nuxt/src/auto-imports/module.ts b/packages/nuxt/src/imports/module.ts similarity index 76% rename from packages/nuxt/src/auto-imports/module.ts rename to packages/nuxt/src/imports/module.ts index 394a066ed47..2200e0bb328 100644 --- a/packages/nuxt/src/auto-imports/module.ts +++ b/packages/nuxt/src/imports/module.ts @@ -1,14 +1,15 @@ import { addVitePlugin, addWebpackPlugin, defineNuxtModule, addTemplate, resolveAlias, useNuxt, addPluginTemplate, logger } from '@nuxt/kit' import { isAbsolute, join, relative, resolve, normalize } from 'pathe' import { createUnimport, Import, scanDirExports, toImports, Unimport } from 'unimport' -import { AutoImportsOptions, ImportPresetWithDeprecation } from '@nuxt/schema' +import { ImportsOptions, ImportPresetWithDeprecation } from '@nuxt/schema' +import defu from 'defu' import { TransformPlugin } from './transform' import { defaultPresets } from './presets' -export default defineNuxtModule>({ +export default defineNuxtModule>({ meta: { - name: 'auto-imports', - configKey: 'autoImports' + name: 'imports', + configKey: 'imports' }, defaults: { presets: defaultPresets, @@ -21,13 +22,28 @@ export default defineNuxtModule>({ } }, async setup (options, nuxt) { + // TODO: remove deprecation warning + // @ts-ignore + if (nuxt.options.autoImports) { + logger.warn('`autoImports` config is deprecated, use `imports` instead.') + // @ts-ignore + options = defu(nuxt.options.autoImports, options) + } + + // @ts-expect-error + nuxt.hooks.deprecateHooks({ + 'autoImports:sources': { to: 'imports:sources' }, + 'autoImports:dirs': { to: 'imports:dirs' }, + 'autoImports:extend': { to: 'imports:extend' } + }) + // Allow modules extending sources - await nuxt.callHook('autoImports:sources', options.presets as ImportPresetWithDeprecation[]) + await nuxt.callHook('imports:sources', options.presets as ImportPresetWithDeprecation[]) options.presets?.forEach((i: ImportPresetWithDeprecation | string) => { if (typeof i !== 'string' && i.names && !i.imports) { i.imports = i.names - logger.warn('auto-imports: presets.names is deprecated, use presets.imports instead') + logger.warn('imports: presets.names is deprecated, use presets.imports instead') } }) @@ -48,7 +64,7 @@ export default defineNuxtModule>({ let composablesDirs: string[] = [] for (const layer of nuxt.options._layers) { composablesDirs.push(resolve(layer.config.srcDir, 'composables')) - for (const dir of (layer.config.autoImports?.dirs ?? [])) { + for (const dir of (layer.config.imports?.dirs ?? [])) { if (!dir) { continue } @@ -56,13 +72,13 @@ export default defineNuxtModule>({ } } - await nuxt.callHook('autoImports:dirs', composablesDirs) + await nuxt.callHook('imports:dirs', composablesDirs) composablesDirs = composablesDirs.map(dir => normalize(dir)) // Support for importing from '#imports' addTemplate({ filename: 'imports.mjs', - getContents: () => ctx.toExports() + '\nif (process.dev) { console.warn("[nuxt] `#imports` should be transformed with real imports. There seems to be something wrong with the auto-imports plugin.") }' + getContents: () => ctx.toExports() + '\nif (process.dev) { console.warn("[nuxt] `#imports` should be transformed with real imports. There seems to be something wrong with the imports plugin.") }' }) nuxt.options.alias['#imports'] = join(nuxt.options.buildDir, 'imports') @@ -71,7 +87,7 @@ export default defineNuxtModule>({ if (nuxt.options.dev && options.global) { // Add all imports to globalThis in development mode addPluginTemplate({ - filename: 'auto-imports.mjs', + filename: 'imports.mjs', getContents: () => { const imports = ctx.getImports() const importStatement = toImports(imports) @@ -85,24 +101,24 @@ export default defineNuxtModule>({ addWebpackPlugin(TransformPlugin.webpack({ ctx, options, sourcemap: nuxt.options.sourcemap })) } - const regenerateAutoImports = async () => { + const regenerateImports = async () => { ctx.clearDynamicImports() await ctx.modifyDynamicImports(async (imports) => { // Scan composables/ imports.push(...await scanDirExports(composablesDirs)) // Modules extending - await nuxt.callHook('autoImports:extend', imports) + await nuxt.callHook('imports:extend', imports) }) } - await regenerateAutoImports() + await regenerateImports() // Generate types addDeclarationTemplates(ctx) // Add generated types to `nuxt.d.ts` nuxt.hook('prepare:types', ({ references }) => { - references.push({ path: resolve(nuxt.options.buildDir, 'types/auto-imports.d.ts') }) + references.push({ path: resolve(nuxt.options.buildDir, 'types/imports.d.ts') }) references.push({ path: resolve(nuxt.options.buildDir, 'imports.d.ts') }) }) @@ -115,7 +131,7 @@ export default defineNuxtModule>({ }) nuxt.hook('builder:generateApp', async () => { - await regenerateAutoImports() + await regenerateImports() }) } }) @@ -147,7 +163,7 @@ function addDeclarationTemplates (ctx: Unimport) { }) addTemplate({ - filename: 'types/auto-imports.d.ts', + filename: 'types/imports.d.ts', getContents: () => '// Generated by auto imports\n' + ctx.generateTypeDeclarations({ resolvePath: r }) }) } diff --git a/packages/nuxt/src/auto-imports/presets.ts b/packages/nuxt/src/imports/presets.ts similarity index 100% rename from packages/nuxt/src/auto-imports/presets.ts rename to packages/nuxt/src/imports/presets.ts diff --git a/packages/nuxt/src/auto-imports/transform.ts b/packages/nuxt/src/imports/transform.ts similarity index 88% rename from packages/nuxt/src/auto-imports/transform.ts rename to packages/nuxt/src/imports/transform.ts index b7b1195f85d..27c4ed552a3 100644 --- a/packages/nuxt/src/auto-imports/transform.ts +++ b/packages/nuxt/src/imports/transform.ts @@ -2,12 +2,12 @@ import { pathToFileURL } from 'node:url' import { createUnplugin } from 'unplugin' import { parseQuery, parseURL } from 'ufo' import { Unimport } from 'unimport' -import { AutoImportsOptions } from '@nuxt/schema' +import { ImportsOptions } from '@nuxt/schema' import { normalize } from 'pathe' -export const TransformPlugin = createUnplugin(({ ctx, options, sourcemap }: { ctx: Unimport, options: Partial, sourcemap?: boolean }) => { +export const TransformPlugin = createUnplugin(({ ctx, options, sourcemap }: { ctx: Unimport, options: Partial, sourcemap?: boolean }) => { return { - name: 'nuxt:auto-imports-transform', + name: 'nuxt:imports-transform', enforce: 'post', transformInclude (id) { const { pathname, search } = parseURL(decodeURIComponent(pathToFileURL(id).href)) @@ -39,7 +39,7 @@ export const TransformPlugin = createUnplugin(({ ctx, options, sourcemap }: { ct async transform (code, id) { id = normalize(id) const isNodeModule = id.match(/[\\/]node_modules[\\/]/) && !options.transform?.include?.some(pattern => id.match(pattern)) - // For modules in node_modules, we only transform `#imports` but not doing auto-imports + // For modules in node_modules, we only transform `#imports` but not doing imports if (isNodeModule && !code.match(/(['"])#imports\1/)) { return } diff --git a/packages/nuxt/src/pages/module.ts b/packages/nuxt/src/pages/module.ts index 3af9e18062a..6f080c1c312 100644 --- a/packages/nuxt/src/pages/module.ts +++ b/packages/nuxt/src/pages/module.ts @@ -78,8 +78,8 @@ export default defineNuxtModule({ }) } - nuxt.hook('autoImports:extend', (autoImports) => { - autoImports.push( + nuxt.hook('imports:extend', (imports) => { + imports.push( { name: 'definePageMeta', as: 'definePageMeta', from: resolve(runtimeDir, 'composables') }, { name: 'useLink', as: 'useLink', from: 'vue-router' } ) diff --git a/packages/nuxt/test/auto-imports.test.ts b/packages/nuxt/test/auto-imports.test.ts index ec9df68047a..dd30e217856 100644 --- a/packages/nuxt/test/auto-imports.test.ts +++ b/packages/nuxt/test/auto-imports.test.ts @@ -4,10 +4,10 @@ import { join } from 'pathe' import { createCommonJS, findExports } from 'mlly' import * as VueFunctions from 'vue' import { createUnimport, Import } from 'unimport' -import { TransformPlugin } from '../src/auto-imports/transform' -import { defaultPresets } from '../src/auto-imports/presets' +import { TransformPlugin } from '../src/imports/transform' +import { defaultPresets } from '../src/imports/presets' -describe('auto-imports:transform', () => { +describe('imports:transform', () => { const imports: Import[] = [ { name: 'ref', as: 'ref', from: 'vue' }, { name: 'computed', as: 'computed', from: 'bar' }, @@ -54,7 +54,7 @@ describe('auto-imports:transform', () => { const excludedNuxtHelpers = ['useHydration'] -describe('auto-imports:nuxt', () => { +describe('imports:nuxt', () => { try { const { __dirname } = createCommonJS(import.meta.url) const entrypointContents = readFileSync(join(__dirname, '../src/app/composables/index.ts'), 'utf8') @@ -170,7 +170,7 @@ const excludedVueHelpers = [ 'compile' ] -describe('auto-imports:vue', () => { +describe('imports:vue', () => { for (const name of Object.keys(VueFunctions)) { if (excludedVueHelpers.includes(name)) { continue diff --git a/packages/schema/src/config/_adhoc.ts b/packages/schema/src/config/_adhoc.ts index b8e1243ba6f..af4e4707eab 100644 --- a/packages/schema/src/config/_adhoc.ts +++ b/packages/schema/src/config/_adhoc.ts @@ -24,14 +24,17 @@ export default { } }, + /** @deprecated Please use `imports` config. */ + autoImports: null, + /** * Configure how Nuxt auto-imports composables into your application. * * @see [Nuxt 3 documentation](https://v3.nuxtjs.org/guide/directory-structure/composables) - * @type {typeof import('../src/types/imports').AutoImportsOptions} + * @type {typeof import('../src/types/imports').ImportsOptions} * @version 3 */ - autoImports: { + imports: { global: false, dirs: [] }, diff --git a/packages/schema/src/types/hooks.ts b/packages/schema/src/types/hooks.ts index c5818e453ee..42de71a58b1 100644 --- a/packages/schema/src/types/hooks.ts +++ b/packages/schema/src/types/hooks.ts @@ -76,8 +76,15 @@ export interface NuxtHooks { 'build:manifest': (manifest: Manifest) => HookResult // Auto imports + 'imports:sources': (presets: ImportPresetWithDeprecation[]) => HookResult + 'imports:extend': (imports: Import[]) => HookResult + 'imports:dirs': (dirs: string[]) => HookResult + + /** @deprecated Please use `imports:sources` hook */ 'autoImports:sources': (presets: ImportPresetWithDeprecation[]) => HookResult + /** @deprecated Please use `imports:extend` hook */ 'autoImports:extend': (imports: Import[]) => HookResult + /** @deprecated Please use `imports:dirs` hook */ 'autoImports:dirs': (dirs: string[]) => HookResult // Components diff --git a/packages/schema/src/types/imports.ts b/packages/schema/src/types/imports.ts index 45d6f22a5d8..cf416685a48 100644 --- a/packages/schema/src/types/imports.ts +++ b/packages/schema/src/types/imports.ts @@ -1,6 +1,6 @@ import { UnimportOptions } from 'unimport' -export interface AutoImportsOptions extends UnimportOptions { +export interface ImportsOptions extends UnimportOptions { dirs?: string[] global?: boolean transform?: { diff --git a/yarn.lock b/yarn.lock index 1a4c2db7486..d565645fa0c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7849,6 +7849,13 @@ __metadata: languageName: node linkType: hard +"hookable@npm:^5.1.2": + version: 5.1.2 + resolution: "hookable@npm:5.1.2" + checksum: 1b3fb622a26d34c9befe8991cf9ffcb575334ef66e151291bc4b3161e1a609365983d258020571bce4b52226d9b5880150d27ba9f4e4029734e5cd37ac31aa39 + languageName: node + linkType: hard + "hosted-git-info@npm:^2.1.4": version: 2.8.9 resolution: "hosted-git-info@npm:2.8.9" @@ -10266,7 +10273,7 @@ __metadata: globby: ^13.1.2 h3: ^0.7.15 hash-sum: ^2.0.0 - hookable: ^5.1.1 + hookable: ^5.1.2 knitwork: ^0.1.2 magic-string: ^0.26.2 mlly: ^0.5.14