mirror of
https://github.com/nuxt/nuxt.git
synced 2025-02-16 13:48:13 +00:00
perf(nuxt): transform #imports
to improve tree-shaking (#5763)
This commit is contained in:
parent
45b449ed05
commit
1a862526fe
@ -38,6 +38,7 @@ export default defineNuxtModule<Partial<AutoImportsOptions>>({
|
|||||||
const ctx = createUnimport({
|
const ctx = createUnimport({
|
||||||
presets: options.presets,
|
presets: options.presets,
|
||||||
imports: options.imports,
|
imports: options.imports,
|
||||||
|
virtualImports: ['#imports'],
|
||||||
addons: {
|
addons: {
|
||||||
vueTemplate: true
|
vueTemplate: true
|
||||||
}
|
}
|
||||||
@ -58,7 +59,7 @@ export default defineNuxtModule<Partial<AutoImportsOptions>>({
|
|||||||
// Support for importing from '#imports'
|
// Support for importing from '#imports'
|
||||||
addTemplate({
|
addTemplate({
|
||||||
filename: 'imports.mjs',
|
filename: 'imports.mjs',
|
||||||
getContents: () => ctx.toExports()
|
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.") }'
|
||||||
})
|
})
|
||||||
nuxt.options.alias['#imports'] = join(nuxt.options.buildDir, 'imports')
|
nuxt.options.alias['#imports'] = join(nuxt.options.buildDir, 'imports')
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ import { createUnplugin } from 'unplugin'
|
|||||||
import { parseQuery, parseURL } from 'ufo'
|
import { parseQuery, parseURL } from 'ufo'
|
||||||
import { Unimport } from 'unimport'
|
import { Unimport } from 'unimport'
|
||||||
import { AutoImportsOptions } from '@nuxt/schema'
|
import { AutoImportsOptions } from '@nuxt/schema'
|
||||||
|
import { normalize } from 'pathe'
|
||||||
|
|
||||||
export const TransformPlugin = createUnplugin(({ ctx, options, sourcemap }: {ctx: Unimport, options: Partial<AutoImportsOptions>, sourcemap?: boolean }) => {
|
export const TransformPlugin = createUnplugin(({ ctx, options, sourcemap }: {ctx: Unimport, options: Partial<AutoImportsOptions>, sourcemap?: boolean }) => {
|
||||||
return {
|
return {
|
||||||
@ -12,15 +13,16 @@ export const TransformPlugin = createUnplugin(({ ctx, options, sourcemap }: {ctx
|
|||||||
const { pathname, search } = parseURL(decodeURIComponent(pathToFileURL(id).href))
|
const { pathname, search } = parseURL(decodeURIComponent(pathToFileURL(id).href))
|
||||||
const { type, macro } = parseQuery(search)
|
const { type, macro } = parseQuery(search)
|
||||||
|
|
||||||
const exclude = options.transform?.exclude || [/[\\/]node_modules[\\/]/]
|
// Included
|
||||||
const include = options.transform?.include || []
|
if (options.transform?.include?.some(pattern => id.match(pattern))) {
|
||||||
|
return true
|
||||||
// Custom includes - exclude node_modules by default
|
}
|
||||||
if (exclude.some(pattern => id.match(pattern)) && !include.some(pattern => id.match(pattern))) {
|
// Excluded
|
||||||
|
if (options.transform?.exclude?.some(pattern => id.match(pattern))) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// vue files
|
// Vue files
|
||||||
if (
|
if (
|
||||||
pathname.endsWith('.vue') &&
|
pathname.endsWith('.vue') &&
|
||||||
(type === 'template' || type === 'script' || macro || !search)
|
(type === 'template' || type === 'script' || macro || !search)
|
||||||
@ -28,19 +30,25 @@ export const TransformPlugin = createUnplugin(({ ctx, options, sourcemap }: {ctx
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// js files
|
// JavaScript files
|
||||||
if (pathname.match(/\.((c|m)?j|t)sx?$/g)) {
|
if (pathname.match(/\.((c|m)?j|t)sx?$/g)) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async transform (_code, id) {
|
async transform (code, id) {
|
||||||
const { code, s } = await ctx.injectImports(_code, id)
|
id = normalize(id)
|
||||||
if (code === _code) {
|
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
|
||||||
|
if (isNodeModule && !code.match(/(['"])#imports\1/)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
return {
|
|
||||||
code,
|
const { s } = await ctx.injectImports(code, id, { autoImport: !isNodeModule })
|
||||||
map: sourcemap && s.generateMap({ source: id, includeContent: true })
|
if (s.hasChanged()) {
|
||||||
|
return {
|
||||||
|
code: s.toString(),
|
||||||
|
map: sourcemap && s.generateMap({ source: id, includeContent: true })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
5
test/fixtures/basic/composables/badSideEffect.ts
vendored
Normal file
5
test/fixtures/basic/composables/badSideEffect.ts
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
export function badSideEffect () {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error('composables/badSideEffect.ts should be tree-shaked')
|
2
test/fixtures/basic/pages/index.vue
vendored
2
test/fixtures/basic/pages/index.vue
vendored
@ -18,6 +18,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
import { useRuntimeConfig } from '#imports'
|
||||||
|
|
||||||
const config = useRuntimeConfig()
|
const config = useRuntimeConfig()
|
||||||
|
|
||||||
const foo = useFoo()
|
const foo = useFoo()
|
||||||
|
Loading…
Reference in New Issue
Block a user