diff --git a/packages/nuxt3/package.json b/packages/nuxt3/package.json index bf5da41dd7..8011f633c4 100644 --- a/packages/nuxt3/package.json +++ b/packages/nuxt3/package.json @@ -40,7 +40,7 @@ "ohmyfetch": "^0.2.0", "scule": "^0.2.1", "ufo": "^0.7.7", - "unplugin": "^0.0.5", + "unplugin": "^0.2.3", "upath": "^2.0.1", "vue": "^3.2.2", "vue-router": "^4.0.11", diff --git a/packages/nuxt3/src/global-imports/transform.ts b/packages/nuxt3/src/global-imports/transform.ts index b39e004df5..a195aa8a72 100644 --- a/packages/nuxt3/src/global-imports/transform.ts +++ b/packages/nuxt3/src/global-imports/transform.ts @@ -2,17 +2,26 @@ import { createUnplugin } from 'unplugin' import { parseQuery, parseURL } from 'ufo' import { IdentifierMap } from './types' -const excludeRegex = [ +const excludeRE = [ // imported from other module - /\bimport\s*\{([\s\S]*?)\}\s*from\b/g, + /\bimport\s*([\w_$]*?),?\s*\{([\s\S]*?)\}\s*from\b/g, // defined as function /\bfunction\s*([\s\S]+?)\s*\(/g, // defined as local variable /\b(?:const|let|var)\s*([\w\d_$]+?)\b/g ] +const multilineCommentsRE = /\/\*(.|[\r\n])*?\*\//gm +const singlelineCommentsRE = /\/\/.*/g + +function stripeComments (code: string) { + return code + .replace(multilineCommentsRE, '') + .replace(singlelineCommentsRE, '') +} + export const TransformPlugin = createUnplugin((map: IdentifierMap) => { - const regex = new RegExp('\\b(' + (Object.keys(map).join('|')) + ')\\b', 'g') + const matchRE = new RegExp(`\\b(${Object.keys(map).join('|')})\\b`, 'g') return { name: 'nuxt-global-imports-transform', @@ -36,16 +45,23 @@ export const TransformPlugin = createUnplugin((map: IdentifierMap) => { } }, transform (code) { + // strip comments so we don't match on them + const withoutComment = stripeComments(code) + // find all possible injection - const matched = new Set(Array.from(code.matchAll(regex)).map(i => i[1])) + const matched = new Set(Array.from(withoutComment.matchAll(matchRE)).map(i => i[1])) // remove those already defined - for (const regex of excludeRegex) { - Array.from(code.matchAll(regex)) - .flatMap(i => i[1]?.split(',') || []) + for (const regex of excludeRE) { + Array.from(withoutComment.matchAll(regex)) + .flatMap(i => [...(i[1]?.split(',') || []), ...(i[2]?.split(',') || [])]) .forEach(i => matched.delete(i.trim())) } + if (!matched.size) { + return null + } + const modules: Record = {} // group by module name diff --git a/packages/nuxt3/test/global-imports.test.ts b/packages/nuxt3/test/global-imports.test.ts index 3b4f1270b9..04058e089c 100644 --- a/packages/nuxt3/test/global-imports.test.ts +++ b/packages/nuxt3/test/global-imports.test.ts @@ -2,15 +2,21 @@ import { expect } from 'chai' import { TransformPlugin } from '../src/global-imports/transform' describe('module:global-imports:build', () => { - const { transform } = TransformPlugin.raw({ ref: 'vue' }) + const { transform: _transform } = TransformPlugin.raw({ ref: 'vue', computed: 'bar' }, {} as any) + const transform = (code: string) => _transform.call({} as any, code, '') - it('should correct inject', () => { - expect(transform('const a = ref(0)', '')) - .to.equal('import { ref } from \'vue\';const a = ref(0)') + it('should correct inject', async () => { + const result = await transform('const a = ref(0)') + expect(result).to.equal('import { ref } from \'vue\';const a = ref(0)') }) - it('should ignore imported', () => { - expect(transform('import { ref } from "foo";const a = ref(0)', '')) - .to.equal('import { ref } from "foo";const a = ref(0)') + it('should ignore imported', async () => { + const result = await transform('import { ref } from "foo";const a = ref(0)') + expect(result).to.equal(null) + }) + + it('should ignore comments', async () => { + 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)') }) }) diff --git a/yarn.lock b/yarn.lock index e837878fac..26daa3acd9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8653,7 +8653,7 @@ fsevents@~2.3.2: scule: ^0.2.1 ufo: ^0.7.7 unbuild: ^0.4.2 - unplugin: ^0.0.5 + unplugin: ^0.2.3 upath: ^2.0.1 vue: ^3.2.2 vue-meta: next @@ -11760,15 +11760,15 @@ typescript@^4.3.5: languageName: node linkType: hard -"unplugin@npm:^0.0.5": - version: 0.0.5 - resolution: "unplugin@npm:0.0.5" +"unplugin@npm:^0.2.3": + version: 0.2.3 + resolution: "unplugin@npm:0.2.3" dependencies: webpack-virtual-modules: ^0.4.3 peerDependencies: rollup: ^2.50.0 vite: ^2.3.0 - webpack: ^5.0.0 + webpack: ^4.0.0 peerDependenciesMeta: rollup: optional: true @@ -11776,7 +11776,7 @@ typescript@^4.3.5: optional: true webpack: optional: true - checksum: 37f66f585365a9d7c26c03cc971329391839b13505942548be48ad834d7d5c68576e4defce92f9845bddd154c93340f8a1773337fce797f1cac1a1a34d6aac26 + checksum: 1d6186a4bd7c722351106f97530cb59db0ad6398e5d76a06ea0eaec0e646b8dbdaf79a2c3038f791b9d5e1e62b89002f286727c5a065ecdeba622b2a69e2a3a7 languageName: node linkType: hard