fix(nuxt): tree shake all occurrences of <DevOnly> (#23466)

This commit is contained in:
Maritaria 2023-10-12 19:27:21 +02:00 committed by GitHub
parent f847f0c999
commit 64bc3c3224
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 66 additions and 13 deletions

View File

@ -1,31 +1,25 @@
import { pathToFileURL } from 'node:url'
import { stripLiteral } from 'strip-literal'
import { parseQuery, parseURL } from 'ufo'
import MagicString from 'magic-string'
import { createUnplugin } from 'unplugin'
import { type Node, parse } from 'ultrahtml'
import { isVue } from '../utils'
interface DevOnlyPluginOptions {
sourcemap?: boolean
}
export const DevOnlyPlugin = createUnplugin((options: DevOnlyPluginOptions, meta) => {
const DEVONLY_COMP_RE = /<(?:dev-only|DevOnly)>[\s\S]*?<\/(?:dev-only|DevOnly)>/g
const DEVONLY_COMP_SINGLE_RE = /<(?:dev-only|DevOnly|lazy-dev-only|LazyDevOnly)>[\s\S]*?<\/(?:dev-only|DevOnly|lazy-dev-only|LazyDevOnly)>/
const DEVONLY_COMP_RE = /<(?:dev-only|DevOnly|lazy-dev-only|LazyDevOnly)>[\s\S]*?<\/(?:dev-only|DevOnly|lazy-dev-only|LazyDevOnly)>/g
export const DevOnlyPlugin = createUnplugin((options: DevOnlyPluginOptions) => {
return {
name: 'nuxt:server-devonly:transform',
enforce: 'pre',
transformInclude (id) {
const { pathname, search } = parseURL(decodeURIComponent(pathToFileURL(id).href))
const { type } = parseQuery(search)
// vue files
if (pathname.endsWith('.vue') && (meta.framework === 'webpack' || type === 'template' || !search)) {
return true
}
return isVue(id, { type: ['template'] })
},
transform (code) {
if (!DEVONLY_COMP_RE.test(code)) { return }
if (!DEVONLY_COMP_SINGLE_RE.test(code)) { return }
const s = new MagicString(code)
const strippedCode = stripLiteral(code)

View File

@ -20,7 +20,7 @@ export function isVue (id: string, opts: { type?: Array<'template' | 'script' |
}
// Macro
if (query.macro && (!opts.type || opts.type.includes('script'))) {
if (query.macro && (search === '?macro=true' || !opts.type || opts.type.includes('script'))) {
return true
}

View File

@ -0,0 +1,59 @@
import { describe, expect, it } from 'vitest'
import type { Plugin } from 'vite'
import { DevOnlyPlugin } from '../src/core/plugins/dev-only'
import { normalizeLineEndings } from './utils'
const pluginVite = DevOnlyPlugin.raw({}, { framework: 'vite' }) as Plugin
const viteTransform = async (source: string, id: string) => {
const result = await (pluginVite.transform! as Function)(source, id)
return typeof result === 'string' ? result : result?.code
}
describe('test devonly transform ', () => {
it('test dev only treeshaking', async () => {
const result = await viteTransform(`<template>
<div>
<LazyDevOnly>
<SomeDevOnlyComponent></SomeDevOnlyComponent>
</LazyDevOnly>
</div>
<SomeComponent>
<lazy-dev-only>
test
</lazy-dev-only>
</SomeComponent>
<div>
<DevOnly>
<SomeDevOnlyComponent></SomeDevOnlyComponent>
</DevOnly>
</div>
<SomeComponent>
<dev-only>
test
</dev-only>
</SomeComponent>
</template>`, 'some id')
expect(normalizeLineEndings(result)).toMatchInlineSnapshot(`
"<template>
<div>
</div>
<SomeComponent>
</SomeComponent>
<div>
</div>
<SomeComponent>
</SomeComponent>
</template>"
`)
expect(result).not.toContain('dev-only')
expect(result).not.toContain('DevOnly')
expect(result).not.toContain('lazy-dev-only')
expect(result).not.toContain('LazyDevOnly')
})
})