perf(nuxt): transform #imports to improve tree-shaking (#5763)

This commit is contained in:
Anthony Fu 2022-07-21 22:27:23 +08:00 committed by GitHub
parent 45b449ed05
commit 1a862526fe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 30 additions and 14 deletions

View File

@ -38,6 +38,7 @@ export default defineNuxtModule<Partial<AutoImportsOptions>>({
const ctx = createUnimport({
presets: options.presets,
imports: options.imports,
virtualImports: ['#imports'],
addons: {
vueTemplate: true
}
@ -58,7 +59,7 @@ export default defineNuxtModule<Partial<AutoImportsOptions>>({
// Support for importing from '#imports'
addTemplate({
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')

View File

@ -3,6 +3,7 @@ import { createUnplugin } from 'unplugin'
import { parseQuery, parseURL } from 'ufo'
import { Unimport } from 'unimport'
import { AutoImportsOptions } from '@nuxt/schema'
import { normalize } from 'pathe'
export const TransformPlugin = createUnplugin(({ ctx, options, sourcemap }: {ctx: Unimport, options: Partial<AutoImportsOptions>, sourcemap?: boolean }) => {
return {
@ -12,15 +13,16 @@ export const TransformPlugin = createUnplugin(({ ctx, options, sourcemap }: {ctx
const { pathname, search } = parseURL(decodeURIComponent(pathToFileURL(id).href))
const { type, macro } = parseQuery(search)
const exclude = options.transform?.exclude || [/[\\/]node_modules[\\/]/]
const include = options.transform?.include || []
// Custom includes - exclude node_modules by default
if (exclude.some(pattern => id.match(pattern)) && !include.some(pattern => id.match(pattern))) {
// Included
if (options.transform?.include?.some(pattern => id.match(pattern))) {
return true
}
// Excluded
if (options.transform?.exclude?.some(pattern => id.match(pattern))) {
return false
}
// vue files
// Vue files
if (
pathname.endsWith('.vue') &&
(type === 'template' || type === 'script' || macro || !search)
@ -28,19 +30,25 @@ export const TransformPlugin = createUnplugin(({ ctx, options, sourcemap }: {ctx
return true
}
// js files
// JavaScript files
if (pathname.match(/\.((c|m)?j|t)sx?$/g)) {
return true
}
},
async transform (_code, id) {
const { code, s } = await ctx.injectImports(_code, id)
if (code === _code) {
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
if (isNodeModule && !code.match(/(['"])#imports\1/)) {
return
}
return {
code,
map: sourcemap && s.generateMap({ source: id, includeContent: true })
const { s } = await ctx.injectImports(code, id, { autoImport: !isNodeModule })
if (s.hasChanged()) {
return {
code: s.toString(),
map: sourcemap && s.generateMap({ source: id, includeContent: true })
}
}
}
}

View File

@ -0,0 +1,5 @@
export function badSideEffect () {
// ...
}
throw new Error('composables/badSideEffect.ts should be tree-shaked')

View File

@ -18,6 +18,8 @@
</template>
<script setup>
import { useRuntimeConfig } from '#imports'
const config = useRuntimeConfig()
const foo = useFoo()