feat: add polyfills option to auto-imports

This commit is contained in:
wattanx 2024-12-22 22:49:29 +09:00
parent f86d749077
commit 9fa3380af7
5 changed files with 66 additions and 25 deletions

View File

@ -9,28 +9,31 @@ import escapeRE from 'escape-string-regexp'
import { lookupNodeModuleSubpath, parseNodeModulePath } from 'mlly' import { lookupNodeModuleSubpath, parseNodeModulePath } from 'mlly'
import { isDirectory } from '../utils' import { isDirectory } from '../utils'
import { TransformPlugin } from './transform' import { TransformPlugin } from './transform'
import { defaultPresets } from './presets' import { defaultPresets, appCompatPresets } from './presets'
export default defineNuxtModule<Partial<ImportsOptions>>({ export default defineNuxtModule<Partial<ImportsOptions>>({
meta: { meta: {
name: 'nuxt:imports', name: 'nuxt:imports',
configKey: 'imports', configKey: 'imports',
}, },
defaults: nuxt => ({ defaults: nuxt => {
autoImport: true, return {
scan: true, autoImport: true,
presets: defaultPresets, scan: true,
global: false, presets: nuxt.options.imports.polyfills ? [...defaultPresets, ...appCompatPresets] : defaultPresets,
imports: [], global: false,
dirs: [], imports: [],
transform: { dirs: [],
include: [ transform: {
new RegExp('^' + escapeRE(nuxt.options.buildDir)), include: [
], new RegExp('^' + escapeRE(nuxt.options.buildDir)),
exclude: undefined, ],
}, exclude: undefined,
virtualImports: ['#imports'], },
}), virtualImports: ['#imports'],
polyfills: true,
}
},
async setup (options, nuxt) { async setup (options, nuxt) {
// TODO: fix sharing of defaults between invocations of modules // TODO: fix sharing of defaults between invocations of modules
const presets = JSON.parse(JSON.stringify(options.presets)) as ImportPresetWithDeprecation[] const presets = JSON.parse(JSON.stringify(options.presets)) as ImportPresetWithDeprecation[]

View File

@ -21,14 +21,6 @@ const granularAppPresets: InlinePreset[] = [
imports: ['useNuxtApp', 'tryUseNuxtApp', 'defineNuxtPlugin', 'definePayloadPlugin', 'useRuntimeConfig', 'defineAppConfig'], imports: ['useNuxtApp', 'tryUseNuxtApp', 'defineNuxtPlugin', 'definePayloadPlugin', 'useRuntimeConfig', 'defineAppConfig'],
from: '#app/nuxt', from: '#app/nuxt',
}, },
{
imports: ['requestIdleCallback', 'cancelIdleCallback'],
from: '#app/compat/idle-callback',
},
{
imports: ['setInterval'],
from: '#app/compat/interval',
},
{ {
imports: ['useAppConfig', 'updateAppConfig'], imports: ['useAppConfig', 'updateAppConfig'],
from: '#app/config', from: '#app/config',
@ -256,6 +248,17 @@ const vueTypesPreset = defineUnimportPreset({
], ],
}) })
export const appCompatPresets: InlinePreset[] = [
{
imports: ['requestIdleCallback', 'cancelIdleCallback'],
from: '#app/compat/idle-callback',
},
{
imports: ['setInterval'],
from: '#app/compat/interval',
},
]
export const defaultPresets: InlinePreset[] = [ export const defaultPresets: InlinePreset[] = [
...commonPresets, ...commonPresets,
...granularAppPresets, ...granularAppPresets,

View File

@ -32,4 +32,10 @@ export interface ImportsOptions extends UnimportOptions {
exclude?: RegExp[] exclude?: RegExp[]
include?: RegExp[] include?: RegExp[]
} }
/**
* Add polyfills for setInterval, requestIdleCallback, and others
* @default true
*/
polyfills?: boolean
} }

View File

@ -1,4 +1,4 @@
import { describe, expect, it } from 'vitest' import { describe, expect, it, vi } from 'vitest'
import type { ComponentOptions } from 'vue' import type { ComponentOptions } from 'vue'
import { Suspense, defineComponent, h, toDisplayString, useAttrs } from 'vue' import { Suspense, defineComponent, h, toDisplayString, useAttrs } from 'vue'
import { mountSuspended } from '@nuxt/test-utils/runtime' import { mountSuspended } from '@nuxt/test-utils/runtime'
@ -65,3 +65,29 @@ describe('client page', () => {
expect(wrapper.find('#fallback').exists()).toBe(false) expect(wrapper.find('#fallback').exists()).toBe(false)
}) })
}) })
describe('app/compat', () => {
const Component = defineComponent({
setup () {
const visible = ref(false)
setInterval(() => {
visible.value = true
}, 1000)
return () => h('div', {}, visible.value ? h('span', { id: 'child' }) : {})
},
})
it('setInterval is not auto-imported', async () => {
vi.useFakeTimers()
const wrapper = mount(Component)
vi.advanceTimersByTime(1000)
await wrapper.vm.$nextTick()
expect(wrapper.find('#child').exists()).toBe(true)
vi.useRealTimers()
})
})

View File

@ -21,6 +21,9 @@ export default defineVitestConfig({
experimental: { experimental: {
appManifest: process.env.TEST_MANIFEST !== 'manifest-off', appManifest: process.env.TEST_MANIFEST !== 'manifest-off',
}, },
imports: {
polyfills: false,
},
}, },
}, },
}, },