@monkeyplus/flow 5.0.0-rc.199 → 5.0.0-rc.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/build.config.ts +25 -0
  2. package/dist/app/entry.d.ts +2 -2
  3. package/dist/app/entry.mjs +2 -3
  4. package/dist/app/flow.d.ts +3 -12
  5. package/dist/app/flow.mjs +0 -3
  6. package/dist/core/runtime/nitro/flow.d.ts +0 -1
  7. package/dist/core/runtime/nitro/flow.mjs +14 -9
  8. package/dist/core/runtime/nitro/renderer.mjs +18 -82
  9. package/dist/head/runtime/plugin.mjs +1 -0
  10. package/dist/index.mjs +772 -543
  11. package/dist/pages/runtime/helpers/index.d.ts +1 -1
  12. package/dist/pages/runtime/helpers/index.mjs +3 -14
  13. package/dist/pages/runtime/index.d.ts +3 -10
  14. package/dist/pages/runtime/index.mjs +4 -12
  15. package/dist/pages/runtime/plugin.mjs +53 -0
  16. package/dist/vite-client/runtime/injectManifest.d.ts +26 -0
  17. package/dist/vite-client/runtime/injectManifest.mjs +104 -0
  18. package/dist/vite-client/runtime/plugin.d.ts +2 -0
  19. package/dist/vite-client/runtime/plugin.mjs +27 -0
  20. package/package.json +40 -55
  21. package/src/app/composables/index.ts +20 -0
  22. package/src/app/entry.ts +36 -0
  23. package/src/app/flow.ts +157 -0
  24. package/src/app/index.ts +5 -0
  25. package/src/auto-imports/module.ts +143 -0
  26. package/src/auto-imports/presets.ts +49 -0
  27. package/src/auto-imports/transform.ts +48 -0
  28. package/src/core/app.ts +90 -0
  29. package/src/core/builder.ts +60 -0
  30. package/src/core/flow.ts +93 -0
  31. package/src/core/modules.ts +32 -0
  32. package/src/core/nitro.ts +206 -0
  33. package/src/core/plugins/import-protection.ts +49 -0
  34. package/src/core/plugins/unctx.ts +31 -0
  35. package/src/core/runtime/nitro/flow.ts +43 -0
  36. package/src/core/runtime/nitro/paths.ts +20 -0
  37. package/src/core/runtime/nitro/renderer.ts +74 -0
  38. package/src/core/templates.ts +119 -0
  39. package/src/core/vite/builder/css.ts +28 -0
  40. package/src/core/vite/builder/dev-bundler.ts +248 -0
  41. package/src/core/vite/builder/index.ts +96 -0
  42. package/src/core/vite/builder/manifest.ts +33 -0
  43. package/src/core/vite/builder/plugins/analyze.ts +32 -0
  44. package/src/core/vite/builder/plugins/cache-dir.ts +13 -0
  45. package/src/core/vite/builder/plugins/dynamic-base.ts +64 -0
  46. package/src/core/vite/builder/plugins/virtual.ts +45 -0
  47. package/src/core/vite/builder/server.ts +164 -0
  48. package/src/core/vite/builder/types/index.ts +13 -0
  49. package/src/core/vite/builder/utils/index.ts +53 -0
  50. package/src/core/vite/builder/utils/warmup.ts +27 -0
  51. package/src/core/vite/builder/utils/wpfs.ts +7 -0
  52. package/src/core/vite/builder/vite-node.ts +110 -0
  53. package/src/core/vite/client/index.ts +63 -0
  54. package/src/dirs.ts +8 -0
  55. package/src/head/module.ts +37 -0
  56. package/src/head/runtime/composables.ts +16 -0
  57. package/src/head/runtime/index.ts +1 -0
  58. package/src/head/runtime/plugin.ts +12 -0
  59. package/src/index.ts +2 -0
  60. package/src/pages/module.ts +55 -0
  61. package/src/pages/runtime/helpers/chunks.ts +0 -0
  62. package/src/pages/runtime/helpers/index.ts +33 -0
  63. package/src/pages/runtime/index.ts +9 -0
  64. package/src/pages/runtime/plugin.ts +65 -0
  65. package/src/pages/templates.ts +20 -0
  66. package/src/pages/utils.ts +49 -0
  67. package/src/vite-client/module.ts +84 -0
  68. package/src/vite-client/runtime/injectManifest.ts +188 -0
  69. package/src/vite-client/runtime/plugin.ts +33 -0
  70. package/dist/app/entry.async.d.ts +0 -3
  71. package/dist/app/entry.async.mjs +0 -1
  72. package/dist/chunks/dev-bundler.mjs +0 -277
  73. package/dist/core/runtime/client.manifest.d.mts +0 -2
  74. package/dist/core/runtime/client.manifest.mjs +0 -6
  75. package/dist/core/runtime/vite-node-shared.d.mts +0 -1
  76. package/dist/core/runtime/vite-node-shared.d.ts +0 -8
  77. package/dist/core/runtime/vite-node-shared.mjs +0 -3
  78. package/dist/core/runtime/vite-node.d.mts +0 -2
  79. package/dist/core/runtime/vite-node.mjs +0 -41
  80. package/dist/pages/runtime/pages.mjs +0 -123
  81. /package/dist/pages/runtime/{pages.d.ts → plugin.d.ts} +0 -0
@@ -0,0 +1,248 @@
1
+ import { pathToFileURL } from 'node:url';
2
+ import { existsSync } from 'node:fs';
3
+ import { builtinModules } from 'node:module';
4
+ import { resolve } from 'pathe';
5
+ import type * as vite from 'vite';
6
+ import type { ExternalsOptions } from 'externality';
7
+ import { ExternalsDefaults, isExternal as _isExternal } from 'externality';
8
+ import { genDynamicImport, genObjectFromRawEntries } from 'knitwork';
9
+ import { hashId, uniq } from './utils';
10
+
11
+ export interface TransformChunk {
12
+ id: string
13
+ code: string
14
+ deps: string[]
15
+ parents: string[]
16
+ }
17
+
18
+ export interface SSRTransformResult {
19
+ code: string
20
+ map: object
21
+ deps: string[]
22
+ dynamicDeps: string[]
23
+ }
24
+
25
+ export interface TransformOptions {
26
+ viteServer: vite.ViteDevServer
27
+ }
28
+
29
+ function isExternal(opts: TransformOptions, id: string) {
30
+ // Externals
31
+ const ssrConfig = (opts.viteServer.config as any).ssr;
32
+
33
+ const externalOpts: ExternalsOptions = {
34
+ inline: [
35
+ /virtual:/,
36
+ /\.ts$/,
37
+ ...ExternalsDefaults.inline,
38
+ ...ssrConfig.noExternal,
39
+ ],
40
+ external: [
41
+ // * Remove to omit fixed un build
42
+ // ...ssrConfig.external,
43
+ /node_modules/,
44
+ ],
45
+ resolve: {
46
+ type: 'module',
47
+ extensions: ['.ts', '.js', '.json', '.vue', '.mjs', '.jsx', '.tsx', '.wasm'],
48
+ },
49
+ };
50
+ return _isExternal(id, opts.viteServer.config.root, externalOpts);
51
+ }
52
+
53
+ async function transformRequest(opts: TransformOptions, id: string) {
54
+ // Virtual modules start with `\0`
55
+ if (id && id.startsWith('/@id/__x00__'))
56
+ id = `\0${id.slice('/@id/__x00__'.length)}`;
57
+
58
+ if (id && id.startsWith('/@id/'))
59
+ id = id.slice('/@id/'.length);
60
+
61
+ if (id && id.startsWith('/@fs/')) {
62
+ // Absolute path
63
+ id = id.slice('/@fs'.length);
64
+ // On Windows, this may be `/C:/my/path` at this point, in which case we want to remove the `/`
65
+ if (id.match(/^\/\w:/))
66
+ id = id.slice(1);
67
+ }
68
+ else if (!id.includes('entry') && id.startsWith('/')) {
69
+ // Relative to the root directory
70
+ const resolvedPath = resolve(opts.viteServer.config.root, `.${id}`);
71
+ if (existsSync(resolvedPath))
72
+ id = resolvedPath;
73
+ }
74
+
75
+ // Vite will add ?v=123 to bypass browser cache
76
+ // Remove for externals
77
+ const withoutVersionQuery = id.replace(/\?v=\w+$/, '');
78
+ if (await isExternal(opts, withoutVersionQuery)) {
79
+ const path = builtinModules.includes(withoutVersionQuery.split('node:').pop())
80
+ ? withoutVersionQuery
81
+ : pathToFileURL(withoutVersionQuery).href;
82
+ return {
83
+ code: `(global, module, _, exports, importMeta, ssrImport, ssrDynamicImport, ssrExportAll) =>
84
+ ${genDynamicImport(path, { wrapper: false })}
85
+ .then(r => {
86
+ if (r.default && r.default.__esModule)
87
+ r = r.default
88
+ exports.default = r.default
89
+ ssrExportAll(r)
90
+ })
91
+ .catch(e => {
92
+ console.error(e)
93
+ throw new Error(${JSON.stringify(`[vite dev] Error loading external "${id}".`)})
94
+ })`,
95
+ deps: [],
96
+ dynamicDeps: [],
97
+ };
98
+ }
99
+
100
+ // Transform
101
+ const res: SSRTransformResult = await opts.viteServer.transformRequest(id, { ssr: true }).catch((err) => {
102
+ // eslint-disable-next-line no-console
103
+ console.warn(`[SSR] Error transforming ${id}:`, err);
104
+ // console.error(err)
105
+ }) as SSRTransformResult || { code: '', map: {}, deps: [], dynamicDeps: [] };
106
+
107
+ // Wrap into a vite module
108
+ const code = `async function (global, module, exports, __vite_ssr_exports__, __vite_ssr_import_meta__, __vite_ssr_import__, __vite_ssr_dynamic_import__, __vite_ssr_exportAll__) {
109
+ ${res.code || '/* empty */'};
110
+ }`;
111
+ return { code, deps: res.deps || [], dynamicDeps: res.dynamicDeps || [] };
112
+ }
113
+
114
+ async function transformRequestRecursive(opts: TransformOptions, id: any, parent = '<entry>', chunks: Record<string, TransformChunk> = {}) {
115
+ if (chunks[id]) {
116
+ chunks[id].parents.push(parent);
117
+ return;
118
+ }
119
+ const res = await transformRequest(opts, id);
120
+ const deps = uniq([...res.deps, ...res.dynamicDeps]);
121
+
122
+ chunks[id] = {
123
+ id,
124
+ code: res.code,
125
+ deps,
126
+ parents: [parent],
127
+ } as TransformChunk;
128
+ for (const dep of deps)
129
+ await transformRequestRecursive(opts, dep, id, chunks);
130
+
131
+ return Object.values(chunks);
132
+ }
133
+
134
+ export async function bundleRequest(opts: TransformOptions, entryURL: string) {
135
+ const chunks = await transformRequestRecursive(opts, entryURL);
136
+
137
+ const listIds = (ids: string[]) => ids.map((id) => `// - ${id} (${hashId(id)})`).join('\n');
138
+ const chunksCode = chunks!.map((chunk) => `
139
+ // --------------------
140
+ // Request: ${chunk.id}
141
+ // Parents: \n${listIds(chunk.parents)}
142
+ // Dependencies: \n${listIds(chunk.deps)}
143
+ // --------------------
144
+ const ${hashId(chunk.id)} = ${chunk.code}
145
+ `).join('\n');
146
+
147
+ const manifestCode = `const __modules__ = ${
148
+ genObjectFromRawEntries(chunks!.map((chunk) => [chunk.id, hashId(chunk.id)]))
149
+ }`;
150
+
151
+ // https://github.com/vitejs/vite/blob/main/packages/vite/src/node/ssr/ssrModuleLoader.ts
152
+ const ssrModuleLoader = `
153
+ const __pendingModules__ = new Map()
154
+ const __pendingImports__ = new Map()
155
+ const __ssrContext__ = { global: globalThis }
156
+
157
+ function __ssrLoadModule__(url, urlStack = []) {
158
+ const pendingModule = __pendingModules__.get(url)
159
+ if (pendingModule) { return pendingModule }
160
+ const modulePromise = __instantiateModule__(url, urlStack)
161
+ __pendingModules__.set(url, modulePromise)
162
+ modulePromise.catch(() => { __pendingModules__.delete(url) })
163
+ .finally(() => { __pendingModules__.delete(url) })
164
+ return modulePromise
165
+ }
166
+
167
+ async function __instantiateModule__(url, urlStack) {
168
+ const mod = __modules__[url]
169
+ if (mod.stubModule) { return mod.stubModule }
170
+ const stubModule = { [Symbol.toStringTag]: 'Module' }
171
+ Object.defineProperty(stubModule, '__esModule', { value: true })
172
+ mod.stubModule = stubModule
173
+ // https://vitejs.dev/guide/api-hmr.html
174
+ const importMeta = { url, hot: { accept() {}, prune() {}, dispose() {}, invalidate() {}, decline() {}, on() {} } }
175
+ urlStack = urlStack.concat(url)
176
+ const isCircular = url => urlStack.includes(url)
177
+ const pendingDeps = []
178
+ const ssrImport = async (dep) => {
179
+ // TODO: Handle externals if dep[0] !== '.' | '/'
180
+ if (!isCircular(dep) && !__pendingImports__.get(dep)?.some(isCircular)) {
181
+ pendingDeps.push(dep)
182
+ if (pendingDeps.length === 1) {
183
+ __pendingImports__.set(url, pendingDeps)
184
+ }
185
+ await __ssrLoadModule__(dep, urlStack)
186
+ if (pendingDeps.length === 1) {
187
+ __pendingImports__.delete(url)
188
+ } else {
189
+ pendingDeps.splice(pendingDeps.indexOf(dep), 1)
190
+ }
191
+ }
192
+ return __modules__[dep].stubModule
193
+ }
194
+ function ssrDynamicImport (dep) {
195
+ // TODO: Handle dynamic import starting with . relative to url
196
+ return ssrImport(dep)
197
+ }
198
+
199
+ function ssrExportAll(sourceModule) {
200
+ for (const key in sourceModule) {
201
+ if (key !== 'default') {
202
+ try {
203
+ Object.defineProperty(stubModule, key, {
204
+ enumerable: true,
205
+ configurable: true,
206
+ get() { return sourceModule[key] }
207
+ })
208
+ } catch (_err) { }
209
+ }
210
+ }
211
+ }
212
+
213
+ const cjsModule = {
214
+ get exports () {
215
+ return stubModule.default
216
+ },
217
+ set exports (v) {
218
+ stubModule.default = v
219
+ },
220
+ }
221
+
222
+ await mod(
223
+ __ssrContext__.global,
224
+ cjsModule,
225
+ stubModule.default,
226
+ stubModule,
227
+ importMeta,
228
+ ssrImport,
229
+ ssrDynamicImport,
230
+ ssrExportAll
231
+ )
232
+
233
+ return stubModule
234
+ }
235
+ `;
236
+
237
+ const code = [
238
+ chunksCode,
239
+ manifestCode,
240
+ ssrModuleLoader,
241
+ `export default await __ssrLoadModule__(${JSON.stringify(entryURL)})`,
242
+ ].join('\n\n');
243
+
244
+ return {
245
+ code,
246
+ ids: chunks!.map((i) => i.id),
247
+ };
248
+ }
@@ -0,0 +1,96 @@
1
+ import { isIgnoredFlow, logger } from '@monkeyplus/flow-kit';
2
+ import type { Flow } from '@monkeyplus/flow-schema';
3
+ import { getPort } from 'get-port-please';
4
+ import * as vite from 'vite';
5
+ import { resolve } from 'pathe';
6
+ import { sanitizeFilePath } from 'mlly';
7
+ import replace from '@rollup/plugin-replace';
8
+ import { warmupViteServer } from './utils/warmup';
9
+ import { buildServer } from './server';
10
+ import type { ViteBuildContext } from './types';
11
+ import virtual from './plugins/virtual';
12
+ import { DynamicBasePlugin } from './plugins/dynamic-base';
13
+
14
+ export async function bundleVite(flow: Flow) {
15
+ const hmrPortDefault = 24678; // Vite's default HMR port
16
+ const hmrPort = await getPort({
17
+ port: hmrPortDefault,
18
+ ports: Array.from({ length: 20 }, (_, i) => hmrPortDefault + 1 + i),
19
+ });
20
+
21
+ const ctx: ViteBuildContext = {
22
+ nuxt: flow,
23
+ flow,
24
+ config: vite.mergeConfig({
25
+ mode: flow.options.dev ? 'development' : undefined,
26
+ resolve: {
27
+ alias: {
28
+ ...flow.options.alias,
29
+ '#app': flow.options.appDir,
30
+ '#build/plugins': resolve(flow.options.buildDir, 'plugins/server'),
31
+ '#build': flow.options.buildDir,
32
+ '/entry.mjs': resolve(flow.options.appDir, 'entry'),
33
+
34
+ },
35
+ },
36
+ optimizeDeps: {
37
+ entries: [
38
+ resolve(flow.options.appDir, 'entry.ts'),
39
+ ],
40
+ include: [],
41
+ },
42
+ // css: resolveCSSOptions(nuxt),
43
+ build: {
44
+ rollupOptions: {
45
+ output: { sanitizeFileName: sanitizeFilePath },
46
+ input: resolve(flow.options.appDir, 'entry'),
47
+ },
48
+ },
49
+ plugins: [
50
+ replace({
51
+ ...Object.fromEntries([';', '(', '{', '}', ' ', '\t', '\n'].map((d) => [`${d}global.`, `${d}globalThis.`])),
52
+ preventAssignment: true,
53
+ }),
54
+ virtual(flow.vfs),
55
+ DynamicBasePlugin.vite({ sourcemap: flow.options.sourcemap }),
56
+ ],
57
+ server: {
58
+ watch: {
59
+ ignored: isIgnoredFlow,
60
+ },
61
+ hmr: {
62
+ // https://github.com/nuxt/framework/issues/4191
63
+ protocol: 'ws',
64
+ clientPort: hmrPort,
65
+ port: hmrPort,
66
+ },
67
+ fs: {
68
+ allow: [
69
+ flow.options.appDir,
70
+ ],
71
+ },
72
+ },
73
+ }, flow.options.vite),
74
+ };
75
+ if (flow.options.dev)
76
+ ctx.config.mode = process.env.NODE_ENV || 'development';
77
+
78
+ await flow.callHook('vite:extend', ctx);
79
+
80
+ flow.hook('vite:serverCreated', (server: vite.ViteDevServer) => {
81
+ // Invalidate virtual modules when templates are re-generated
82
+ ctx.nuxt.hook('app:templatesGenerated', () => {
83
+ for (const [id, mod] of server.moduleGraph.idToModuleMap) {
84
+ if (id.startsWith('\x00virtual:'))
85
+ server.moduleGraph.invalidateModule(mod);
86
+ }
87
+ });
88
+
89
+ const start = Date.now();
90
+ warmupViteServer(server, ['/entry.mjs'])
91
+ .then(() => logger.info(`Vite server warmed up in ${Date.now() - start}ms`))
92
+ .catch(logger.error);
93
+ });
94
+
95
+ await buildServer(ctx);
96
+ }
@@ -0,0 +1,33 @@
1
+ import fse from 'fs-extra';
2
+ import { resolve } from 'pathe';
3
+ import { joinURL } from 'ufo';
4
+ import type { ViteBuildContext } from './types';
5
+
6
+ export async function writeManifest(ctx: ViteBuildContext, extraEntries: string[] = []) {
7
+ // Write client manifest for use in vue-bundle-renderer
8
+ const clientDist = resolve(ctx.flow.options.buildDir, 'dist/client');
9
+ const serverDist = resolve(ctx.flow.options.buildDir, 'dist/server');
10
+
11
+ const entries = [
12
+ '@vite/client',
13
+ 'entry.mjs',
14
+ ...extraEntries,
15
+ ];
16
+
17
+ // Legacy dev manifest
18
+ const devClientManifest = {
19
+ publicPath: joinURL(ctx.flow.options.app.baseURL, ctx.flow.options.app.buildAssetsDir),
20
+ all: entries,
21
+ initial: entries,
22
+ async: [],
23
+ modules: {},
24
+ };
25
+
26
+ const clientManifest = ctx.flow.options.dev
27
+ ? devClientManifest
28
+ : await fse.readJSON(resolve(clientDist, 'manifest.json'));
29
+
30
+ await fse.mkdirp(serverDist);
31
+ await fse.writeFile(resolve(serverDist, 'client.manifest.json'), JSON.stringify(clientManifest, null, 2), 'utf8');
32
+ await fse.writeFile(resolve(serverDist, 'client.manifest.mjs'), `export default ${JSON.stringify(clientManifest, null, 2)}`, 'utf8');
33
+ }
@@ -0,0 +1,32 @@
1
+ // import type { Plugin } from 'vite';
2
+ // import { transform } from 'esbuild';
3
+ // // import { visualizer } from 'rollup-plugin-visualizer';
4
+ // import type { ViteBuildContext } from '../types';
5
+
6
+ // export function analyzePlugin(ctx: ViteBuildContext): Plugin[] {
7
+ // return [
8
+ // {
9
+ // name: 'nuxt:analyze-minify',
10
+ // async generateBundle(_opts, outputBundle) {
11
+ // for (const [_bundleId, bundle] of Object.entries(outputBundle)) {
12
+ // if (bundle.type !== 'chunk') continue;
13
+ // const originalEntries = Object.entries(bundle.modules);
14
+ // const minifiedEntries = await Promise.all(originalEntries.map(async([moduleId, module]) => {
15
+ // const { code } = await transform(module.code || '', { minify: true });
16
+ // return [moduleId, { ...module, code }];
17
+ // }));
18
+ // bundle.modules = Object.fromEntries(minifiedEntries);
19
+ // }
20
+ // return null;
21
+ // },
22
+ // },
23
+ // // visualizer({
24
+ // // // @ts-ignore
25
+ // // ...ctx.flow.options?.build?.analyze as any,
26
+ // // // @ts-ignore
27
+ // // filename: ctx.flow.options.build.analyze.filename.replace('{name}', 'client'),
28
+ // // title: 'Client bundle stats',
29
+ // // gzipSize: true,
30
+ // // }),
31
+ // ];
32
+ // }
@@ -0,0 +1,13 @@
1
+ import { resolve } from 'pathe';
2
+ import type { Plugin } from 'vite';
3
+
4
+ export function cacheDirPlugin(rootDir: string, name: string) {
5
+ const optimizeCacheDir = resolve(rootDir, 'node_modules/.cache/vite', name);
6
+ return <Plugin> {
7
+ name: 'flow:cache-dir',
8
+ configResolved(resolvedConfig) {
9
+ // @ts-ignore
10
+ resolvedConfig.optimizeCacheDir = optimizeCacheDir;
11
+ },
12
+ };
13
+ }
@@ -0,0 +1,64 @@
1
+ import { createUnplugin } from 'unplugin';
2
+
3
+ import MagicString from 'magic-string';
4
+
5
+ interface DynamicBasePluginOptions {
6
+ globalPublicPath?: string
7
+ sourcemap?: boolean
8
+ }
9
+
10
+ const VITE_ASSET_RE = /^export default ["'](__VITE_ASSET.*)["']$/;
11
+
12
+ export const DynamicBasePlugin = createUnplugin((options: DynamicBasePluginOptions = {}) => {
13
+ return {
14
+ name: 'nuxt:dynamic-base-path',
15
+ resolveId(id) {
16
+ if (id.startsWith('/__NUXT_BASE__'))
17
+ return id.replace('/__NUXT_BASE__', '');
18
+
19
+ if (id === '#internal/nitro') return '#internal/nitro';
20
+ return null;
21
+ },
22
+ enforce: 'post',
23
+ transform(code, id) {
24
+ const s = new MagicString(code);
25
+
26
+ if (options.globalPublicPath && id.includes('paths.mjs') && code.includes('const appConfig = '))
27
+ s.append(`${options.globalPublicPath} = buildAssetsURL();\n`);
28
+
29
+ const assetId = code.match(VITE_ASSET_RE);
30
+ if (assetId) {
31
+ s.overwrite(0, code.length,
32
+ [
33
+ 'import { buildAssetsURL } from \'#build/paths.mjs\';',
34
+ `export default buildAssetsURL("${assetId[1]}".replace("/__NUXT_BASE__", ""));`,
35
+ ].join('\n'),
36
+ );
37
+ }
38
+
39
+ if (!id.includes('paths.mjs') && code.includes('NUXT_BASE') && !code.includes('import { publicAssetsURL as __publicAssetsURL }'))
40
+ s.prepend('import { publicAssetsURL as __publicAssetsURL } from \'#build/paths.mjs\';\n');
41
+
42
+ if (id === 'vite/preload-helper') {
43
+ // Define vite base path as buildAssetsUrl (i.e. including _nuxt/)
44
+ s.prepend('import { buildAssetsDir } from \'#build/paths.mjs\';\n');
45
+ s.replace(/const base = ['"]\/__NUXT_BASE__\/['"]/, 'const base = buildAssetsDir()');
46
+ }
47
+
48
+ // Sanitize imports
49
+ s.replace(/from *['"]\/__NUXT_BASE__(\/[^'"]*)['"]/g, 'from "$1"');
50
+
51
+ // Dynamically compute string URLs featuring baseURL
52
+ const delimiterRE = /(?<!(const base = |from *))(`([^`]*)\/__NUXT_BASE__\/([^`]*)`|'([^']*)\/__NUXT_BASE__\/([^']*)'|"([^"]*)\/__NUXT_BASE__\/([^"]*)")/g;
53
+ /* eslint-disable-next-line no-template-curly-in-string */
54
+ s.replace(delimiterRE, (r) => `\`${r.replace(/\/__NUXT_BASE__\//g, '${__publicAssetsURL()}').slice(1, -1)}\``);
55
+
56
+ if (s.hasChanged()) {
57
+ return {
58
+ code: s.toString(),
59
+ map: options.sourcemap && s.generateMap({ source: id, includeContent: true }),
60
+ };
61
+ }
62
+ },
63
+ };
64
+ });
@@ -0,0 +1,45 @@
1
+ import { dirname, isAbsolute, join, resolve } from 'pathe';
2
+ import type { Plugin } from 'rollup';
3
+
4
+ const PREFIX = 'virtual:';
5
+
6
+ export default function virtual(vfs: Record<string, string>): Plugin {
7
+ const extensions = ['', '.ts', '.vue', '.mjs', '.cjs', '.js', '.json'];
8
+ const resolveWithExt = (id: any) => {
9
+ for (const ext of extensions) {
10
+ const rId = id + ext;
11
+ if (rId in vfs)
12
+ return rId;
13
+ }
14
+ return null;
15
+ };
16
+
17
+ return {
18
+ name: 'virtual',
19
+
20
+ resolveId(id, importer) {
21
+ if (process.platform === 'win32' && isAbsolute(id)) {
22
+ // Add back C: prefix on Windows
23
+ id = resolve(id);
24
+ }
25
+ const resolvedId = resolveWithExt(id);
26
+ if (resolvedId) return PREFIX + resolvedId;
27
+ if (importer && !isAbsolute(id)) {
28
+ const importerNoPrefix = importer.startsWith(PREFIX) ? importer.slice(PREFIX.length) : importer;
29
+ const importedDir = dirname(importerNoPrefix);
30
+ const resolved = resolveWithExt(join(importedDir, id));
31
+ if (resolved) return PREFIX + resolved;
32
+ }
33
+ return null;
34
+ },
35
+
36
+ load(id) {
37
+ if (!id.startsWith(PREFIX)) return null;
38
+ const idNoPrefix = id.slice(PREFIX.length);
39
+ return {
40
+ code: vfs[idNoPrefix],
41
+ map: null,
42
+ };
43
+ },
44
+ };
45
+ }