From 33eb148e62e3fa226f7280c239f87a2692a9a47f Mon Sep 17 00:00:00 2001 From: Wenlu Wang Date: Thu, 31 Mar 2022 15:48:02 +0800 Subject: [PATCH] fix: dynamic import module to avoid breaking in browser (#129) --- README.md | 2 +- jest.js | 4 ++-- package.json | 10 +++------- pnpm-lock.yaml | 8 +++++++- rollup.config.js | 3 +-- src/core/parseSFC.ts | 15 +++------------ src/core/transform.ts | 8 ++++---- src/index.ts | 4 ++-- test/errors.test.ts | 31 ++++++++++++++----------------- test/transform.test.ts | 4 ++-- 10 files changed, 39 insertions(+), 50 deletions(-) diff --git a/README.md b/README.md index d389f8b..a413fa3 100644 --- a/README.md +++ b/README.md @@ -249,7 +249,7 @@ module.exports = { ```ts import { transform } from 'unplugin-vue2-script-setup' -const Vue2SFC = transform(` +const Vue2SFC = await transform(` diff --git a/jest.js b/jest.js index bf42d7c..dcd4584 100644 --- a/jest.js +++ b/jest.js @@ -15,8 +15,8 @@ function requireVueJest() { } module.exports = { - process(source, filename, ...args) { - const transformed = transform(source, filename) + async process(source, filename, ...args) { + const transformed = await transform(source, filename) const code = transformed ? transformed.code : source return requireVueJest().process.call(this, code, filename, ...args) }, diff --git a/package.json b/package.json index 5c3d7cf..16f28be 100644 --- a/package.json +++ b/package.json @@ -49,11 +49,6 @@ "require": "./dist/webpack.js", "import": "./dist/webpack.mjs", "types": "./webpack.d.ts" - }, - "./lib": { - "require": "./dist/lib.js", - "import": "./dist/lib.mjs", - "types": "./lib.d.ts" } }, "main": "dist/index.js", @@ -101,6 +96,7 @@ "@types/babel__core": "^7.1.18", "@types/estree": "^0.0.51", "@types/node": "^17.0.21", + "@types/pug": "^2.0.6", "@types/ws": "^8.5.0", "@vue/composition-api": "^1.4.6", "@vue/runtime-dom": "^3.2.31", @@ -117,9 +113,9 @@ "vitest": "0.5.4" }, "peerDependencies": { - "pug": "^3.0.2", "@vue/composition-api": "^1.4.3", - "@vue/runtime-dom": "^3.2.31" + "@vue/runtime-dom": "^3.2.31", + "pug": "^3.0.2" }, "peerDependenciesMeta": { "pug": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 11c0106..4d49a4d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -23,6 +23,7 @@ importers: '@types/babel__core': ^7.1.18 '@types/estree': ^0.0.51 '@types/node': ^17.0.21 + '@types/pug': ^2.0.6 '@types/ws': ^8.5.0 '@vue/compiler-core': ^3.2.31 '@vue/compiler-dom': ^3.2.31 @@ -69,6 +70,7 @@ importers: '@types/babel__core': 7.1.18 '@types/estree': 0.0.51 '@types/node': 17.0.21 + '@types/pug': 2.0.6 '@types/ws': 8.5.0 '@vue/composition-api': 1.4.6 '@vue/runtime-dom': 3.2.31 @@ -2486,6 +2488,10 @@ packages: resolution: {integrity: sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==} dev: true + /@types/pug/2.0.6: + resolution: {integrity: sha512-SnHmG9wN1UVmagJOnyo/qkk0Z7gejYxOYYmaAwr5u2yFYfsupN3sg10kyzN8Hep/2zbHxCnsumxOoRIRMBwKCg==} + dev: true + /@types/q/1.5.5: resolution: {integrity: sha512-L28j2FcJfSZOnL1WBjDYp2vUHCeIFlyYI/53EwD/rKUBQ7MtUUfbQWiyKJGpcnv4/WgrhWsFKrcPstcAt/J0tQ==} dev: true @@ -7132,7 +7138,7 @@ packages: optional: true /fsevents/2.3.2: - resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + resolution: {integrity: sha1-ilJveLj99GI7cJ4Ll1xSwkwC/Ro=} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] requiresBuild: true diff --git a/rollup.config.js b/rollup.config.js index e5f9695..0e669b6 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -13,8 +13,7 @@ const entries = [ 'src/vite.ts', 'src/rollup.ts', 'src/esbuild.ts', - 'src/nuxt.ts', - 'src/lib.ts', + 'src/nuxt.ts' ] const dtsEntries = [ diff --git a/src/core/parseSFC.ts b/src/core/parseSFC.ts index eba58c3..97b4d8d 100644 --- a/src/core/parseSFC.ts +++ b/src/core/parseSFC.ts @@ -1,6 +1,5 @@ /* eslint-disable one-var */ /* eslint-disable @typescript-eslint/no-namespace */ -import { createRequire } from 'module' import { notNullish, partition } from '@antfu/utils' import type { Program } from '@babel/types' import type { ParserPlugin } from '@babel/parser' @@ -83,14 +82,6 @@ const BUILD_IN_DIRECTIVES = new Set([ // 'ref', ]) -function getRequire() { - return ( - (typeof require === 'function') - ? require - : createRequire(import.meta.url) - ) -} - function getComponents(node: TemplateChildNode): string[] { const current = node.type === NodeTypes.ELEMENT && node.tagType === ElementTypes.COMPONENT @@ -282,11 +273,11 @@ function getBabelParserOptions(lang: string | null | undefined) { plugins, } } -export function parseSFC( +export async function parseSFC( code: string, id?: string, options?: ScriptSetupTransformOptions, -): ParsedSFC { +): Promise { const elementChildren = baseParse(code, parserOptions).children.flatMap(x => x.type === NodeTypes.ELEMENT && x.tagType === ElementTypes.ELEMENT ? [x] @@ -376,7 +367,7 @@ export function parseSFC( && p.value.content === 'pug', ) ? baseParse( - getRequire()('pug').compile( + (await import('pug')).compile( templateNode.children.map(x => x.loc.source).join(''), { filename: id, diff --git a/src/core/transform.ts b/src/core/transform.ts index b3de7e5..414c59d 100644 --- a/src/core/transform.ts +++ b/src/core/transform.ts @@ -15,12 +15,12 @@ export function shouldTransform(code: string, id: string, options?: ScriptSetupT return (options?.reactivityTransform && shouldTransformRefSugar(code)) || scriptSetupRE.test(code) } -export function transform(input: string, id: string, options?: ScriptSetupTransformOptions): TransformResult { +export async function transform(input: string, id: string, options?: ScriptSetupTransformOptions): Promise { if (!shouldTransform(input, id, options)) return null const resolved = resolveOptions(options) if (id.endsWith('.vue') || id.includes('.vue?vue')) - return transformVue(input, id, resolved) + return await transformVue(input, id, resolved) else return transformNonVue(input, id, resolved) } @@ -36,10 +36,10 @@ function transformNonVue(input: string, id: string, options: ResolvedOptions): T return null } -function transformVue(input: string, id: string, options: ResolvedOptions): TransformResult { +async function transformVue(input: string, id: string, options: ResolvedOptions): Promise { const s = new MagicString(input) - const sfc = parseSFC(input, id) + const sfc = await parseSFC(input, id) if (options.reactivityTransform) transformSfcRefSugar(sfc, options) diff --git a/src/index.ts b/src/index.ts index f4beb31..ad3edbf 100644 --- a/src/index.ts +++ b/src/index.ts @@ -17,9 +17,9 @@ export const unplugin = createUnplugin((options = {}) => { transformInclude(id) { return filter(id) }, - transform(code, id) { + async transform(code, id) { try { - return transform(code, id, options) + return await transform(code, id, options) } catch (e: any) { this.error(e) diff --git a/test/errors.test.ts b/test/errors.test.ts index cd49462..21e6fbf 100644 --- a/test/errors.test.ts +++ b/test/errors.test.ts @@ -2,8 +2,8 @@ import { describe, expect, it, vi } from 'vitest' import { transform as t } from '../src' describe('errors', () => { - it('langs', () => { - expect(() => + it('langs', async() => { + await expect(() => t(` -`, 'Lang.vue')) - .toThrowError(' `, 'DefineProps.vue')) - .toThrowError('duplicate defineProps() call') + .rejects.toThrowError('duplicate defineProps() call') }) - it('top-level await', () => { - expect(() => + it('top-level await', async() => { + await expect(() => t(` `, 'TopLevel.vue')) - .toThrowError('top-level await is not supported in Vue 2') + .rejects.toThrowError('top-level await is not supported in Vue 2') - expect(() => + await expect(() => t(` `, 'TopLevel.vue')) - .toThrowError('top-level await is not supported in Vue 2') + .rejects.toThrowError('top-level await is not supported in Vue 2') }) - it('ref sugar', () => { + it('ref sugar', async() => { const consoleWarnMock = vi.spyOn(console, 'warn') - expect(() => - t(` + await t(` -`, 'App.vue')) - .not.toThrow() + `, 'App.vue') consoleWarnMock.mockRestore() }) diff --git a/test/transform.test.ts b/test/transform.test.ts index 2052f90..3b455a1 100644 --- a/test/transform.test.ts +++ b/test/transform.test.ts @@ -18,10 +18,10 @@ describe('transform', () => { for (const file of files) { it(file.replace(/\\/g, '/'), async() => { const fixture = await fs.readFile(resolve(root, file), 'utf-8') - const result = transform(fixture, file, { reactivityTransform: true })?.code || fixture + const result = (await transform(fixture, file, { reactivityTransform: true }))?.code || fixture expect(result).toMatchSnapshot() - const result2 = transform(result, file, { reactivityTransform: true })?.code || result + const result2 = (await transform(result, file, { reactivityTransform: true }))?.code || result expect(result).toEqual(result2) }) }