@typed/vite-plugin 0.0.20 → 0.0.22
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.
- package/dist/prerender.d.ts +6 -0
- package/dist/prerender.d.ts.map +1 -0
- package/dist/prerender.js +44 -0
- package/dist/prerender.js.map +1 -0
- package/dist/staticHtmlPlugin.d.ts +2 -0
- package/dist/staticHtmlPlugin.d.ts.map +1 -0
- package/dist/staticHtmlPlugin.js +2 -0
- package/dist/staticHtmlPlugin.js.map +1 -0
- package/dist/vite-plugin.d.ts +63 -2
- package/dist/vite-plugin.d.ts.map +1 -1
- package/dist/vite-plugin.js +182 -58
- package/dist/vite-plugin.js.map +1 -1
- package/package.json +8 -4
- package/src/vite-plugin.ts +326 -67
- package/tsconfig.build.tsbuildinfo +1 -1
- package/tsconfig.json +3 -0
- package/dist/browser.d.ts +0 -3
- package/dist/browser.d.ts.map +0 -1
- package/dist/browser.js +0 -4
- package/dist/browser.js.map +0 -1
- package/dist/server.d.ts +0 -3
- package/dist/server.d.ts.map +0 -1
- package/dist/server.js +0 -4
- package/dist/server.js.map +0 -1
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ModuleTreeJsonWithFallback } from '@typed/compiler';
|
|
2
|
+
import type { ClientManifest, HtmlEntryFile } from './vite-plugin.js';
|
|
3
|
+
export declare function collectModuleTrees(clientManifest: ClientManifest): Map<HtmlEntryFile, import("@typed/compiler").SourceFileToJson<import("@typed/compiler").ModuleTreeWithFallback>[]>;
|
|
4
|
+
export declare function collectStaticPaths(htmlEntryFile: HtmlEntryFile, moduleTrees: ModuleTreeJsonWithFallback[]): Promise<ReadonlyArray<string>>;
|
|
5
|
+
export declare function collectStaticPathsFromTree(htmlEntryFile: HtmlEntryFile, moduleTree: ModuleTreeJsonWithFallback): Promise<Set<string>>;
|
|
6
|
+
//# sourceMappingURL=prerender.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prerender.d.ts","sourceRoot":"","sources":["../src/prerender.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAA;AAGjE,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAErE,wBAAgB,kBAAkB,CAAC,cAAc,EAAE,cAAc,sHA2BhE;AAED,wBAAsB,kBAAkB,CACtC,aAAa,EAAE,aAAa,EAC5B,WAAW,EAAE,0BAA0B,EAAE,GACxC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAUhC;AAED,wBAAsB,0BAA0B,CAC9C,aAAa,EAAE,aAAa,EAC5B,UAAU,EAAE,0BAA0B,GACrC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAatB"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { join } from 'path';
|
|
2
|
+
import { pathCardinality } from '@typed/framework';
|
|
3
|
+
export function collectModuleTrees(clientManifest) {
|
|
4
|
+
const entryFileToModuleTrees = new Map();
|
|
5
|
+
// Retrieve all module trees from the client manifest
|
|
6
|
+
for (const htmlEntryFile of clientManifest.entryFiles) {
|
|
7
|
+
for (const i of htmlEntryFile.imports) {
|
|
8
|
+
const manifestEntries = clientManifest.modules[i];
|
|
9
|
+
if (!manifestEntries) {
|
|
10
|
+
continue;
|
|
11
|
+
}
|
|
12
|
+
for (const key in manifestEntries) {
|
|
13
|
+
const manifestEntry = manifestEntries[key];
|
|
14
|
+
if (manifestEntry.type === 'runtime' || manifestEntry.type === 'browser') {
|
|
15
|
+
if (entryFileToModuleTrees.get(htmlEntryFile)?.push(manifestEntry)) {
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
entryFileToModuleTrees.set(htmlEntryFile, [manifestEntry]);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return entryFileToModuleTrees;
|
|
24
|
+
}
|
|
25
|
+
export async function collectStaticPaths(htmlEntryFile, moduleTrees) {
|
|
26
|
+
const staticPaths = new Set();
|
|
27
|
+
for (const moduleTree of moduleTrees) {
|
|
28
|
+
const paths = await collectStaticPathsFromTree(htmlEntryFile, moduleTree);
|
|
29
|
+
paths.forEach((p) => staticPaths.add(p));
|
|
30
|
+
}
|
|
31
|
+
return Array.from(staticPaths).sort((a, b) => pathCardinality(a, b));
|
|
32
|
+
}
|
|
33
|
+
export async function collectStaticPathsFromTree(htmlEntryFile, moduleTree) {
|
|
34
|
+
const staticPaths = new Set();
|
|
35
|
+
// Collect all static paths
|
|
36
|
+
for (const mod of moduleTree.modules) {
|
|
37
|
+
staticPaths.add(join(htmlEntryFile.basePath, mod.route));
|
|
38
|
+
}
|
|
39
|
+
for (const child of moduleTree.children) {
|
|
40
|
+
await collectStaticPathsFromTree(htmlEntryFile, child);
|
|
41
|
+
}
|
|
42
|
+
return staticPaths;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=prerender.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prerender.js","sourceRoot":"","sources":["../src/prerender.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAG3B,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAIlD,MAAM,UAAU,kBAAkB,CAAC,cAA8B;IAC/D,MAAM,sBAAsB,GAAG,IAAI,GAAG,EAA+C,CAAA;IAErF,qDAAqD;IACrD,KAAK,MAAM,aAAa,IAAI,cAAc,CAAC,UAAU,EAAE;QACrD,KAAK,MAAM,CAAC,IAAI,aAAa,CAAC,OAAO,EAAE;YACrC,MAAM,eAAe,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;YAEjD,IAAI,CAAC,eAAe,EAAE;gBACpB,SAAQ;aACT;YAED,KAAK,MAAM,GAAG,IAAI,eAAe,EAAE;gBACjC,MAAM,aAAa,GAAG,eAAe,CAAC,GAAG,CAAC,CAAA;gBAE1C,IAAI,aAAa,CAAC,IAAI,KAAK,SAAS,IAAI,aAAa,CAAC,IAAI,KAAK,SAAS,EAAE;oBACxE,IAAI,sBAAsB,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,IAAI,CAAC,aAAa,CAAC,EAAE;wBAClE,SAAQ;qBACT;oBAED,sBAAsB,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC,aAAa,CAAC,CAAC,CAAA;iBAC3D;aACF;SACF;KACF;IAED,OAAO,sBAAsB,CAAA;AAC/B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,aAA4B,EAC5B,WAAyC;IAEzC,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU,CAAA;IAErC,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE;QACpC,MAAM,KAAK,GAAG,MAAM,0BAA0B,CAAC,aAAa,EAAE,UAAU,CAAC,CAAA;QAEzE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA;KACzC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;AACtE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAC9C,aAA4B,EAC5B,UAAsC;IAEtC,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU,CAAA;IAErC,2BAA2B;IAC3B,KAAK,MAAM,GAAG,IAAI,UAAU,CAAC,OAAO,EAAE;QACpC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,QAAQ,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAA;KACzD;IAED,KAAK,MAAM,KAAK,IAAI,UAAU,CAAC,QAAQ,EAAE;QACvC,MAAM,0BAA0B,CAAC,aAAa,EAAE,KAAK,CAAC,CAAA;KACvD;IAED,OAAO,WAAW,CAAA;AACpB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"staticHtmlPlugin.d.ts","sourceRoot":"","sources":["../src/staticHtmlPlugin.ts"],"names":[],"mappings":"AAAA,wBAAgB,gBAAgB,SAAM"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"staticHtmlPlugin.js","sourceRoot":"","sources":["../src/staticHtmlPlugin.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,gBAAgB,KAAK,CAAC"}
|
package/dist/vite-plugin.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type ApiModuleTreeJson, type ModuleTreeJsonWithFallback } from '@typed/compiler';
|
|
2
|
+
import type { Plugin, PluginOption } from 'vite';
|
|
2
3
|
/**
|
|
3
4
|
* The Configuration for the Typed Plugin. All file paths can be relative to sourceDirectory or
|
|
4
5
|
* can be absolute, path.resolve is used to stitch things together.
|
|
@@ -38,6 +39,66 @@ export interface PluginOptions {
|
|
|
38
39
|
* If true, will configure the plugin to save all the generated files to disk
|
|
39
40
|
*/
|
|
40
41
|
readonly saveGeneratedModules?: boolean;
|
|
42
|
+
/**
|
|
43
|
+
* If true, will configure the plugin to operate in a static build mode.
|
|
44
|
+
*/
|
|
45
|
+
readonly isStaticBuild?: boolean;
|
|
46
|
+
}
|
|
47
|
+
export declare const PLUGIN_NAME = "@typed/vite-plugin";
|
|
48
|
+
export interface TypedVitePlugin extends Plugin {
|
|
49
|
+
readonly name: typeof PLUGIN_NAME;
|
|
50
|
+
readonly resolvedOptions: ResolvedOptions;
|
|
51
|
+
}
|
|
52
|
+
export interface Manifest {
|
|
53
|
+
readonly entryFiles: EntryFile[];
|
|
54
|
+
readonly modules: {
|
|
55
|
+
[importer: string]: Record<string, ManifestEntry>;
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
export interface ClientManifest extends Manifest {
|
|
59
|
+
readonly entryFiles: HtmlEntryFile[];
|
|
60
|
+
readonly modules: {
|
|
61
|
+
[importer: string]: Record<string, ManifestEntry>;
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
export type EntryFile = HtmlEntryFile | TsEntryFile;
|
|
65
|
+
export interface HtmlEntryFile {
|
|
66
|
+
readonly type: 'html';
|
|
67
|
+
readonly filePath: string;
|
|
68
|
+
readonly imports: string[];
|
|
69
|
+
readonly basePath: string;
|
|
70
|
+
}
|
|
71
|
+
export interface TsEntryFile {
|
|
72
|
+
readonly type: 'ts';
|
|
73
|
+
readonly filePath: string;
|
|
74
|
+
}
|
|
75
|
+
export type ManifestEntry = ApiManifestEntry | ExpressManifestEntry | HtmlManifestEntry | RuntimeManifestEntry | BrowserManifestEntry;
|
|
76
|
+
export interface ApiManifestEntry extends ApiModuleTreeJson {
|
|
77
|
+
readonly type: 'api';
|
|
78
|
+
}
|
|
79
|
+
export interface ExpressManifestEntry extends ApiModuleTreeJson {
|
|
80
|
+
readonly type: 'express';
|
|
81
|
+
}
|
|
82
|
+
export interface HtmlManifestEntry {
|
|
83
|
+
readonly type: 'html';
|
|
84
|
+
readonly filePath: string;
|
|
85
|
+
}
|
|
86
|
+
export interface BrowserManifestEntry extends ModuleTreeJsonWithFallback {
|
|
87
|
+
readonly type: 'browser';
|
|
88
|
+
}
|
|
89
|
+
export interface RuntimeManifestEntry extends ModuleTreeJsonWithFallback {
|
|
90
|
+
readonly type: 'runtime';
|
|
91
|
+
}
|
|
92
|
+
export interface ResolvedOptions {
|
|
93
|
+
readonly sourceDirectory: string;
|
|
94
|
+
readonly tsConfig: string;
|
|
95
|
+
readonly serverFilePath: string;
|
|
96
|
+
readonly clientOutputDirectory: string;
|
|
97
|
+
readonly serverOutputDirectory: string;
|
|
98
|
+
readonly htmlFiles: readonly string[];
|
|
99
|
+
readonly debug: boolean;
|
|
100
|
+
readonly saveGeneratedModules: boolean;
|
|
101
|
+
readonly isStaticBuild: boolean;
|
|
41
102
|
}
|
|
42
|
-
export default function makePlugin({ sourceDirectory: directory, tsConfig, serverFilePath, clientOutputDirectory, serverOutputDirectory, htmlFileGlobs, debug, saveGeneratedModules, }: PluginOptions): PluginOption[];
|
|
103
|
+
export default function makePlugin({ sourceDirectory: directory, tsConfig, serverFilePath, clientOutputDirectory, serverOutputDirectory, htmlFileGlobs, debug, saveGeneratedModules, isStaticBuild, }: PluginOptions): PluginOption[];
|
|
43
104
|
//# sourceMappingURL=vite-plugin.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vite-plugin.d.ts","sourceRoot":"","sources":["../src/vite-plugin.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"vite-plugin.d.ts","sourceRoot":"","sources":["../src/vite-plugin.ts"],"names":[],"mappings":"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"}
|
package/dist/vite-plugin.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { existsSync } from 'fs';
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync } from 'fs';
|
|
2
2
|
import { readFile } from 'fs/promises';
|
|
3
|
-
import {
|
|
3
|
+
import { EOL } from 'os';
|
|
4
|
+
import { basename, dirname, join, relative, resolve } from 'path';
|
|
4
5
|
import effectTransformer from '@effect/language-service/transformer';
|
|
5
|
-
import { setupTsProject, makeHtmlModule, makeRuntimeModule, readDirectory, readModules, readApiModules, makeApiModule, } from '@typed/compiler';
|
|
6
|
+
import { setupTsProject, makeHtmlModule, makeRuntimeModule, readDirectory, readModules, readApiModules, makeApiModule, moduleTreeToJson, apiModuleTreeToJson, } from '@typed/compiler';
|
|
6
7
|
import glob from 'fast-glob';
|
|
7
8
|
import { Project, SourceFile, ts } from 'ts-morph';
|
|
8
9
|
// @ts-expect-error Unable to resolve types w/ NodeNext
|
|
@@ -10,12 +11,13 @@ import vavite from 'vavite';
|
|
|
10
11
|
import compression from 'vite-plugin-compression';
|
|
11
12
|
import tsconfigPaths from 'vite-tsconfig-paths';
|
|
12
13
|
const cwd = process.cwd();
|
|
13
|
-
const PLUGIN_NAME = '@typed/vite-plugin';
|
|
14
|
+
export const PLUGIN_NAME = '@typed/vite-plugin';
|
|
14
15
|
const RUNTIME_VIRTUAL_ENTRYPOINT_PREFIX = 'runtime';
|
|
15
16
|
const BROWSER_VIRTUAL_ENTRYPOINT_PREFIX = 'browser';
|
|
16
17
|
const HTML_VIRTUAL_ENTRYPOINT_PREFIX = 'html';
|
|
17
18
|
const API_VIRTUAL_ENTRYPOINT_PREFIX = 'api';
|
|
18
19
|
const EXPRESS_VIRTUAL_ENTRYPOINT_PREFIX = 'express';
|
|
20
|
+
const TYPED_CONFIG_IMPORT = 'typed:config';
|
|
19
21
|
const PREFIXES = [
|
|
20
22
|
RUNTIME_VIRTUAL_ENTRYPOINT_PREFIX,
|
|
21
23
|
BROWSER_VIRTUAL_ENTRYPOINT_PREFIX,
|
|
@@ -24,7 +26,7 @@ const PREFIXES = [
|
|
|
24
26
|
EXPRESS_VIRTUAL_ENTRYPOINT_PREFIX,
|
|
25
27
|
];
|
|
26
28
|
const VIRTUAL_ID_PREFIX = '\0';
|
|
27
|
-
export default function makePlugin({ sourceDirectory: directory, tsConfig, serverFilePath, clientOutputDirectory, serverOutputDirectory, htmlFileGlobs, debug = false, saveGeneratedModules = false, }) {
|
|
29
|
+
export default function makePlugin({ sourceDirectory: directory, tsConfig, serverFilePath, clientOutputDirectory, serverOutputDirectory, htmlFileGlobs, debug = false, saveGeneratedModules = false, isStaticBuild = false, }) {
|
|
28
30
|
// Resolved options
|
|
29
31
|
const sourceDirectory = resolve(cwd, directory);
|
|
30
32
|
const tsConfigFilePath = resolve(sourceDirectory, tsConfig ?? 'tsconfig.json');
|
|
@@ -40,9 +42,32 @@ export default function makePlugin({ sourceDirectory: directory, tsConfig, serve
|
|
|
40
42
|
optimize: defaultIncludeExcludeTs,
|
|
41
43
|
debug: debug ? defaultIncludeExcludeTs : {},
|
|
42
44
|
};
|
|
45
|
+
const resolvedOptions = {
|
|
46
|
+
sourceDirectory,
|
|
47
|
+
tsConfig: tsConfigFilePath,
|
|
48
|
+
serverFilePath: resolvedServerFilePath,
|
|
49
|
+
serverOutputDirectory: resolvedServerOutputDirectory,
|
|
50
|
+
clientOutputDirectory: resolvedClientOutputDirectory,
|
|
51
|
+
htmlFiles: findHtmlFiles(sourceDirectory, htmlFileGlobs).map((p) => resolve(sourceDirectory, p)),
|
|
52
|
+
debug,
|
|
53
|
+
saveGeneratedModules,
|
|
54
|
+
isStaticBuild,
|
|
55
|
+
};
|
|
43
56
|
const dependentsMap = new Map();
|
|
44
57
|
const filePathToModule = new Map();
|
|
58
|
+
const manifest = {
|
|
59
|
+
entryFiles: [],
|
|
60
|
+
modules: {},
|
|
61
|
+
};
|
|
62
|
+
const addManifestEntry = (entry, importer, id) => {
|
|
63
|
+
if (!manifest.modules[importer]) {
|
|
64
|
+
manifest.modules[importer] = {};
|
|
65
|
+
}
|
|
66
|
+
manifest.modules[importer][id] = entry;
|
|
67
|
+
};
|
|
45
68
|
let devServer;
|
|
69
|
+
let logger;
|
|
70
|
+
let isSsr = false;
|
|
46
71
|
let project;
|
|
47
72
|
let transformers;
|
|
48
73
|
const serverExists = existsSync(resolvedServerFilePath);
|
|
@@ -50,22 +75,20 @@ export default function makePlugin({ sourceDirectory: directory, tsConfig, serve
|
|
|
50
75
|
tsconfigPaths({
|
|
51
76
|
projects: [tsConfigFilePath],
|
|
52
77
|
}),
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
]
|
|
60
|
-
: []),
|
|
78
|
+
serverExists &&
|
|
79
|
+
!isStaticBuild &&
|
|
80
|
+
vavite({
|
|
81
|
+
serverEntry: resolvedServerFilePath,
|
|
82
|
+
serveClientAssetsInDev: true,
|
|
83
|
+
}),
|
|
61
84
|
];
|
|
62
85
|
const setupProject = () => {
|
|
63
86
|
if (project) {
|
|
64
87
|
return;
|
|
65
88
|
}
|
|
66
|
-
info(`Setting up TypeScript project
|
|
89
|
+
info(`Setting up TypeScript project...`, logger);
|
|
67
90
|
project = setupTsProject(tsConfigFilePath);
|
|
68
|
-
info(`Setup TypeScript project
|
|
91
|
+
info(`Setup TypeScript project.`, logger);
|
|
69
92
|
// Setup transformer for virtual modules.
|
|
70
93
|
transformers = {
|
|
71
94
|
before: [
|
|
@@ -78,7 +101,9 @@ export default function makePlugin({ sourceDirectory: directory, tsConfig, serve
|
|
|
78
101
|
setupProject();
|
|
79
102
|
return {
|
|
80
103
|
...project.getCompilerOptions(),
|
|
81
|
-
|
|
104
|
+
inlineSourceMap: false,
|
|
105
|
+
inlineSources: saveGeneratedModules,
|
|
106
|
+
sourceMap: true,
|
|
82
107
|
};
|
|
83
108
|
};
|
|
84
109
|
const handleFileChange = async (path, event) => {
|
|
@@ -101,7 +126,7 @@ export default function makePlugin({ sourceDirectory: directory, tsConfig, serve
|
|
|
101
126
|
for (const dependent of dependents ?? []) {
|
|
102
127
|
const mod = devServer.moduleGraph.getModuleById(dependent);
|
|
103
128
|
if (mod) {
|
|
104
|
-
info(`reloading ${dependent}
|
|
129
|
+
info(`reloading ${dependent}`, logger);
|
|
105
130
|
await devServer.reloadModule(mod);
|
|
106
131
|
}
|
|
107
132
|
}
|
|
@@ -115,19 +140,23 @@ export default function makePlugin({ sourceDirectory: directory, tsConfig, serve
|
|
|
115
140
|
}
|
|
116
141
|
}
|
|
117
142
|
};
|
|
118
|
-
const
|
|
143
|
+
const buildRuntimeModule = async (importer, id) => {
|
|
119
144
|
const moduleDirectory = resolve(dirname(importer), parseModulesFromId(id, importer));
|
|
120
145
|
const relativeDirectory = relative(sourceDirectory, moduleDirectory);
|
|
121
146
|
const isBrowser = id.startsWith(BROWSER_VIRTUAL_ENTRYPOINT_PREFIX);
|
|
122
147
|
const moduleType = isBrowser ? 'browser' : 'runtime';
|
|
123
148
|
const filePath = `${moduleDirectory}.${moduleType}.__generated__.ts`;
|
|
124
|
-
info(`Building ${moduleType} module for ${relativeDirectory}...`);
|
|
125
149
|
const directory = await readDirectory(moduleDirectory);
|
|
126
150
|
const moduleTree = readModules(project, directory);
|
|
151
|
+
addManifestEntry({
|
|
152
|
+
type: moduleType,
|
|
153
|
+
...moduleTreeToJson(sourceDirectory, moduleTree),
|
|
154
|
+
}, relative(sourceDirectory, importer), id);
|
|
127
155
|
// Setup the TypeScript project if it hasn't been already
|
|
128
156
|
setupProject();
|
|
129
157
|
const sourceFile = makeRuntimeModule(project, moduleTree, importer, filePath, isBrowser);
|
|
130
|
-
|
|
158
|
+
addDependents(sourceFile);
|
|
159
|
+
info(`Built ${moduleType} module for ${relativeDirectory}.`, logger);
|
|
131
160
|
filePathToModule.set(filePath, sourceFile);
|
|
132
161
|
if (saveGeneratedModules) {
|
|
133
162
|
await sourceFile.save();
|
|
@@ -139,9 +168,8 @@ export default function makePlugin({ sourceDirectory: directory, tsConfig, serve
|
|
|
139
168
|
const htmlFilePath = resolve(dirname(importer), htmlFileName + '.html');
|
|
140
169
|
const relativeHtmlFilePath = relative(sourceDirectory, htmlFilePath);
|
|
141
170
|
let html = '';
|
|
142
|
-
info(`Building html module for ${relativeHtmlFilePath}...`);
|
|
143
171
|
// If there's a dev server, use it to transform the HTML for development
|
|
144
|
-
if (devServer) {
|
|
172
|
+
if (!isStaticBuild && devServer) {
|
|
145
173
|
html = (await readFile(htmlFilePath, 'utf-8')).toString();
|
|
146
174
|
html = await devServer.transformIndexHtml(getRelativePath(sourceDirectory, htmlFilePath), html);
|
|
147
175
|
}
|
|
@@ -157,8 +185,14 @@ export default function makePlugin({ sourceDirectory: directory, tsConfig, serve
|
|
|
157
185
|
serverOutputDirectory: resolvedServerOutputDirectory,
|
|
158
186
|
clientOutputDirectory: resolvedClientOutputDirectory,
|
|
159
187
|
devServer,
|
|
188
|
+
isStaticBuild,
|
|
160
189
|
});
|
|
161
|
-
|
|
190
|
+
addManifestEntry({
|
|
191
|
+
type: 'html',
|
|
192
|
+
filePath: relativeHtmlFilePath,
|
|
193
|
+
}, relative(sourceDirectory, importer), id);
|
|
194
|
+
addDependents(sourceFile);
|
|
195
|
+
info(`Built html module for ${relativeHtmlFilePath}.`, logger);
|
|
162
196
|
const filePath = sourceFile.getFilePath();
|
|
163
197
|
filePathToModule.set(filePath, sourceFile);
|
|
164
198
|
if (saveGeneratedModules) {
|
|
@@ -171,35 +205,54 @@ export default function makePlugin({ sourceDirectory: directory, tsConfig, serve
|
|
|
171
205
|
const moduleName = parseModulesFromId(id, importer);
|
|
172
206
|
const moduleDirectory = resolve(importDirectory, moduleName);
|
|
173
207
|
const relativeDirectory = relative(sourceDirectory, moduleDirectory);
|
|
174
|
-
const moduleType = id.startsWith(EXPRESS_VIRTUAL_ENTRYPOINT_PREFIX) ? 'express' : '
|
|
175
|
-
info(`Building ${moduleType} module for ${relativeDirectory}...`);
|
|
208
|
+
const moduleType = id.startsWith(EXPRESS_VIRTUAL_ENTRYPOINT_PREFIX) ? 'express' : 'api';
|
|
176
209
|
const directory = await readDirectory(moduleDirectory);
|
|
177
210
|
const moduleTree = readApiModules(project, directory);
|
|
178
211
|
const filePath = `${importDirectory}/${basename(moduleName)}.${moduleType.toLowerCase()}.__generated__.ts`;
|
|
179
212
|
const sourceFile = makeApiModule(project, moduleTree, filePath, importer, id.startsWith(EXPRESS_VIRTUAL_ENTRYPOINT_PREFIX));
|
|
180
|
-
|
|
213
|
+
addManifestEntry({
|
|
214
|
+
type: moduleType,
|
|
215
|
+
...apiModuleTreeToJson(sourceDirectory, moduleTree),
|
|
216
|
+
}, relative(sourceDirectory, importer), id);
|
|
217
|
+
addDependents(sourceFile);
|
|
218
|
+
info(`Built ${moduleType} module for ${relativeDirectory}.`, logger);
|
|
181
219
|
filePathToModule.set(filePath, sourceFile);
|
|
182
220
|
if (saveGeneratedModules) {
|
|
183
221
|
await sourceFile.save();
|
|
184
222
|
}
|
|
185
223
|
return filePath;
|
|
186
224
|
};
|
|
225
|
+
const addDependents = (sourceFile) => {
|
|
226
|
+
const importer = sourceFile.getFilePath();
|
|
227
|
+
const imports = sourceFile
|
|
228
|
+
.getLiteralsReferencingOtherSourceFiles()
|
|
229
|
+
.map((i) => i.getLiteralValue());
|
|
230
|
+
for (const i of imports) {
|
|
231
|
+
const dependents = dependentsMap.get(i) ?? new Set();
|
|
232
|
+
dependents.add(importer);
|
|
233
|
+
dependentsMap.set(i, dependents);
|
|
234
|
+
}
|
|
235
|
+
};
|
|
187
236
|
const virtualModulePlugin = {
|
|
188
237
|
name: PLUGIN_NAME,
|
|
238
|
+
resolvedOptions,
|
|
189
239
|
config(config, env) {
|
|
240
|
+
isSsr = env.ssrBuild ?? false;
|
|
190
241
|
// Configure Build steps when running with vavite
|
|
191
242
|
if (env.mode === 'multibuild') {
|
|
192
243
|
const clientBuild = {
|
|
193
244
|
outDir: resolvedClientOutputDirectory,
|
|
194
245
|
rollupOptions: {
|
|
195
|
-
input: buildClientInput(
|
|
246
|
+
input: buildClientInput(resolvedOptions.htmlFiles),
|
|
196
247
|
},
|
|
197
248
|
};
|
|
198
249
|
const serverBuild = {
|
|
199
250
|
ssr: true,
|
|
200
251
|
outDir: resolvedServerOutputDirectory,
|
|
201
252
|
rollupOptions: {
|
|
202
|
-
input:
|
|
253
|
+
input: {
|
|
254
|
+
index: resolvedServerFilePath,
|
|
255
|
+
},
|
|
203
256
|
},
|
|
204
257
|
};
|
|
205
258
|
config.buildSteps = [
|
|
@@ -220,6 +273,21 @@ export default function makePlugin({ sourceDirectory: directory, tsConfig, serve
|
|
|
220
273
|
return;
|
|
221
274
|
}
|
|
222
275
|
},
|
|
276
|
+
configResolved(resolvedConfig) {
|
|
277
|
+
logger = resolvedConfig.logger;
|
|
278
|
+
const input = resolvedConfig.build.rollupOptions.input;
|
|
279
|
+
if (!input)
|
|
280
|
+
return;
|
|
281
|
+
if (typeof input === 'string') {
|
|
282
|
+
manifest.entryFiles.push(parseEntryFile(sourceDirectory, input));
|
|
283
|
+
}
|
|
284
|
+
else if (Array.isArray(input)) {
|
|
285
|
+
manifest.entryFiles.push(...input.map((i) => parseEntryFile(sourceDirectory, i)));
|
|
286
|
+
}
|
|
287
|
+
else {
|
|
288
|
+
manifest.entryFiles.push(...Object.values(input).map((i) => parseEntryFile(sourceDirectory, i)));
|
|
289
|
+
}
|
|
290
|
+
},
|
|
223
291
|
configureServer(server) {
|
|
224
292
|
devServer = server;
|
|
225
293
|
server.watcher.on('all', (event, path) => {
|
|
@@ -237,13 +305,16 @@ export default function makePlugin({ sourceDirectory: directory, tsConfig, serve
|
|
|
237
305
|
async watchChange(path, { event }) {
|
|
238
306
|
handleFileChange(path, event);
|
|
239
307
|
},
|
|
240
|
-
closeBundle() {
|
|
308
|
+
async closeBundle() {
|
|
241
309
|
if (project) {
|
|
242
310
|
const diagnostics = project.getPreEmitDiagnostics();
|
|
243
311
|
if (diagnostics.length > 0) {
|
|
244
312
|
this.error(project.formatDiagnosticsWithColorAndContext(diagnostics));
|
|
245
313
|
}
|
|
246
314
|
}
|
|
315
|
+
if (Object.keys(manifest).length > 0) {
|
|
316
|
+
writeFileSync(resolve(isSsr ? resolvedServerOutputDirectory : resolvedClientOutputDirectory, 'typed-manifest.json'), JSON.stringify(manifest, null, 2) + EOL);
|
|
317
|
+
}
|
|
247
318
|
},
|
|
248
319
|
async resolveId(id, importer) {
|
|
249
320
|
if (!importer) {
|
|
@@ -252,16 +323,22 @@ export default function makePlugin({ sourceDirectory: directory, tsConfig, serve
|
|
|
252
323
|
if (id.startsWith(RUNTIME_VIRTUAL_ENTRYPOINT_PREFIX) ||
|
|
253
324
|
id.startsWith(BROWSER_VIRTUAL_ENTRYPOINT_PREFIX)) {
|
|
254
325
|
setupProject();
|
|
255
|
-
|
|
326
|
+
const virtualId = VIRTUAL_ID_PREFIX + (await buildRuntimeModule(importer, id));
|
|
327
|
+
return virtualId;
|
|
256
328
|
}
|
|
257
329
|
if (id.startsWith(HTML_VIRTUAL_ENTRYPOINT_PREFIX)) {
|
|
258
330
|
setupProject();
|
|
259
|
-
|
|
331
|
+
const virtualId = VIRTUAL_ID_PREFIX + (await buildHtmlModule(importer, id));
|
|
332
|
+
return virtualId;
|
|
260
333
|
}
|
|
261
334
|
if (id.startsWith(API_VIRTUAL_ENTRYPOINT_PREFIX) ||
|
|
262
335
|
id.startsWith(EXPRESS_VIRTUAL_ENTRYPOINT_PREFIX)) {
|
|
263
336
|
setupProject();
|
|
264
|
-
|
|
337
|
+
const virtualId = VIRTUAL_ID_PREFIX + (await buildApiModule(importer, id));
|
|
338
|
+
return virtualId;
|
|
339
|
+
}
|
|
340
|
+
if (id === TYPED_CONFIG_IMPORT) {
|
|
341
|
+
return VIRTUAL_ID_PREFIX + TYPED_CONFIG_IMPORT;
|
|
265
342
|
}
|
|
266
343
|
importer = importer.replace(VIRTUAL_ID_PREFIX, '');
|
|
267
344
|
// Virtual modules have problems with resolving relative paths due to not
|
|
@@ -274,21 +351,21 @@ export default function makePlugin({ sourceDirectory: directory, tsConfig, serve
|
|
|
274
351
|
id = id.replace(VIRTUAL_ID_PREFIX, '');
|
|
275
352
|
const sourceFile = filePathToModule.get(id) ?? project?.getSourceFile(id);
|
|
276
353
|
if (sourceFile) {
|
|
277
|
-
logDiagnostics(project, sourceFile, sourceDirectory, id);
|
|
278
|
-
const text = sourceFile.getFullText();
|
|
279
|
-
const output = ts.transpileModule(text, {
|
|
280
|
-
fileName: id,
|
|
281
|
-
compilerOptions: transpilerCompilerOptions(),
|
|
282
|
-
transformers,
|
|
283
|
-
});
|
|
354
|
+
logDiagnostics(project, sourceFile, sourceDirectory, id, logger);
|
|
284
355
|
return {
|
|
285
|
-
code:
|
|
286
|
-
|
|
356
|
+
code: sourceFile.getFullText(),
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
if (id === TYPED_CONFIG_IMPORT) {
|
|
360
|
+
return {
|
|
361
|
+
code: Object.entries(resolvedOptions)
|
|
362
|
+
.map(([key, value]) => `export const ${key} = ${JSON.stringify(value)}`)
|
|
363
|
+
.join(EOL),
|
|
287
364
|
};
|
|
288
365
|
}
|
|
289
366
|
},
|
|
290
367
|
transform(text, id) {
|
|
291
|
-
if (/.
|
|
368
|
+
if (/.[c|m]?tsx?$/.test(id)) {
|
|
292
369
|
const output = ts.transpileModule(text, {
|
|
293
370
|
fileName: id,
|
|
294
371
|
compilerOptions: transpilerCompilerOptions(),
|
|
@@ -304,20 +381,18 @@ export default function makePlugin({ sourceDirectory: directory, tsConfig, serve
|
|
|
304
381
|
plugins.push(virtualModulePlugin);
|
|
305
382
|
return plugins;
|
|
306
383
|
}
|
|
307
|
-
function logDiagnostics(project, sourceFile, sourceDirectory, filePath) {
|
|
384
|
+
function logDiagnostics(project, sourceFile, sourceDirectory, filePath, logger) {
|
|
308
385
|
const diagnostics = sourceFile.getPreEmitDiagnostics();
|
|
309
386
|
const relativeFilePath = relative(sourceDirectory, filePath);
|
|
310
387
|
if (diagnostics.length > 0) {
|
|
311
|
-
info(
|
|
312
|
-
info(
|
|
313
|
-
|
|
314
|
-
else {
|
|
315
|
-
info(`${relativeFilePath} module successfuly typed-checked.`);
|
|
388
|
+
info(`Type-checking errors found at ${relativeFilePath}`, logger);
|
|
389
|
+
info(`Source:` + EOL + sourceFile.getFullText(), logger);
|
|
390
|
+
info(project.formatDiagnosticsWithColorAndContext(diagnostics), logger);
|
|
316
391
|
}
|
|
317
392
|
}
|
|
318
393
|
function findRelativeFile(importer, id) {
|
|
319
394
|
const dir = dirname(importer);
|
|
320
|
-
const tsPath = resolve(dir, id.replace(/.js(x)?$/, '
|
|
395
|
+
const tsPath = resolve(dir, id.replace(/.([c|m])?js(x)?$/, '.$1ts$2'));
|
|
321
396
|
if (existsSync(tsPath)) {
|
|
322
397
|
return tsPath;
|
|
323
398
|
}
|
|
@@ -347,12 +422,7 @@ function findHtmlFiles(directory, htmlFileGlobs) {
|
|
|
347
422
|
});
|
|
348
423
|
}
|
|
349
424
|
function buildClientInput(htmlFilePaths) {
|
|
350
|
-
|
|
351
|
-
for (const htmlFilePath of htmlFilePaths) {
|
|
352
|
-
const htmlFile = basename(htmlFilePath, '.html');
|
|
353
|
-
input[htmlFile] = htmlFilePath;
|
|
354
|
-
}
|
|
355
|
-
return input;
|
|
425
|
+
return htmlFilePaths.reduce((acc, htmlFilePath) => ({ ...acc, [basename(htmlFilePath, '.html')]: htmlFilePath }), {});
|
|
356
426
|
}
|
|
357
427
|
function getRelativePath(from, to) {
|
|
358
428
|
const path = relative(from, to);
|
|
@@ -361,8 +431,62 @@ function getRelativePath(from, to) {
|
|
|
361
431
|
}
|
|
362
432
|
return path;
|
|
363
433
|
}
|
|
364
|
-
function info(message) {
|
|
365
|
-
|
|
366
|
-
|
|
434
|
+
function info(message, logger) {
|
|
435
|
+
if (logger) {
|
|
436
|
+
logger.info(`[${PLUGIN_NAME}]: ${message}`);
|
|
437
|
+
}
|
|
438
|
+
else {
|
|
439
|
+
console.info(`[${PLUGIN_NAME}]:`, `${message}`);
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
function parseEntryFile(sourceDirectory, filePath) {
|
|
443
|
+
if (filePath.endsWith('.html')) {
|
|
444
|
+
return parseHtmlEntryFile(sourceDirectory, filePath);
|
|
445
|
+
}
|
|
446
|
+
return parseTsEntryFile(sourceDirectory, filePath);
|
|
447
|
+
}
|
|
448
|
+
function parseHtmlEntryFile(sourceDirectory, filePath) {
|
|
449
|
+
const content = readFileSync(filePath, 'utf-8').toString();
|
|
450
|
+
return {
|
|
451
|
+
type: 'html',
|
|
452
|
+
filePath: relative(sourceDirectory, filePath),
|
|
453
|
+
imports: parseHtmlImports(sourceDirectory, content),
|
|
454
|
+
basePath: parseBasePath(content),
|
|
455
|
+
};
|
|
456
|
+
}
|
|
457
|
+
function parseHtmlImports(sourceDirectory, content) {
|
|
458
|
+
const imports = [];
|
|
459
|
+
const matches = content.match(/<script[^>]*src="([^"]*)"[^>]*>/g);
|
|
460
|
+
if (matches) {
|
|
461
|
+
for (const match of matches) {
|
|
462
|
+
// If script is not type=module then skip
|
|
463
|
+
if (!match.includes('type="module"')) {
|
|
464
|
+
continue;
|
|
465
|
+
}
|
|
466
|
+
const src = match.match(/src="([^"]*)"/)?.[1];
|
|
467
|
+
if (src) {
|
|
468
|
+
const fullPath = join(sourceDirectory, src);
|
|
469
|
+
const relativePath = relative(sourceDirectory, fullPath);
|
|
470
|
+
imports.push(relativePath);
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
return imports;
|
|
475
|
+
}
|
|
476
|
+
function parseBasePath(content) {
|
|
477
|
+
const baseTag = content.match(/<base[^>]*>/)?.[0];
|
|
478
|
+
if (baseTag) {
|
|
479
|
+
const href = baseTag.match(/href="([^"]*)"/)?.[1];
|
|
480
|
+
if (href) {
|
|
481
|
+
return href;
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
return '/';
|
|
485
|
+
}
|
|
486
|
+
function parseTsEntryFile(sourceDirectory, filePath) {
|
|
487
|
+
return {
|
|
488
|
+
type: 'ts',
|
|
489
|
+
filePath: relative(sourceDirectory, filePath),
|
|
490
|
+
};
|
|
367
491
|
}
|
|
368
492
|
//# sourceMappingURL=vite-plugin.js.map
|