From 5f24df98a9d85f3922de9ea1d0b147a6434de2fc Mon Sep 17 00:00:00 2001 From: qzs Date: Thu, 23 May 2024 07:52:24 +0000 Subject: [PATCH 1/3] feat: Allow @rollup/plugin-virtual to be a function that takes a module ID --- packages/virtual/src/index.ts | 21 +++++++++++++++------ packages/virtual/test/test.js | 18 +++++++++++++++++- packages/virtual/types/index.d.ts | 3 ++- 3 files changed, 34 insertions(+), 8 deletions(-) diff --git a/packages/virtual/src/index.ts b/packages/virtual/src/index.ts index 511b5bfad..f6244a4d5 100644 --- a/packages/virtual/src/index.ts +++ b/packages/virtual/src/index.ts @@ -2,12 +2,13 @@ import * as path from 'path'; import type { Plugin } from 'rollup'; -import type { RollupVirtualOptions } from '../'; +import type { RollupVirtualOptions, RollupVirtualOption } from '../'; const PREFIX = `\0virtual:`; +const IMPORTER_SEP = `::`; export default function virtual(modules: RollupVirtualOptions): Plugin { - const resolvedIds = new Map(); + const resolvedIds = new Map(); Object.keys(modules).forEach((id) => { resolvedIds.set(path.resolve(id), modules[id]); @@ -17,14 +18,16 @@ export default function virtual(modules: RollupVirtualOptions): Plugin { name: 'virtual', resolveId(id, importer) { - if (id in modules) return PREFIX + id; + const importerSuffix = importer ? `${IMPORTER_SEP}${importer}` : ''; + + if (id in modules) return PREFIX + id + importerSuffix; if (importer) { const importerNoPrefix = importer.startsWith(PREFIX) ? importer.slice(PREFIX.length) : importer; const resolved = path.resolve(path.dirname(importerNoPrefix), id); - if (resolvedIds.has(resolved)) return PREFIX + resolved; + if (resolvedIds.has(resolved)) return PREFIX + resolved + importerSuffix; } return null; @@ -32,9 +35,15 @@ export default function virtual(modules: RollupVirtualOptions): Plugin { load(id) { if (id.startsWith(PREFIX)) { - const idNoPrefix = id.slice(PREFIX.length); + const [idNoPrefix, importer] = id.slice(PREFIX.length).split(IMPORTER_SEP); + + const module = idNoPrefix in modules ? modules[idNoPrefix] : resolvedIds.get(idNoPrefix); + + if (typeof module === 'function') { + return module(importer); + } - return idNoPrefix in modules ? modules[idNoPrefix] : resolvedIds.get(idNoPrefix); + return module; } return null; diff --git a/packages/virtual/test/test.js b/packages/virtual/test/test.js index e57094e03..2ebdb2f44 100755 --- a/packages/virtual/test/test.js +++ b/packages/virtual/test/test.js @@ -22,6 +22,22 @@ test('loads an absolute path from memory', (t) => { const resolved = plugin.resolveId('./foo.js', 'src/main.js'); - t.is(resolved, `\0virtual:${path.resolve('src/foo.js')}`); + t.is(resolved, `\0virtual:${path.resolve('src/foo.js')}::src/main.js`); t.is(plugin.load(resolved), 'export default 42'); }); + +test('use function that takes a module ID', (t) => { + const plugin = virtual({ + routeName: (importer) => { + const routeRoot = 'src/views/'; + const routeName = importer.replace(routeRoot, '').replace(/\.\w+$/, ''); + + return `export const routeName = '${routeName}'`; + } + }); + + const resolved = plugin.resolveId('routeName', 'src/views/user/index.vue'); + + t.is(resolved, `\0virtual:routeName::src/views/user/index.vue`); + t.is(plugin.load(resolved), "export const routeName = 'user/index'"); +}); diff --git a/packages/virtual/types/index.d.ts b/packages/virtual/types/index.d.ts index 34fd38186..5ff242081 100644 --- a/packages/virtual/types/index.d.ts +++ b/packages/virtual/types/index.d.ts @@ -1,7 +1,8 @@ import type { Plugin } from 'rollup'; +export type RollupVirtualOption = string | ((importer: string | undefined) => string); export interface RollupVirtualOptions { - [id: string]: string; + [id: string]: RollupVirtualOption; } /** From ad478de3ad7cd55921659af3b1ea5dae0216e9a7 Mon Sep 17 00:00:00 2001 From: qzs Date: Thu, 23 May 2024 09:43:37 +0000 Subject: [PATCH 2/3] fix: when virtual config is string, no need "importerSuffix" --- packages/virtual/src/index.ts | 17 +++++++++++++---- packages/virtual/test/test.js | 2 +- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/packages/virtual/src/index.ts b/packages/virtual/src/index.ts index f6244a4d5..755da7a23 100644 --- a/packages/virtual/src/index.ts +++ b/packages/virtual/src/index.ts @@ -14,20 +14,29 @@ export default function virtual(modules: RollupVirtualOptions): Plugin { resolvedIds.set(path.resolve(id), modules[id]); }); + function getImporterSuffix(id: string, importer: string | undefined) { + const module = modules[id] ?? resolvedIds.get(id); + if (typeof module === 'function') { + const importerSuffix = importer ? `${IMPORTER_SEP}${importer}` : ''; + return importerSuffix; + } + + return ''; + } + return { name: 'virtual', resolveId(id, importer) { - const importerSuffix = importer ? `${IMPORTER_SEP}${importer}` : ''; - - if (id in modules) return PREFIX + id + importerSuffix; + if (id in modules) return PREFIX + id + getImporterSuffix(id, importer); if (importer) { const importerNoPrefix = importer.startsWith(PREFIX) ? importer.slice(PREFIX.length) : importer; const resolved = path.resolve(path.dirname(importerNoPrefix), id); - if (resolvedIds.has(resolved)) return PREFIX + resolved + importerSuffix; + if (resolvedIds.has(resolved)) + return PREFIX + resolved + getImporterSuffix(resolved, importer); } return null; diff --git a/packages/virtual/test/test.js b/packages/virtual/test/test.js index 2ebdb2f44..5e1d7a37e 100755 --- a/packages/virtual/test/test.js +++ b/packages/virtual/test/test.js @@ -22,7 +22,7 @@ test('loads an absolute path from memory', (t) => { const resolved = plugin.resolveId('./foo.js', 'src/main.js'); - t.is(resolved, `\0virtual:${path.resolve('src/foo.js')}::src/main.js`); + t.is(resolved, `\0virtual:${path.resolve('src/foo.js')}`); t.is(plugin.load(resolved), 'export default 42'); }); From 7c33adf956ba94231135f45c492f76cd4a688280 Mon Sep 17 00:00:00 2001 From: qzs Date: Thu, 6 Jun 2024 09:31:14 +0800 Subject: [PATCH 3/3] fix: Apply suggestions from code review Co-authored-by: Andrew Powell --- packages/virtual/src/index.ts | 4 ++-- packages/virtual/types/index.d.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/virtual/src/index.ts b/packages/virtual/src/index.ts index 755da7a23..7b3bfa734 100644 --- a/packages/virtual/src/index.ts +++ b/packages/virtual/src/index.ts @@ -2,13 +2,13 @@ import * as path from 'path'; import type { Plugin } from 'rollup'; -import type { RollupVirtualOptions, RollupVirtualOption } from '../'; +import type { RollupVirtualOptions, VirtualIdResolver } from '../'; const PREFIX = `\0virtual:`; const IMPORTER_SEP = `::`; export default function virtual(modules: RollupVirtualOptions): Plugin { - const resolvedIds = new Map(); + const resolvedIds = new Map(); Object.keys(modules).forEach((id) => { resolvedIds.set(path.resolve(id), modules[id]); diff --git a/packages/virtual/types/index.d.ts b/packages/virtual/types/index.d.ts index 5ff242081..5d94fc950 100644 --- a/packages/virtual/types/index.d.ts +++ b/packages/virtual/types/index.d.ts @@ -1,8 +1,8 @@ import type { Plugin } from 'rollup'; -export type RollupVirtualOption = string | ((importer: string | undefined) => string); +export type VirtualIdResolver = string | ((importer: string | undefined) => string); export interface RollupVirtualOptions { - [id: string]: RollupVirtualOption; + [id: string]: VirtualIdResolver; } /**