deno.land / x / fresh@1.1.1 / src / server / bundle.ts

نووسراو ببینە
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
import { BuildOptions } from "https://deno.land/x/esbuild@v0.14.51/mod.js";import { BUILD_ID } from "./constants.ts";import { denoPlugin, esbuild, toFileUrl } from "./deps.ts";import { Island, Plugin } from "./types.ts";
export interface JSXConfig { jsx: "react" | "react-jsx"; jsxImportSource?: string;}
let esbuildInitialized: boolean | Promise<void> = false;async function ensureEsbuildInitialized() { if (esbuildInitialized === false) { if (Deno.run === undefined) { esbuildInitialized = esbuild.initialize({ wasmURL: "https://deno.land/x/esbuild@v0.14.51/esbuild.wasm", worker: false, }); } else { esbuild.initialize({}); } await esbuildInitialized; esbuildInitialized = true; } else if (esbuildInitialized instanceof Promise) { await esbuildInitialized; }}
const JSX_RUNTIME_MODE = { "react": "transform", "react-jsx": "automatic",} as const;
export class Bundler { #importMapURL: URL; #jsxConfig: JSXConfig; #islands: Island[]; #plugins: Plugin[]; #cache: Map<string, Uint8Array> | Promise<void> | undefined = undefined; #dev: boolean;
constructor( islands: Island[], plugins: Plugin[], importMapURL: URL, jsxConfig: JSXConfig, dev: boolean, ) { this.#islands = islands; this.#plugins = plugins; this.#importMapURL = importMapURL; this.#jsxConfig = jsxConfig; this.#dev = dev; }
async bundle() { const entryPoints: Record<string, string> = { main: this.#dev ? new URL("../../src/runtime/main_dev.ts", import.meta.url).href : new URL("../../src/runtime/main.ts", import.meta.url).href, };
for (const island of this.#islands) { entryPoints[`island-${island.id}`] = island.url; }
for (const plugin of this.#plugins) { for (const [name, url] of Object.entries(plugin.entrypoints ?? {})) { entryPoints[`plugin-${plugin.name}-${name}`] = url; } }
const absWorkingDir = Deno.cwd(); await ensureEsbuildInitialized(); // In dev-mode we skip identifier minification to be able to show proper // component names in Preact DevTools instead of single characters. const minifyOptions: Partial<BuildOptions> = this.#dev ? { minifyIdentifiers: false, minifySyntax: true, minifyWhitespace: true } : { minify: true }; const bundle = await esbuild.build({ bundle: true, define: { __FRSH_BUILD_ID: `"${BUILD_ID}"` }, entryPoints, format: "esm", metafile: true, ...minifyOptions, outdir: ".", // This is requried to ensure the format of the outputFiles path is the same // between windows and linux absWorkingDir, outfile: "", platform: "neutral", plugins: [denoPlugin({ importMapURL: this.#importMapURL })], sourcemap: this.#dev ? "linked" : false, splitting: true, target: ["chrome99", "firefox99", "safari15"], treeShaking: true, write: false, jsx: JSX_RUNTIME_MODE[this.#jsxConfig.jsx], jsxImportSource: this.#jsxConfig.jsxImportSource, }); // const metafileOutputs = bundle.metafile!.outputs;
// for (const path in metafileOutputs) { // const meta = metafileOutputs[path]; // const imports = meta.imports // .filter(({ kind }) => kind === "import-statement") // .map(({ path }) => `/${path}`); // this.#preloads.set(`/${path}`, imports); // }
const cache = new Map<string, Uint8Array>(); const absDirUrlLength = toFileUrl(absWorkingDir).href.length; for (const file of bundle.outputFiles) { cache.set( toFileUrl(file.path).href.substring(absDirUrlLength), file.contents, ); } this.#cache = cache;
return; }
async cache(): Promise<Map<string, Uint8Array>> { if (this.#cache === undefined) { this.#cache = this.bundle(); } if (this.#cache instanceof Promise) { await this.#cache; } return this.#cache as Map<string, Uint8Array>; }
async get(path: string): Promise<Uint8Array | null> { const cache = await this.cache(); return cache.get(path) ?? null; }
// getPreloads(path: string): string[] { // return this.#preloads.get(path) ?? []; // }}
fresh

Version Info

Tagged at
a year ago