From ac2e9fe350c0c11e45bd3916f1b7b2dbdfb26b41 Mon Sep 17 00:00:00 2001 From: Ivan Demchuk Date: Mon, 25 Jul 2022 19:18:29 +0300 Subject: [PATCH 01/10] Pass query string info to transformInclude --- src/webpack/index.ts | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/webpack/index.ts b/src/webpack/index.ts index 65db6fa9..c1b68c0e 100644 --- a/src/webpack/index.ts +++ b/src/webpack/index.ts @@ -49,23 +49,23 @@ export function getWebpackPlugin ( // transform hook if (plugin.transform) { compiler.options.module.rules.push({ - include (id: string) { - if (id == null) { - return false - } - if (plugin.transformInclude) { - return plugin.transformInclude(slash(id)) - } else { - return true - } - }, enforce: plugin.enforce, - use: [{ - loader: TRANSFORM_LOADER, - options: { - unpluginName: plugin.name + use: (data: { resource: string, resourceQuery: string } | null) => { + if (data == null || !plugin.transformInclude) { + return [] } - }] + + if (!plugin.transformInclude(slash(data.resource + data.resourceQuery))) { + return [] + } + + return [{ + loader: TRANSFORM_LOADER, + options: { + unpluginName: plugin.name + } + }] + } }) } From 613b253014e5da829f34e311fc2ded0d0fc40443 Mon Sep 17 00:00:00 2001 From: Ivan Demchuk Date: Mon, 25 Jul 2022 19:47:53 +0300 Subject: [PATCH 02/10] Add tests for query string support --- test/fixtures/transform/__test__/build.test.ts | 3 +++ test/fixtures/transform/src/main.js | 3 ++- test/fixtures/transform/src/query.js | 1 + test/fixtures/transform/unplugin.js | 13 +++++++++++-- 4 files changed, 17 insertions(+), 3 deletions(-) create mode 100644 test/fixtures/transform/src/query.js diff --git a/test/fixtures/transform/__test__/build.test.ts b/test/fixtures/transform/__test__/build.test.ts index 6064e788..c2895a4f 100644 --- a/test/fixtures/transform/__test__/build.test.ts +++ b/test/fixtures/transform/__test__/build.test.ts @@ -10,6 +10,7 @@ describe('transform build', () => { expect(content).toContain('NON-TARGET: __UNPLUGIN__') expect(content).toContain('TARGET: [Injected Vite]') + expect(content).toContain('QUERY: [Injected Vite]') }) it('rollup', async () => { @@ -24,6 +25,7 @@ describe('transform build', () => { expect(content).toContain('NON-TARGET: __UNPLUGIN__') expect(content).toContain('TARGET: [Injected Webpack]') + expect(content).toContain('QUERY: [Injected Webpack]') }) it('esbuild', async () => { @@ -31,5 +33,6 @@ describe('transform build', () => { expect(content).toContain('NON-TARGET: __UNPLUGIN__') expect(content).toContain('TARGET: [Injected Esbuild]') + expect(content).toContain('QUERY: [Injected Esbuild]') }) }) diff --git a/test/fixtures/transform/src/main.js b/test/fixtures/transform/src/main.js index cfc500fd..3d84918e 100644 --- a/test/fixtures/transform/src/main.js +++ b/test/fixtures/transform/src/main.js @@ -1,4 +1,5 @@ import { msg1 } from './nontarget' import { msg2 } from './target' +import { msg3 } from './query?query-param=query-value' -console.log(msg1, msg2) +console.log(msg1, msg2, msg3) diff --git a/test/fixtures/transform/src/query.js b/test/fixtures/transform/src/query.js new file mode 100644 index 00000000..d23b5f87 --- /dev/null +++ b/test/fixtures/transform/src/query.js @@ -0,0 +1 @@ +export const msg3 = 'QUERY: __UNPLUGIN__' diff --git a/test/fixtures/transform/unplugin.js b/test/fixtures/transform/unplugin.js index 6a054801..641b6fe2 100644 --- a/test/fixtures/transform/unplugin.js +++ b/test/fixtures/transform/unplugin.js @@ -1,11 +1,20 @@ const { createUnplugin } = require('unplugin') const MagicString = require('magic-string') -module.exports = createUnplugin((options) => { +module.exports = createUnplugin((options, meta) => { return { name: 'transform-fixture', + resolveId (id) { + // Rollup doesn't know how to import module with query string so we ignore the module + if (id.includes('?query-param=query-value') && meta.framework === 'rollup') { + return { + id, + external: true + } + } + }, transformInclude (id) { - return id.match(/[/\\]target\.js$/) + return id.match(/[/\\]target\.js$/) || id.includes('?query-param=query-value') }, transform (code, id) { const s = new MagicString(code) From aa6206b04eed364e69e71a8247e1eb88be59c891 Mon Sep 17 00:00:00 2001 From: Ivan Demchuk Date: Mon, 25 Jul 2022 19:48:10 +0300 Subject: [PATCH 03/10] Add support for query strings to esbuild --- src/esbuild/index.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/esbuild/index.ts b/src/esbuild/index.ts index 27085b39..ccd773b7 100644 --- a/src/esbuild/index.ts +++ b/src/esbuild/index.ts @@ -112,6 +112,8 @@ export function getEsbuildPlugin ( if (plugin.load || plugin.transform) { onLoad({ filter: onLoadFilter }, async (args) => { + const id = args.path + args.suffix + const errors: PartialMessage[] = [] const warnings: PartialMessage[] = [] const pluginContext: UnpluginContext = { @@ -125,7 +127,7 @@ export function getEsbuildPlugin ( let code: string | undefined, map: SourceMap | null | undefined if (plugin.load) { - const result = await plugin.load.call(Object.assign(context, pluginContext), args.path) + const result = await plugin.load.call(Object.assign(context, pluginContext), id) if (typeof result === 'string') { code = result } else if (typeof result === 'object' && result !== null) { @@ -149,7 +151,7 @@ export function getEsbuildPlugin ( return { contents: code, errors, warnings, loader: guessLoader(args.path), resolveDir } } - if (!plugin.transformInclude || plugin.transformInclude(args.path)) { + if (!plugin.transformInclude || plugin.transformInclude(id)) { if (!code) { // caution: 'utf8' assumes the input file is not in binary. // if you want your plugin handle binary files, make sure to @@ -157,7 +159,7 @@ export function getEsbuildPlugin ( code = await fs.promises.readFile(args.path, 'utf8') } - const result = await plugin.transform.call(Object.assign(context, pluginContext), code, args.path) + const result = await plugin.transform.call(Object.assign(context, pluginContext), code, id) if (typeof result === 'string') { code = result } else if (typeof result === 'object' && result !== null) { From 508b01a7dcabc720ca4431bd6e884d8f63c7e6e5 Mon Sep 17 00:00:00 2001 From: Ivan Demchuk Date: Mon, 25 Jul 2022 19:50:45 +0300 Subject: [PATCH 04/10] Fix webpack warning --- src/webpack/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/webpack/index.ts b/src/webpack/index.ts index c1b68c0e..b067a2d3 100644 --- a/src/webpack/index.ts +++ b/src/webpack/index.ts @@ -61,6 +61,7 @@ export function getWebpackPlugin ( return [{ loader: TRANSFORM_LOADER, + ident: plugin.name, options: { unpluginName: plugin.name } From 3e82265d1bc982453239368d6a2db434578cf20b Mon Sep 17 00:00:00 2001 From: Ivan Demchuk Date: Mon, 25 Jul 2022 20:23:38 +0300 Subject: [PATCH 05/10] Add sanity check to tests --- test/fixtures/transform/unplugin.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/test/fixtures/transform/unplugin.js b/test/fixtures/transform/unplugin.js index 641b6fe2..21e5862a 100644 --- a/test/fixtures/transform/unplugin.js +++ b/test/fixtures/transform/unplugin.js @@ -23,7 +23,14 @@ module.exports = createUnplugin((options, meta) => { return null } - s.overwrite(index, index + '__UNPLUGIN__'.length, `[Injected ${options.msg}]`) + const injectedCode = `[Injected ${options.msg}]` + + if (id.includes(injectedCode)) { + throw new Error('File was already transformed') + } + + s.overwrite(index, index + '__UNPLUGIN__'.length, injectedCode) + return { code: s.toString(), map: s.generateMap({ From 63591651f88f5d8208c67d9b346e78d4388eecdd Mon Sep 17 00:00:00 2001 From: Ivan Demchuk Date: Mon, 25 Jul 2022 20:23:50 +0300 Subject: [PATCH 06/10] Fix transformInclude check --- src/webpack/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/webpack/index.ts b/src/webpack/index.ts index b067a2d3..d8a983f7 100644 --- a/src/webpack/index.ts +++ b/src/webpack/index.ts @@ -51,11 +51,11 @@ export function getWebpackPlugin ( compiler.options.module.rules.push({ enforce: plugin.enforce, use: (data: { resource: string, resourceQuery: string } | null) => { - if (data == null || !plugin.transformInclude) { + if (data == null) { return [] } - if (!plugin.transformInclude(slash(data.resource + data.resourceQuery))) { + if (plugin.transformInclude != null && !plugin.transformInclude(slash(data.resource + data.resourceQuery))) { return [] } From 4ea1973d02a72f513289a13698332cfcd27762dc Mon Sep 17 00:00:00 2001 From: Ivan Demchuk Date: Mon, 25 Jul 2022 20:30:26 +0300 Subject: [PATCH 07/10] Code cleanup --- src/webpack/index.ts | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/webpack/index.ts b/src/webpack/index.ts index d8a983f7..d3bf8d97 100644 --- a/src/webpack/index.ts +++ b/src/webpack/index.ts @@ -55,17 +55,18 @@ export function getWebpackPlugin ( return [] } - if (plugin.transformInclude != null && !plugin.transformInclude(slash(data.resource + data.resourceQuery))) { + const id = slash(data.resource + data.resourceQuery) + if (!plugin.transformInclude || plugin.transformInclude(id)) { + return [{ + loader: TRANSFORM_LOADER, + ident: plugin.name, + options: { + unpluginName: plugin.name + } + }] + } else { return [] } - - return [{ - loader: TRANSFORM_LOADER, - ident: plugin.name, - options: { - unpluginName: plugin.name - } - }] } }) } From 7e1cffd4cec0ef9e5a3e434dcd08d4712cc4a56f Mon Sep 17 00:00:00 2001 From: Ivan Demchuk Date: Mon, 25 Jul 2022 20:35:52 +0300 Subject: [PATCH 08/10] Fix null check --- src/webpack/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/webpack/index.ts b/src/webpack/index.ts index d3bf8d97..014967b7 100644 --- a/src/webpack/index.ts +++ b/src/webpack/index.ts @@ -50,8 +50,8 @@ export function getWebpackPlugin ( if (plugin.transform) { compiler.options.module.rules.push({ enforce: plugin.enforce, - use: (data: { resource: string, resourceQuery: string } | null) => { - if (data == null) { + use: (data: { resource: string | null, resourceQuery: string }) => { + if (data.resource == null) { return [] } From be0fb5fc12ffe950010843707036305b1d2e46bc Mon Sep 17 00:00:00 2001 From: Anthony Fu Date: Tue, 26 Jul 2022 12:28:15 +0800 Subject: [PATCH 09/10] chore: perf --- src/webpack/index.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/webpack/index.ts b/src/webpack/index.ts index 014967b7..5dcd6c54 100644 --- a/src/webpack/index.ts +++ b/src/webpack/index.ts @@ -2,7 +2,7 @@ import fs from 'fs' import { fileURLToPath } from 'url' import { resolve, dirname } from 'path' import VirtualModulesPlugin from 'webpack-virtual-modules' -import type { ResolvePluginInstance } from 'webpack' +import type { ResolvePluginInstance, RuleSetUseItem } from 'webpack' import type { UnpluginContextMeta, UnpluginInstance, UnpluginFactory, WebpackCompiler, ResolvedUnpluginOptions } from '../types' import { slash, backSlash } from './utils' import { createContext } from './context' @@ -48,22 +48,22 @@ export function getWebpackPlugin ( // transform hook if (plugin.transform) { + const loaderItem: RuleSetUseItem = { + loader: TRANSFORM_LOADER, + ident: plugin.name, + options: { + unpluginName: plugin.name + } + } compiler.options.module.rules.push({ enforce: plugin.enforce, use: (data: { resource: string | null, resourceQuery: string }) => { if (data.resource == null) { return [] } - const id = slash(data.resource + data.resourceQuery) if (!plugin.transformInclude || plugin.transformInclude(id)) { - return [{ - loader: TRANSFORM_LOADER, - ident: plugin.name, - options: { - unpluginName: plugin.name - } - }] + return [loaderItem] } else { return [] } From 0faea784e2f337d1b64fff5d09ea3692d00efc58 Mon Sep 17 00:00:00 2001 From: Anthony Fu Date: Tue, 26 Jul 2022 12:29:32 +0800 Subject: [PATCH 10/10] chore: perf --- src/webpack/index.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/webpack/index.ts b/src/webpack/index.ts index 5dcd6c54..2844b2b3 100644 --- a/src/webpack/index.ts +++ b/src/webpack/index.ts @@ -48,25 +48,25 @@ export function getWebpackPlugin ( // transform hook if (plugin.transform) { - const loaderItem: RuleSetUseItem = { + const useLoader: RuleSetUseItem[] = [{ loader: TRANSFORM_LOADER, ident: plugin.name, options: { unpluginName: plugin.name } - } + }] + const useNone: RuleSetUseItem[] = [] compiler.options.module.rules.push({ enforce: plugin.enforce, use: (data: { resource: string | null, resourceQuery: string }) => { if (data.resource == null) { - return [] + return useNone } - const id = slash(data.resource + data.resourceQuery) + const id = slash(data.resource + (data.resourceQuery || '')) if (!plugin.transformInclude || plugin.transformInclude(id)) { - return [loaderItem] - } else { - return [] + return useLoader } + return useNone } }) }