mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-22 13:45:18 +00:00
refactor!: migrate to unimport
(#3386)
This commit is contained in:
parent
c942465f79
commit
cff2f37cc8
@ -1,35 +1,29 @@
|
|||||||
import { installModule, useNuxt } from '@nuxt/kit'
|
import { installModule, useNuxt } from '@nuxt/kit'
|
||||||
import * as CompositionApi from '@vue/composition-api'
|
import * as CompositionApi from '@vue/composition-api'
|
||||||
|
import type { Preset } from 'unimport'
|
||||||
import autoImports from '../../nuxt3/src/auto-imports/module'
|
import autoImports from '../../nuxt3/src/auto-imports/module'
|
||||||
|
import { vuePreset, commonPresets, appPreset } from '../../nuxt3/src/auto-imports/presets'
|
||||||
|
|
||||||
const UnsupportedImports = new Set(['useAsyncData', 'useFetch'])
|
const UnsupportedImports = new Set(['useAsyncData', 'useFetch'])
|
||||||
const CapiHelpers = new Set(Object.keys(CompositionApi))
|
const CapiHelpers = new Set(Object.keys(CompositionApi))
|
||||||
|
|
||||||
const ImportRewrites = {
|
|
||||||
vue: '@vue/composition-api'
|
|
||||||
}
|
|
||||||
|
|
||||||
export function setupAutoImports () {
|
export function setupAutoImports () {
|
||||||
const nuxt = useNuxt()
|
const nuxt = useNuxt()
|
||||||
|
|
||||||
nuxt.hook('autoImports:extend', (autoImports) => {
|
const bridgePresets: Preset[] = [
|
||||||
for (const autoImport of autoImports) {
|
...commonPresets,
|
||||||
// Rewrite imports
|
{
|
||||||
if (autoImport.from in ImportRewrites) {
|
from: '#app',
|
||||||
autoImport.from = ImportRewrites[autoImport.from]
|
imports: [
|
||||||
}
|
...appPreset.imports.filter(i => !UnsupportedImports.has(i as string)),
|
||||||
// Disable unsupported imports
|
'useNuxt2Meta'
|
||||||
if (UnsupportedImports.has(autoImport.name)) {
|
]
|
||||||
autoImport.disabled = true
|
},
|
||||||
}
|
{
|
||||||
if (autoImport.from === '@vue/composition-api' && !CapiHelpers.has(autoImport.name)) {
|
from: '@vue/composition-api',
|
||||||
autoImport.disabled = true
|
imports: vuePreset.imports.filter(i => CapiHelpers.has(i as string))
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
]
|
||||||
|
|
||||||
// Add bridge-only auto-imports
|
nuxt.hook('modules:done', () => installModule(autoImports, { presets: bridgePresets }))
|
||||||
autoImports.push({ name: 'useNuxt2Meta', as: 'useNuxt2Meta', from: '#app' })
|
|
||||||
})
|
|
||||||
|
|
||||||
nuxt.hook('modules:done', () => installModule(autoImports))
|
|
||||||
}
|
}
|
||||||
|
@ -1,30 +0,0 @@
|
|||||||
import * as CompositionApi from '@vue/composition-api'
|
|
||||||
import { expect, describe, it } from 'vitest'
|
|
||||||
|
|
||||||
import { Nuxt3AutoImports } from '../../nuxt3/src/auto-imports/imports'
|
|
||||||
|
|
||||||
const excludedVueHelpers = [
|
|
||||||
'EffectScope',
|
|
||||||
'createApp',
|
|
||||||
'createRef',
|
|
||||||
'default',
|
|
||||||
'del',
|
|
||||||
'isRaw',
|
|
||||||
'set',
|
|
||||||
'useCSSModule',
|
|
||||||
'version',
|
|
||||||
'warn',
|
|
||||||
'watchPostEffect',
|
|
||||||
'watchSyncEffect'
|
|
||||||
]
|
|
||||||
|
|
||||||
describe('auto-imports:vue', () => {
|
|
||||||
for (const name of Object.keys(CompositionApi)) {
|
|
||||||
if (excludedVueHelpers.includes(name)) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
it(`should register ${name} globally`, () => {
|
|
||||||
expect(Nuxt3AutoImports.find(a => a.from === 'vue').names).to.include(name)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
@ -29,6 +29,7 @@
|
|||||||
"scule": "^0.2.1",
|
"scule": "^0.2.1",
|
||||||
"semver": "^7.3.5",
|
"semver": "^7.3.5",
|
||||||
"unctx": "^1.0.2",
|
"unctx": "^1.0.2",
|
||||||
|
"unimport": "0.0.8",
|
||||||
"untyped": "^0.4.2"
|
"untyped": "^0.4.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
@ -1,14 +1,12 @@
|
|||||||
import type { AutoImport } from '../../schema/src/types/imports'
|
import { Import } from 'unimport'
|
||||||
import { useNuxt } from './context'
|
import { useNuxt } from './context'
|
||||||
import { assertNuxtCompatibility } from './compatibility'
|
import { assertNuxtCompatibility } from './compatibility'
|
||||||
|
|
||||||
export function addAutoImport (_autoImports: AutoImport | AutoImport[]) {
|
export function addAutoImport (imports: Import | Import[]) {
|
||||||
assertNuxtCompatibility({ bridge: true })
|
assertNuxtCompatibility({ bridge: true })
|
||||||
|
|
||||||
useNuxt().hook('autoImports:extend', (autoImports: AutoImport[]) => {
|
useNuxt().hook('autoImports:extend', (autoImports) => {
|
||||||
for (const composable of (Array.isArray(_autoImports) ? _autoImports : [_autoImports])) {
|
autoImports.push(...(Array.isArray(imports) ? imports : [imports]))
|
||||||
autoImports.push(composable)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,6 +58,7 @@
|
|||||||
"pathe": "^0.2.0",
|
"pathe": "^0.2.0",
|
||||||
"scule": "^0.2.1",
|
"scule": "^0.2.1",
|
||||||
"ufo": "^0.7.11",
|
"ufo": "^0.7.11",
|
||||||
|
"unimport": "0.0.8",
|
||||||
"unplugin": "^0.4.0",
|
"unplugin": "^0.4.0",
|
||||||
"untyped": "^0.4.2",
|
"untyped": "^0.4.2",
|
||||||
"vue": "^3.2.31",
|
"vue": "^3.2.31",
|
||||||
|
@ -2,44 +2,45 @@ import { promises as fsp, existsSync } from 'fs'
|
|||||||
import { parse as parsePath } from 'pathe'
|
import { parse as parsePath } from 'pathe'
|
||||||
import { findExports } from 'mlly'
|
import { findExports } from 'mlly'
|
||||||
import { camelCase } from 'scule'
|
import { camelCase } from 'scule'
|
||||||
import { AutoImport } from '@nuxt/schema'
|
|
||||||
import { resolveFiles } from '@nuxt/kit'
|
import { resolveFiles } from '@nuxt/kit'
|
||||||
import { filterInPlace } from './utils'
|
import { Unimport } from 'unimport'
|
||||||
|
|
||||||
export async function scanForComposables (dir: string | string[], autoImports: AutoImport[]) {
|
export async function scanForComposables (dir: string | string[], ctx: Unimport) {
|
||||||
const performScan = async (entry: string) => {
|
const performScan = async (entry: string) => {
|
||||||
const files = await resolveFiles(entry, [
|
const files = await resolveFiles(entry, [
|
||||||
'*.{ts,js,mjs,cjs,mts,cts}',
|
'*.{ts,js,mjs,cjs,mts,cts}',
|
||||||
'*/index.{ts,js,mjs,cjs,mts,cts}'
|
'*/index.{ts,js,mjs,cjs,mts,cts}'
|
||||||
])
|
])
|
||||||
|
|
||||||
await Promise.all(
|
await ctx.modifyDynamicImports(async (dynamicImports) => {
|
||||||
files.map(async (path) => {
|
await Promise.all(
|
||||||
// Remove original entries from the same import (for build watcher)
|
files.map(async (path) => {
|
||||||
filterInPlace(autoImports, i => i.from !== path)
|
// Remove original entries from the same import (for build watcher)
|
||||||
|
filterInPlace(dynamicImports, i => i.from !== path)
|
||||||
|
|
||||||
const code = await fsp.readFile(path, '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) {
|
||||||
let name = parsePath(path).name
|
let name = parsePath(path).name
|
||||||
if (name === 'index') {
|
if (name === 'index') {
|
||||||
name = parsePath(path.split('/').slice(0, -1).join('/')).name
|
name = parsePath(path.split('/').slice(0, -1).join('/')).name
|
||||||
}
|
|
||||||
autoImports.push({ name: 'default', as: camelCase(name), from: path })
|
|
||||||
}
|
|
||||||
for (const exp of exports) {
|
|
||||||
if (exp.type === 'named') {
|
|
||||||
for (const name of exp.names) {
|
|
||||||
autoImports.push({ name, as: name, from: path })
|
|
||||||
}
|
}
|
||||||
} else if (exp.type === 'declaration') {
|
dynamicImports.push({ name: 'default', as: camelCase(name), from: path })
|
||||||
autoImports.push({ name: exp.name, as: exp.name, from: path })
|
|
||||||
}
|
}
|
||||||
}
|
for (const exp of exports) {
|
||||||
})
|
if (exp.type === 'named') {
|
||||||
)
|
for (const name of exp.names) {
|
||||||
|
dynamicImports.push({ name, as: name, from: path })
|
||||||
|
}
|
||||||
|
} else if (exp.type === 'declaration') {
|
||||||
|
dynamicImports.push({ name: exp.name, as: exp.name, from: path })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const entry of Array.isArray(dir) ? dir : [dir]) {
|
for (const entry of Array.isArray(dir) ? dir : [dir]) {
|
||||||
@ -48,3 +49,12 @@ export async function scanForComposables (dir: string | string[], autoImports: A
|
|||||||
await performScan(entry)
|
await performScan(entry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function filterInPlace<T> (arr: T[], predicate: (v: T) => any) {
|
||||||
|
let i = arr.length
|
||||||
|
while (i--) {
|
||||||
|
if (!predicate(arr[i])) {
|
||||||
|
arr.splice(i, 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,49 +0,0 @@
|
|||||||
import type { AutoImport } from '@nuxt/schema'
|
|
||||||
import escapeRE from 'escape-string-regexp'
|
|
||||||
|
|
||||||
export interface AutoImportContext {
|
|
||||||
autoImports: AutoImport[]
|
|
||||||
matchRE: RegExp
|
|
||||||
transform: {
|
|
||||||
exclude: RegExp[]
|
|
||||||
}
|
|
||||||
map: Map<string, AutoImport>
|
|
||||||
}
|
|
||||||
|
|
||||||
export function createAutoImportContext (opts): AutoImportContext {
|
|
||||||
return {
|
|
||||||
autoImports: [],
|
|
||||||
map: new Map(),
|
|
||||||
matchRE: /__never__/,
|
|
||||||
transform: {
|
|
||||||
exclude: opts.transform.exclude || [/node_modules/]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function updateAutoImportContext (ctx: AutoImportContext) {
|
|
||||||
// Detect duplicates
|
|
||||||
const usedNames = new Set()
|
|
||||||
for (const autoImport of ctx.autoImports) {
|
|
||||||
if (usedNames.has(autoImport.as)) {
|
|
||||||
autoImport.disabled = true
|
|
||||||
console.warn(`Disabling duplicate auto import '${autoImport.as}' (imported from '${autoImport.from}')`)
|
|
||||||
} else {
|
|
||||||
usedNames.add(autoImport.as)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Filter out disabled auto imports
|
|
||||||
ctx.autoImports = ctx.autoImports.filter(i => i.disabled !== true)
|
|
||||||
|
|
||||||
// Create regex
|
|
||||||
ctx.matchRE = new RegExp(`\\b(${ctx.autoImports.map(i => escapeRE(i.as)).join('|')})\\b`, 'g')
|
|
||||||
|
|
||||||
// Create map
|
|
||||||
ctx.map.clear()
|
|
||||||
for (const autoImport of ctx.autoImports) {
|
|
||||||
ctx.map.set(autoImport.as, autoImport)
|
|
||||||
}
|
|
||||||
|
|
||||||
return ctx
|
|
||||||
}
|
|
@ -1,113 +0,0 @@
|
|||||||
import type { AutoImportSource } from '@nuxt/schema'
|
|
||||||
|
|
||||||
export const Nuxt3AutoImports: AutoImportSource[] = [
|
|
||||||
// #app
|
|
||||||
{
|
|
||||||
from: '#app',
|
|
||||||
names: [
|
|
||||||
'useAsyncData',
|
|
||||||
'useLazyAsyncData',
|
|
||||||
'defineNuxtComponent',
|
|
||||||
'useNuxtApp',
|
|
||||||
'defineNuxtPlugin',
|
|
||||||
'useRuntimeConfig',
|
|
||||||
'useState',
|
|
||||||
'useFetch',
|
|
||||||
'useLazyFetch',
|
|
||||||
'useCookie',
|
|
||||||
'useRequestHeaders',
|
|
||||||
'useRouter',
|
|
||||||
'useRoute',
|
|
||||||
'defineNuxtRouteMiddleware',
|
|
||||||
'navigateTo',
|
|
||||||
'abortNavigation',
|
|
||||||
'addRouteMiddleware'
|
|
||||||
]
|
|
||||||
},
|
|
||||||
// #meta
|
|
||||||
{
|
|
||||||
from: '#meta',
|
|
||||||
names: [
|
|
||||||
'useMeta'
|
|
||||||
]
|
|
||||||
},
|
|
||||||
// vue-demi (mocked)
|
|
||||||
{
|
|
||||||
from: 'vue-demi',
|
|
||||||
names: [
|
|
||||||
'isVue2',
|
|
||||||
'isVue3'
|
|
||||||
]
|
|
||||||
},
|
|
||||||
// vue
|
|
||||||
{
|
|
||||||
from: 'vue',
|
|
||||||
names: [
|
|
||||||
// <script setup>
|
|
||||||
'withCtx',
|
|
||||||
'withDirectives',
|
|
||||||
'withKeys',
|
|
||||||
'withMemo',
|
|
||||||
'withModifiers',
|
|
||||||
'withScopeId',
|
|
||||||
|
|
||||||
// Lifecycle
|
|
||||||
'onActivated',
|
|
||||||
'onBeforeMount',
|
|
||||||
'onBeforeUnmount',
|
|
||||||
'onBeforeUpdate',
|
|
||||||
'onDeactivated',
|
|
||||||
'onErrorCaptured',
|
|
||||||
'onMounted',
|
|
||||||
'onRenderTracked',
|
|
||||||
'onRenderTriggered',
|
|
||||||
'onServerPrefetch',
|
|
||||||
'onUnmounted',
|
|
||||||
'onUpdated',
|
|
||||||
|
|
||||||
// Reactivity
|
|
||||||
'computed',
|
|
||||||
'customRef',
|
|
||||||
'isProxy',
|
|
||||||
'isReactive',
|
|
||||||
'isReadonly',
|
|
||||||
'isRef',
|
|
||||||
'markRaw',
|
|
||||||
'proxyRefs',
|
|
||||||
'reactive',
|
|
||||||
'readonly',
|
|
||||||
'ref',
|
|
||||||
'shallowReactive',
|
|
||||||
'shallowReadonly',
|
|
||||||
'shallowRef',
|
|
||||||
'toRaw',
|
|
||||||
'toRef',
|
|
||||||
'toRefs',
|
|
||||||
'triggerRef',
|
|
||||||
'unref',
|
|
||||||
'watch',
|
|
||||||
'watchEffect',
|
|
||||||
'isShallow',
|
|
||||||
|
|
||||||
// effect
|
|
||||||
'effect',
|
|
||||||
'effectScope',
|
|
||||||
'getCurrentScope',
|
|
||||||
'onScopeDispose',
|
|
||||||
|
|
||||||
// Component
|
|
||||||
'defineComponent',
|
|
||||||
'defineAsyncComponent',
|
|
||||||
'getCurrentInstance',
|
|
||||||
'h',
|
|
||||||
'inject',
|
|
||||||
'nextTick',
|
|
||||||
'provide',
|
|
||||||
'useAttrs',
|
|
||||||
'useCssModule',
|
|
||||||
'useCssVars',
|
|
||||||
'useSlots',
|
|
||||||
'useTransitionState'
|
|
||||||
] as Array<keyof typeof import('vue')>
|
|
||||||
}
|
|
||||||
]
|
|
@ -1,21 +1,20 @@
|
|||||||
import { addVitePlugin, addWebpackPlugin, defineNuxtModule, addTemplate, resolveAlias, addPluginTemplate, useNuxt } from '@nuxt/kit'
|
import { addVitePlugin, addWebpackPlugin, defineNuxtModule, addTemplate, resolveAlias, useNuxt, addPluginTemplate, logger } from '@nuxt/kit'
|
||||||
import type { AutoImportsOptions } from '@nuxt/schema'
|
|
||||||
import { isAbsolute, join, relative, resolve, normalize } from 'pathe'
|
import { isAbsolute, join, relative, resolve, normalize } from 'pathe'
|
||||||
import { genDynamicImport } from 'knitwork'
|
import { createUnimport, Import, toImports, Unimport } from 'unimport'
|
||||||
|
import { AutoImportsOptions, ImportPresetWithDeperection } from '@nuxt/schema'
|
||||||
import { TransformPlugin } from './transform'
|
import { TransformPlugin } from './transform'
|
||||||
import { Nuxt3AutoImports } from './imports'
|
import { defaultPresets } from './presets'
|
||||||
import { scanForComposables } from './composables'
|
import { scanForComposables } from './composables'
|
||||||
import { toExports, toImports } from './utils'
|
|
||||||
import { AutoImportContext, createAutoImportContext, updateAutoImportContext } from './context'
|
|
||||||
|
|
||||||
export default defineNuxtModule<AutoImportsOptions>({
|
export default defineNuxtModule<Partial<AutoImportsOptions>>({
|
||||||
meta: {
|
meta: {
|
||||||
name: 'auto-imports',
|
name: 'auto-imports',
|
||||||
configKey: 'autoImports'
|
configKey: 'autoImports'
|
||||||
},
|
},
|
||||||
defaults: {
|
defaults: {
|
||||||
sources: Nuxt3AutoImports,
|
presets: defaultPresets,
|
||||||
global: false,
|
global: false,
|
||||||
|
imports: [],
|
||||||
dirs: [],
|
dirs: [],
|
||||||
transform: {
|
transform: {
|
||||||
exclude: undefined
|
exclude: undefined
|
||||||
@ -23,13 +22,23 @@ export default defineNuxtModule<AutoImportsOptions>({
|
|||||||
},
|
},
|
||||||
async setup (options, nuxt) {
|
async setup (options, nuxt) {
|
||||||
// Allow modules extending sources
|
// Allow modules extending sources
|
||||||
await nuxt.callHook('autoImports:sources', options.sources)
|
await nuxt.callHook('autoImports:sources', options.presets as ImportPresetWithDeperection[])
|
||||||
|
|
||||||
|
options.presets.forEach((i: ImportPresetWithDeperection) => {
|
||||||
|
if (typeof i !== 'string' && i.names && !i.imports) {
|
||||||
|
i.imports = i.names
|
||||||
|
logger.warn('auto-imports: presets.names is deprecated, use presets.imports instead')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
// Filter disabled sources
|
// Filter disabled sources
|
||||||
options.sources = options.sources.filter(source => source.disabled !== true)
|
// options.sources = options.sources.filter(source => source.disabled !== true)
|
||||||
|
|
||||||
// Create a context to share state between module internals
|
// Create a context to share state between module internals
|
||||||
const ctx = createAutoImportContext(options)
|
const ctx = createUnimport({
|
||||||
|
presets: defaultPresets,
|
||||||
|
imports: options.imports
|
||||||
|
})
|
||||||
|
|
||||||
// composables/ dirs
|
// composables/ dirs
|
||||||
let composablesDirs = [
|
let composablesDirs = [
|
||||||
@ -51,7 +60,7 @@ export default defineNuxtModule<AutoImportsOptions>({
|
|||||||
// Support for importing from '#imports'
|
// Support for importing from '#imports'
|
||||||
addTemplate({
|
addTemplate({
|
||||||
filename: 'imports.mjs',
|
filename: 'imports.mjs',
|
||||||
getContents: () => toExports(ctx.autoImports)
|
getContents: () => ctx.toExports()
|
||||||
})
|
})
|
||||||
nuxt.options.alias['#imports'] = join(nuxt.options.buildDir, 'imports')
|
nuxt.options.alias['#imports'] = join(nuxt.options.buildDir, 'imports')
|
||||||
|
|
||||||
@ -62,30 +71,25 @@ export default defineNuxtModule<AutoImportsOptions>({
|
|||||||
addPluginTemplate({
|
addPluginTemplate({
|
||||||
filename: 'auto-imports.mjs',
|
filename: 'auto-imports.mjs',
|
||||||
getContents: () => {
|
getContents: () => {
|
||||||
const imports = toImports(ctx.autoImports)
|
const imports = ctx.getImports()
|
||||||
const globalThisSet = ctx.autoImports.map(i => `globalThis.${i.as} = ${i.as};`).join('\n')
|
const importStatement = toImports(imports)
|
||||||
return `${imports}\n\n${globalThisSet}\n\nexport default () => {};`
|
const globalThisSet = imports.map(i => `globalThis.${i.as} = ${i.as};`).join('\n')
|
||||||
|
return `${importStatement}\n\n${globalThisSet}\n\nexport default () => {};`
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
// Transform to inject imports in production mode
|
// Transform to inject imports in production mode
|
||||||
addVitePlugin(TransformPlugin.vite(ctx))
|
addVitePlugin(TransformPlugin.vite({ ctx, options }))
|
||||||
addWebpackPlugin(TransformPlugin.webpack(ctx))
|
addWebpackPlugin(TransformPlugin.webpack({ ctx, options }))
|
||||||
}
|
}
|
||||||
|
|
||||||
const regenerateAutoImports = async () => {
|
const regenerateAutoImports = async () => {
|
||||||
// Resolve autoimports from sources
|
|
||||||
ctx.autoImports = options.sources.flatMap(source => source.names.map(
|
|
||||||
importName => typeof importName === 'string'
|
|
||||||
? { name: importName, as: importName, from: source.from }
|
|
||||||
: { name: importName.name, as: importName.as || importName.name, from: source.from }
|
|
||||||
))
|
|
||||||
// Scan composables/
|
// Scan composables/
|
||||||
await scanForComposables(composablesDirs, ctx.autoImports)
|
await scanForComposables(composablesDirs, ctx)
|
||||||
// Allow modules extending
|
// Allow modules extending
|
||||||
await nuxt.callHook('autoImports:extend', ctx.autoImports)
|
await ctx.modifyDynamicImports(async (imports) => {
|
||||||
// Update context
|
await nuxt.callHook('autoImports:extend', imports)
|
||||||
updateAutoImportContext(ctx)
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
await regenerateAutoImports()
|
await regenerateAutoImports()
|
||||||
@ -113,37 +117,34 @@ export default defineNuxtModule<AutoImportsOptions>({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
function addDeclarationTemplates (ctx: AutoImportContext) {
|
function addDeclarationTemplates (ctx: Unimport) {
|
||||||
const nuxt = useNuxt()
|
const nuxt = useNuxt()
|
||||||
|
|
||||||
// Remove file extension for benefit of TypeScript
|
// Remove file extension for benefit of TypeScript
|
||||||
const stripExtension = (path: string) => path.replace(/\.[a-z]+$/, '')
|
const stripExtension = (path: string) => path.replace(/\.[a-z]+$/, '')
|
||||||
|
|
||||||
const resolved = {}
|
const resolved = {}
|
||||||
const r = (id: string) => {
|
const r = ({ from }: Import) => {
|
||||||
if (resolved[id]) { return resolved[id] }
|
if (resolved[from]) {
|
||||||
let path = resolveAlias(id)
|
return resolved[from]
|
||||||
|
}
|
||||||
|
let path = resolveAlias(from)
|
||||||
if (isAbsolute(path)) {
|
if (isAbsolute(path)) {
|
||||||
path = relative(join(nuxt.options.buildDir, 'types'), path)
|
path = relative(join(nuxt.options.buildDir, 'types'), path)
|
||||||
}
|
}
|
||||||
|
|
||||||
path = stripExtension(path)
|
path = stripExtension(path)
|
||||||
resolved[id] = path
|
resolved[from] = path
|
||||||
return path
|
return path
|
||||||
}
|
}
|
||||||
|
|
||||||
addTemplate({
|
addTemplate({
|
||||||
filename: 'imports.d.ts',
|
filename: 'imports.d.ts',
|
||||||
getContents: () => toExports(ctx.autoImports.map(i => ({ ...i, from: stripExtension(i.from) })))
|
getContents: () => ctx.toExports()
|
||||||
})
|
})
|
||||||
|
|
||||||
addTemplate({
|
addTemplate({
|
||||||
filename: 'types/auto-imports.d.ts',
|
filename: 'types/auto-imports.d.ts',
|
||||||
getContents: () => `// Generated by auto imports
|
getContents: () => '// Generated by auto imports\n' + ctx.generateTypeDecarations(r)
|
||||||
declare global {
|
|
||||||
${ctx.autoImports.map(i => ` const ${i.as}: typeof ${genDynamicImport(r(i.from), { wrapper: false })}['${i.name}']`).join('\n')}
|
|
||||||
}
|
|
||||||
|
|
||||||
export {}
|
|
||||||
`
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
120
packages/nuxt3/src/auto-imports/presets.ts
Normal file
120
packages/nuxt3/src/auto-imports/presets.ts
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
import { defineUnimportPreset } from 'unimport'
|
||||||
|
|
||||||
|
export const commonPresets = [
|
||||||
|
// #meta
|
||||||
|
defineUnimportPreset({
|
||||||
|
from: '#meta',
|
||||||
|
imports: [
|
||||||
|
'useMeta'
|
||||||
|
]
|
||||||
|
}),
|
||||||
|
// vue-demi (mocked)
|
||||||
|
defineUnimportPreset({
|
||||||
|
from: 'vue-demi',
|
||||||
|
imports: [
|
||||||
|
'isVue2',
|
||||||
|
'isVue3'
|
||||||
|
]
|
||||||
|
})
|
||||||
|
]
|
||||||
|
|
||||||
|
export const appPreset = defineUnimportPreset({
|
||||||
|
from: '#app',
|
||||||
|
imports: [
|
||||||
|
'useAsyncData',
|
||||||
|
'useLazyAsyncData',
|
||||||
|
'defineNuxtComponent',
|
||||||
|
'useNuxtApp',
|
||||||
|
'defineNuxtPlugin',
|
||||||
|
'useRuntimeConfig',
|
||||||
|
'useState',
|
||||||
|
'useFetch',
|
||||||
|
'useLazyFetch',
|
||||||
|
'useCookie',
|
||||||
|
'useRequestHeaders',
|
||||||
|
'useRouter',
|
||||||
|
'useRoute',
|
||||||
|
'defineNuxtRouteMiddleware',
|
||||||
|
'navigateTo',
|
||||||
|
'abortNavigation',
|
||||||
|
'addRouteMiddleware'
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
// vue
|
||||||
|
export const vuePreset = defineUnimportPreset({
|
||||||
|
from: 'vue',
|
||||||
|
imports: [
|
||||||
|
// <script setup>
|
||||||
|
'withCtx',
|
||||||
|
'withDirectives',
|
||||||
|
'withKeys',
|
||||||
|
'withMemo',
|
||||||
|
'withModifiers',
|
||||||
|
'withScopeId',
|
||||||
|
|
||||||
|
// Lifecycle
|
||||||
|
'onActivated',
|
||||||
|
'onBeforeMount',
|
||||||
|
'onBeforeUnmount',
|
||||||
|
'onBeforeUpdate',
|
||||||
|
'onDeactivated',
|
||||||
|
'onErrorCaptured',
|
||||||
|
'onMounted',
|
||||||
|
'onRenderTracked',
|
||||||
|
'onRenderTriggered',
|
||||||
|
'onServerPrefetch',
|
||||||
|
'onUnmounted',
|
||||||
|
'onUpdated',
|
||||||
|
|
||||||
|
// Reactivity
|
||||||
|
'computed',
|
||||||
|
'customRef',
|
||||||
|
'isProxy',
|
||||||
|
'isReactive',
|
||||||
|
'isReadonly',
|
||||||
|
'isRef',
|
||||||
|
'markRaw',
|
||||||
|
'proxyRefs',
|
||||||
|
'reactive',
|
||||||
|
'readonly',
|
||||||
|
'ref',
|
||||||
|
'shallowReactive',
|
||||||
|
'shallowReadonly',
|
||||||
|
'shallowRef',
|
||||||
|
'toRaw',
|
||||||
|
'toRef',
|
||||||
|
'toRefs',
|
||||||
|
'triggerRef',
|
||||||
|
'unref',
|
||||||
|
'watch',
|
||||||
|
'watchEffect',
|
||||||
|
'isShallow',
|
||||||
|
|
||||||
|
// effect
|
||||||
|
'effect',
|
||||||
|
'effectScope',
|
||||||
|
'getCurrentScope',
|
||||||
|
'onScopeDispose',
|
||||||
|
|
||||||
|
// Component
|
||||||
|
'defineComponent',
|
||||||
|
'defineAsyncComponent',
|
||||||
|
'getCurrentInstance',
|
||||||
|
'h',
|
||||||
|
'inject',
|
||||||
|
'nextTick',
|
||||||
|
'provide',
|
||||||
|
'useAttrs',
|
||||||
|
'useCssModule',
|
||||||
|
'useCssVars',
|
||||||
|
'useSlots',
|
||||||
|
'useTransitionState'
|
||||||
|
] as Array<keyof typeof import('vue')>
|
||||||
|
})
|
||||||
|
|
||||||
|
export const defaultPresets = [
|
||||||
|
...commonPresets,
|
||||||
|
appPreset,
|
||||||
|
vuePreset
|
||||||
|
]
|
@ -1,37 +1,9 @@
|
|||||||
import { createUnplugin } from 'unplugin'
|
import { createUnplugin } from 'unplugin'
|
||||||
import { parseQuery, parseURL } from 'ufo'
|
import { parseQuery, parseURL } from 'ufo'
|
||||||
import { toImports } from './utils'
|
import { Unimport } from 'unimport'
|
||||||
import { AutoImportContext } from './context'
|
import { AutoImportsOptions } from '@nuxt/schema'
|
||||||
|
|
||||||
const excludeRE = [
|
export const TransformPlugin = createUnplugin(({ ctx, options }: {ctx: Unimport, options: Partial<AutoImportsOptions> }) => {
|
||||||
// imported from other module
|
|
||||||
/\bimport\s*([\s\S]+?)\s*from\b/g,
|
|
||||||
// defined as function
|
|
||||||
/\bfunction\s*([\w_$]+?)\s*\(/g,
|
|
||||||
// defined as local variable
|
|
||||||
/\b(?:const|let|var)\s+?(\[[\s\S]*?\]|\{[\s\S]*?\}|[\s\S]+?)\s*?[=;\n]/g
|
|
||||||
]
|
|
||||||
|
|
||||||
const importAsRE = /^.*\sas\s+/
|
|
||||||
const separatorRE = /[,[\]{}\n]/g
|
|
||||||
const multilineCommentsRE = /\/\*\s(.|[\r\n])*?\*\//gm
|
|
||||||
const singlelineCommentsRE = /\/\/\s.*$/gm
|
|
||||||
const templateLiteralRE = /\$\{(.*)\}/g
|
|
||||||
const quotesRE = [
|
|
||||||
/(["'])((?:\\\1|(?!\1)|.|\r)*?)\1/gm,
|
|
||||||
/([`])((?:\\\1|(?!\1)|.|\n|\r)*?)\1/gm
|
|
||||||
]
|
|
||||||
|
|
||||||
function stripCommentsAndStrings (code: string) {
|
|
||||||
return code
|
|
||||||
.replace(multilineCommentsRE, '')
|
|
||||||
.replace(singlelineCommentsRE, '')
|
|
||||||
.replace(templateLiteralRE, '` + $1 + `')
|
|
||||||
.replace(quotesRE[0], '""')
|
|
||||||
.replace(quotesRE[1], '``')
|
|
||||||
}
|
|
||||||
|
|
||||||
export const TransformPlugin = createUnplugin((ctx: AutoImportContext) => {
|
|
||||||
return {
|
return {
|
||||||
name: 'nuxt:auto-imports-transform',
|
name: 'nuxt:auto-imports-transform',
|
||||||
enforce: 'post',
|
enforce: 'post',
|
||||||
@ -39,8 +11,10 @@ export const TransformPlugin = createUnplugin((ctx: AutoImportContext) => {
|
|||||||
const { pathname, search } = parseURL(id)
|
const { pathname, search } = parseURL(id)
|
||||||
const { type, macro } = parseQuery(search)
|
const { type, macro } = parseQuery(search)
|
||||||
|
|
||||||
|
const exclude = options.transform?.exclude || [/[\\/]node_modules[\\/]/]
|
||||||
|
|
||||||
// Exclude node_modules by default
|
// Exclude node_modules by default
|
||||||
if (ctx.transform.exclude.some(pattern => id.match(pattern))) {
|
if (exclude.some(pattern => id.match(pattern))) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,35 +31,15 @@ export const TransformPlugin = createUnplugin((ctx: AutoImportContext) => {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
transform (code) {
|
async transform (_code, id) {
|
||||||
// strip comments so we don't match on them
|
const { code, s } = await ctx.injectImports(_code)
|
||||||
const stripped = stripCommentsAndStrings(code)
|
if (code === _code) {
|
||||||
|
return
|
||||||
// find all possible injection
|
|
||||||
const matched = new Set(Array.from(stripped.matchAll(ctx.matchRE)).map(i => i[1]))
|
|
||||||
|
|
||||||
// remove those already defined
|
|
||||||
for (const regex of excludeRE) {
|
|
||||||
Array.from(stripped.matchAll(regex))
|
|
||||||
.flatMap(i => [
|
|
||||||
...(i[1]?.split(separatorRE) || []),
|
|
||||||
...(i[2]?.split(separatorRE) || [])
|
|
||||||
])
|
|
||||||
.map(i => i.replace(importAsRE, '').trim())
|
|
||||||
.forEach(i => matched.delete(i))
|
|
||||||
}
|
}
|
||||||
|
return {
|
||||||
if (!matched.size) {
|
code,
|
||||||
return null
|
map: s.generateMap({ source: id, includeContent: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
// For webpack4/bridge support
|
|
||||||
const isCJSContext = stripped.includes('require(')
|
|
||||||
|
|
||||||
const matchedImports = Array.from(matched).map(name => ctx.map.get(name)).filter(Boolean)
|
|
||||||
const imports = toImports(matchedImports, isCJSContext)
|
|
||||||
|
|
||||||
return imports + code
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -1,47 +0,0 @@
|
|||||||
import type { AutoImport } from '@nuxt/schema'
|
|
||||||
import { genExport, genImport, genString } from 'knitwork'
|
|
||||||
|
|
||||||
export function toImportModuleMap (autoImports: AutoImport[], isCJS = false) {
|
|
||||||
const aliasKeyword = isCJS ? ' : ' : ' as '
|
|
||||||
const map: Record<string, Set<string>> = {}
|
|
||||||
for (const autoImport of autoImports) {
|
|
||||||
if (!map[autoImport.from]) {
|
|
||||||
map[autoImport.from] = new Set()
|
|
||||||
}
|
|
||||||
map[autoImport.from].add(
|
|
||||||
autoImport.name === autoImport.as
|
|
||||||
? autoImport.name
|
|
||||||
: autoImport.name + aliasKeyword + autoImport.as
|
|
||||||
)
|
|
||||||
}
|
|
||||||
return map
|
|
||||||
}
|
|
||||||
|
|
||||||
export function toImports (autoImports: AutoImport[], isCJS = false) {
|
|
||||||
const map = toImportModuleMap(autoImports, isCJS)
|
|
||||||
if (isCJS) {
|
|
||||||
return Object.entries(map)
|
|
||||||
.map(([name, imports]) => `const { ${Array.from(imports).join(', ')} } = require(${genString(name)});`)
|
|
||||||
.join('\n')
|
|
||||||
} else {
|
|
||||||
return Object.entries(map)
|
|
||||||
.map(([name, imports]) => genImport(name, Array.from(imports)))
|
|
||||||
.join('\n')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function toExports (autoImports: AutoImport[]) {
|
|
||||||
const map = toImportModuleMap(autoImports, false)
|
|
||||||
return Object.entries(map)
|
|
||||||
.map(([name, imports]) => genExport(name, Array.from(imports)))
|
|
||||||
.join('\n')
|
|
||||||
}
|
|
||||||
|
|
||||||
export function filterInPlace<T> (arr: T[], predicate: (v: T) => any) {
|
|
||||||
let i = arr.length
|
|
||||||
while (i--) {
|
|
||||||
if (!predicate(arr[i])) {
|
|
||||||
arr.splice(i, 1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,35 +1,32 @@
|
|||||||
import { readFileSync } from 'fs'
|
import { readFileSync } from 'fs'
|
||||||
import type { AutoImport } from '@nuxt/schema'
|
|
||||||
import { expect, describe, it } from 'vitest'
|
import { expect, describe, it } from 'vitest'
|
||||||
import { join } from 'pathe'
|
import { join } from 'pathe'
|
||||||
import { createCommonJS, findExports } from 'mlly'
|
import { createCommonJS, findExports } from 'mlly'
|
||||||
import * as VueFunctions from 'vue'
|
import * as VueFunctions from 'vue'
|
||||||
import { AutoImportContext, updateAutoImportContext } from '../src/auto-imports/context'
|
import { createUnimport, Import } from 'unimport'
|
||||||
import { TransformPlugin } from '../src/auto-imports/transform'
|
import { TransformPlugin } from '../src/auto-imports/transform'
|
||||||
import { Nuxt3AutoImports } from '../src/auto-imports/imports'
|
import { defaultPresets } from '../src/auto-imports/presets'
|
||||||
|
|
||||||
describe('auto-imports:transform', () => {
|
describe('auto-imports:transform', () => {
|
||||||
const autoImports: AutoImport[] = [
|
const imports: Import[] = [
|
||||||
{ name: 'ref', as: 'ref', from: 'vue' },
|
{ name: 'ref', as: 'ref', from: 'vue' },
|
||||||
{ name: 'computed', as: 'computed', from: 'bar' },
|
{ name: 'computed', as: 'computed', from: 'bar' },
|
||||||
{ name: 'foo', as: 'foo', from: 'excluded' }
|
{ name: 'foo', as: 'foo', from: 'excluded' }
|
||||||
]
|
]
|
||||||
|
|
||||||
const ctx = {
|
const ctx = createUnimport({
|
||||||
autoImports,
|
imports
|
||||||
map: new Map(),
|
})
|
||||||
transform: {
|
|
||||||
exclude: [/excluded/]
|
|
||||||
}
|
|
||||||
} as AutoImportContext
|
|
||||||
updateAutoImportContext(ctx)
|
|
||||||
|
|
||||||
const transformPlugin = TransformPlugin.raw(ctx, { framework: 'rollup' })
|
const transformPlugin = TransformPlugin.raw({ ctx, options: { transform: { exclude: [/node_modules/] } } }, { framework: 'rollup' })
|
||||||
const transform = (code: string) => transformPlugin.transform.call({ error: null, warn: null }, code, '')
|
const transform = async (source: string) => {
|
||||||
|
const { code } = await transformPlugin.transform.call({ error: null, warn: null }, source, '') || { code: null }
|
||||||
|
return code
|
||||||
|
}
|
||||||
|
|
||||||
it('should correct inject', async () => {
|
it('should correct inject', async () => {
|
||||||
expect(await transform('const a = ref(0)')).to.equal('import { ref } from "vue";const a = ref(0)')
|
expect(await transform('const a = ref(0)')).toMatchInlineSnapshot('"import { ref } from \'vue\';const a = ref(0)"')
|
||||||
expect(await transform('import { computed as ref } from "foo"; const a = ref(0)')).to.include('import { computed } from "bar";')
|
expect(await transform('import { computed as ref } from "foo"; const a = ref(0)')).to.toMatchInlineSnapshot('"import { computed } from \'bar\';import { computed as ref } from \\"foo\\"; const a = ref(0)"')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should ignore existing imported', async () => {
|
it('should ignore existing imported', async () => {
|
||||||
@ -43,11 +40,14 @@ describe('auto-imports:transform', () => {
|
|||||||
|
|
||||||
it('should ignore comments', async () => {
|
it('should ignore comments', async () => {
|
||||||
const result = await transform('// import { computed } from "foo"\n;const a = computed(0)')
|
const result = await transform('// import { computed } from "foo"\n;const a = computed(0)')
|
||||||
expect(result).to.equal('import { computed } from "bar";// import { computed } from "foo"\n;const a = computed(0)')
|
expect(result).toMatchInlineSnapshot(`
|
||||||
|
"import { computed } from 'bar';// import { computed } from \\"foo\\"
|
||||||
|
;const a = computed(0)"
|
||||||
|
`)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should exclude files from transform', () => {
|
it('should exclude files from transform', async () => {
|
||||||
expect(transformPlugin.transformInclude.call({ error: null, warn: null }, 'excluded')).to.equal(false)
|
expect(await transform('excluded')).toEqual(null)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -64,7 +64,7 @@ describe('auto-imports:nuxt3', () => {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
it(`should register ${name} globally`, () => {
|
it(`should register ${name} globally`, () => {
|
||||||
expect(Nuxt3AutoImports.find(a => a.from === '#app').names).to.include(name)
|
expect(defaultPresets.find(a => a.from === '#app').imports).to.include(name)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -175,7 +175,7 @@ describe('auto-imports:vue', () => {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
it(`should register ${name} globally`, () => {
|
it(`should register ${name} globally`, () => {
|
||||||
expect(Nuxt3AutoImports.find(a => a.from === 'vue').names).toContain(name)
|
expect(defaultPresets.find(a => a.from === 'vue').imports).toContain(name)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -27,7 +27,8 @@
|
|||||||
"postcss-import-resolver": "^2.0.0",
|
"postcss-import-resolver": "^2.0.0",
|
||||||
"scule": "^0.2.1",
|
"scule": "^0.2.1",
|
||||||
"std-env": "^3.0.1",
|
"std-env": "^3.0.1",
|
||||||
"ufo": "^0.7.11"
|
"ufo": "^0.7.11",
|
||||||
|
"unimport": "0.0.5"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^14.16.0 || ^16.11.0 || ^17.0.0"
|
"node": "^14.16.0 || ^16.11.0 || ^17.0.0"
|
||||||
|
@ -4,7 +4,7 @@ import type { Compiler, Configuration, Stats } from 'webpack'
|
|||||||
import type { TSConfig } from 'pkg-types'
|
import type { TSConfig } from 'pkg-types'
|
||||||
import type { ModuleContainer } from './module'
|
import type { ModuleContainer } from './module'
|
||||||
import type { NuxtTemplate, Nuxt, NuxtApp } from './nuxt'
|
import type { NuxtTemplate, Nuxt, NuxtApp } from './nuxt'
|
||||||
import type { AutoImport, AutoImportSource } from './imports'
|
import type { Preset as ImportPreset, Import } from 'unimport'
|
||||||
import type { NuxtConfig, NuxtOptions } from './config'
|
import type { NuxtConfig, NuxtOptions } from './config'
|
||||||
import type { Component, ComponentsDir, ScanDir, ComponentsOptions } from './components'
|
import type { Component, ComponentsDir, ScanDir, ComponentsOptions } from './components'
|
||||||
import { NuxtCompatibility, NuxtCompatibilityIssues } from '..'
|
import { NuxtCompatibility, NuxtCompatibilityIssues } from '..'
|
||||||
@ -52,6 +52,13 @@ export type NuxtLayout = {
|
|||||||
file: string
|
file: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ImportPresetWithDeperection extends ImportPreset {
|
||||||
|
/**
|
||||||
|
* @deprecated renamed to `imports`
|
||||||
|
*/
|
||||||
|
names?: string[]
|
||||||
|
}
|
||||||
|
|
||||||
export interface NuxtHooks {
|
export interface NuxtHooks {
|
||||||
// Kit
|
// Kit
|
||||||
'kit:compatibility': (compatibility: NuxtCompatibility, issues: NuxtCompatibilityIssues) => HookResult
|
'kit:compatibility': (compatibility: NuxtCompatibility, issues: NuxtCompatibilityIssues) => HookResult
|
||||||
@ -66,8 +73,8 @@ export interface NuxtHooks {
|
|||||||
'pages:layouts:extend': (layouts: NuxtLayout[]) => HookResult
|
'pages:layouts:extend': (layouts: NuxtLayout[]) => HookResult
|
||||||
|
|
||||||
// Auto imports
|
// Auto imports
|
||||||
'autoImports:sources': (autoImportSources: AutoImportSource[]) => HookResult
|
'autoImports:sources': (presets: ImportPresetWithDeperection[]) => HookResult
|
||||||
'autoImports:extend': (autoImports: AutoImport[]) => HookResult
|
'autoImports:extend': (imports: Import[]) => HookResult
|
||||||
'autoImports:dirs': (dirs: string[]) => HookResult
|
'autoImports:dirs': (dirs: string[]) => HookResult
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
|
@ -1,66 +1,9 @@
|
|||||||
export type IdentifierMap = Record<string, string>
|
import { UnimportOptions } from 'unimport'
|
||||||
export type Identifiers = [string, string][]
|
|
||||||
|
|
||||||
export interface AutoImport {
|
export interface AutoImportsOptions extends UnimportOptions {
|
||||||
/**
|
|
||||||
* Export name to be imported
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
name: string
|
|
||||||
/**
|
|
||||||
* Import as this name
|
|
||||||
*/
|
|
||||||
as: string
|
|
||||||
/**
|
|
||||||
* Module specifier to import from
|
|
||||||
*/
|
|
||||||
from: string
|
|
||||||
/**
|
|
||||||
* Disable auto import
|
|
||||||
*/
|
|
||||||
disabled?: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface AutoImportSource {
|
|
||||||
/**
|
|
||||||
* Exports from module for auto-import
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
names: (string | { name: string, as?: string })[]
|
|
||||||
/**
|
|
||||||
* Module specifier to import from
|
|
||||||
*/
|
|
||||||
from: string
|
|
||||||
/**
|
|
||||||
* Disable auto import source
|
|
||||||
*/
|
|
||||||
disabled?: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface AutoImportsOptions {
|
|
||||||
/**
|
|
||||||
* Auto import sources
|
|
||||||
*/
|
|
||||||
sources?: AutoImportSource[]
|
|
||||||
|
|
||||||
/**
|
|
||||||
* [experimental] Use globalThis injection instead of transform for development
|
|
||||||
*/
|
|
||||||
global?: boolean
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Additional directories to scan composables from
|
|
||||||
*
|
|
||||||
* By default <rootDir>/composables is added
|
|
||||||
*/
|
|
||||||
dirs?: string[]
|
dirs?: string[]
|
||||||
|
global?: boolean,
|
||||||
transform: {
|
transform?: {
|
||||||
/**
|
|
||||||
* Exclusion patterns for transforming files
|
|
||||||
*
|
|
||||||
* By default [/node_modules/] will be used
|
|
||||||
*/
|
|
||||||
exclude?: RegExp[]
|
exclude?: RegExp[]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
42
yarn.lock
42
yarn.lock
@ -2986,6 +2986,7 @@ __metadata:
|
|||||||
semver: ^7.3.5
|
semver: ^7.3.5
|
||||||
unbuild: latest
|
unbuild: latest
|
||||||
unctx: ^1.0.2
|
unctx: ^1.0.2
|
||||||
|
unimport: 0.0.8
|
||||||
untyped: ^0.4.2
|
untyped: ^0.4.2
|
||||||
languageName: unknown
|
languageName: unknown
|
||||||
linkType: soft
|
linkType: soft
|
||||||
@ -3148,6 +3149,7 @@ __metadata:
|
|||||||
std-env: ^3.0.1
|
std-env: ^3.0.1
|
||||||
ufo: ^0.7.11
|
ufo: ^0.7.11
|
||||||
unbuild: latest
|
unbuild: latest
|
||||||
|
unimport: 0.0.5
|
||||||
languageName: unknown
|
languageName: unknown
|
||||||
linkType: soft
|
linkType: soft
|
||||||
|
|
||||||
@ -13829,6 +13831,15 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"magic-string@npm:^0.26.0":
|
||||||
|
version: 0.26.0
|
||||||
|
resolution: "magic-string@npm:0.26.0"
|
||||||
|
dependencies:
|
||||||
|
sourcemap-codec: ^1.4.8
|
||||||
|
checksum: 2065de79cdbb76fe1b073244d51a2094cabf317e95a4ce385d7ddbe1d1f16b864c0f2a1ae514872251e64edc44bf56c8bb6a7dbe5eff9c9c236f877bcdfec9f9
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"magic-string@npm:^0.26.1":
|
"magic-string@npm:^0.26.1":
|
||||||
version: 0.26.1
|
version: 0.26.1
|
||||||
resolution: "magic-string@npm:0.26.1"
|
resolution: "magic-string@npm:0.26.1"
|
||||||
@ -15496,6 +15507,7 @@ __metadata:
|
|||||||
scule: ^0.2.1
|
scule: ^0.2.1
|
||||||
ufo: ^0.7.11
|
ufo: ^0.7.11
|
||||||
unbuild: latest
|
unbuild: latest
|
||||||
|
unimport: 0.0.8
|
||||||
unplugin: ^0.4.0
|
unplugin: ^0.4.0
|
||||||
untyped: ^0.4.2
|
untyped: ^0.4.2
|
||||||
vue: ^3.2.31
|
vue: ^3.2.31
|
||||||
@ -21184,6 +21196,34 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"unimport@npm:0.0.5":
|
||||||
|
version: 0.0.5
|
||||||
|
resolution: "unimport@npm:0.0.5"
|
||||||
|
dependencies:
|
||||||
|
"@rollup/pluginutils": ^4.1.2
|
||||||
|
escape-string-regexp: ^5.0.0
|
||||||
|
local-pkg: ^0.4.1
|
||||||
|
magic-string: ^0.26.0
|
||||||
|
mlly: ^0.4.3
|
||||||
|
unplugin: ^0.3.3
|
||||||
|
checksum: 6514320ff1771f699dc6c69b7a7086fe6a62ca1ece7a4877798e89964bf3b9b2450631266a49dfa5785ba8939e4f30517333e4639ecf44e97077fb3128a946d5
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"unimport@npm:0.0.8":
|
||||||
|
version: 0.0.8
|
||||||
|
resolution: "unimport@npm:0.0.8"
|
||||||
|
dependencies:
|
||||||
|
"@rollup/pluginutils": ^4.1.2
|
||||||
|
escape-string-regexp: ^5.0.0
|
||||||
|
local-pkg: ^0.4.1
|
||||||
|
magic-string: ^0.26.0
|
||||||
|
mlly: ^0.4.3
|
||||||
|
unplugin: ^0.3.3
|
||||||
|
checksum: ac6e2ef860b274c28093117c23071aaa35f484f88ff23cd25a4f4d114c24e72969f46f729b26023546ffdc1016ef42e5fc399d14389c0c0374f4a74b17ff1955
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"union-value@npm:^1.0.0":
|
"union-value@npm:^1.0.0":
|
||||||
version: 1.0.1
|
version: 1.0.1
|
||||||
resolution: "union-value@npm:1.0.1"
|
resolution: "union-value@npm:1.0.1"
|
||||||
@ -21303,7 +21343,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"unplugin@npm:^0.3.0, unplugin@npm:^0.3.2":
|
"unplugin@npm:^0.3.0, unplugin@npm:^0.3.2, unplugin@npm:^0.3.3":
|
||||||
version: 0.3.3
|
version: 0.3.3
|
||||||
resolution: "unplugin@npm:0.3.3"
|
resolution: "unplugin@npm:0.3.3"
|
||||||
dependencies:
|
dependencies:
|
||||||
|
Loading…
Reference in New Issue
Block a user