@freshpack/webpack 1.0.1 → 1.0.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.
- package/CHANGELOG.md +6 -0
- package/denoEnv.js +40 -52
- package/denoEnv.js.map +1 -0
- package/fresh.js +223 -246
- package/fresh.js.map +1 -0
- package/importMetaResolve.d.ts +4 -0
- package/importMetaResolve.js +50 -0
- package/importMetaResolve.js.map +1 -0
- package/mod.d.ts +1 -0
- package/mod.js +2 -0
- package/mod.js.map +1 -0
- package/package.json +23 -3
- package/prefresh-forked/index.js +50 -48
- package/prefresh-forked/index.js.map +1 -0
- package/prefresh-forked/loader/index.js +2 -1
- package/prefresh-forked/loader/index.js.map +1 -0
- package/prefresh-forked/utils/Runtime.js +11 -36
- package/prefresh-forked/utils/Runtime.js.map +1 -0
- package/prefresh-forked/utils/constants.js +5 -16
- package/prefresh-forked/utils/constants.js.map +1 -0
- package/prefresh-forked/utils/prefresh.js +30 -37
- package/prefresh-forked/utils/prefresh.js.map +1 -0
- package/quasiquote.js +28 -26
- package/quasiquote.js.map +1 -0
- package/rawBytesLoader.js +6 -8
- package/rawBytesLoader.js.map +1 -0
- package/rawImports.js +37 -37
- package/rawImports.js.map +1 -0
- package/requireHook.js +9 -8
- package/requireHook.js.map +1 -0
- package/resolve.js +357 -367
- package/resolve.js.map +1 -0
- package/transpileLoader.js +34 -26
- package/transpileLoader.js.map +1 -0
- package/unmap.js +88 -90
- package/unmap.js.map +1 -0
- package/util.js +32 -34
- package/util.js.map +1 -0
- package/viteComment.js +20 -22
- package/viteComment.js.map +1 -0
package/CHANGELOG.md
CHANGED
package/denoEnv.js
CHANGED
|
@@ -1,61 +1,49 @@
|
|
|
1
1
|
import Webpack from "webpack";
|
|
2
2
|
const NAME = "DenoEnvPlugin";
|
|
3
|
-
const PARSER_TYPES = [
|
|
4
|
-
"javascript/auto",
|
|
5
|
-
"javascript/dynamic",
|
|
6
|
-
"javascript/esm",
|
|
7
|
-
];
|
|
3
|
+
const PARSER_TYPES = ["javascript/auto", "javascript/dynamic", "javascript/esm"];
|
|
8
4
|
/**
|
|
9
5
|
* DenoEnvPlugin replaces calls to `Deno.env.get` with a constant expression of environment variable name.
|
|
10
6
|
*/
|
|
11
7
|
export class DenoEnvPlugin {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
8
|
+
#allowed;
|
|
9
|
+
constructor(opts = {}) {
|
|
10
|
+
this.#allowed = [...(opts.allowedEnv ?? []), /^FRESH_PUBLIC_/, "NODE_ENV", "DENO_DEPLOYMENT_ID", "GITHUB_SHA", "CI_COMMIT_SHA", "CI"];
|
|
11
|
+
}
|
|
12
|
+
#isAllowed(name) {
|
|
13
|
+
return this.#allowed.some(allowed => allowed instanceof RegExp ? allowed.test(name) : allowed === name);
|
|
14
|
+
}
|
|
15
|
+
#value(name, compiler) {
|
|
16
|
+
if (name === "NODE_ENV") {
|
|
17
|
+
const mode = compiler.options.mode;
|
|
18
|
+
if (mode !== undefined && mode !== "none") return mode;
|
|
23
19
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
if (!this.#isAllowed(name)) {
|
|
46
|
-
throw new Error(`Env var is not allowed in bundling: ${name}`);
|
|
47
|
-
}
|
|
48
|
-
const value = this.#value(name, compiler);
|
|
49
|
-
const dep = new Webpack.dependencies.ConstDependency(value === undefined ? "undefined" : JSON.stringify(value), expr.range);
|
|
50
|
-
if (expr.loc)
|
|
51
|
-
dep.loc = expr.loc;
|
|
52
|
-
parser.state.module.addPresentationalDependency(dep);
|
|
53
|
-
return true;
|
|
54
|
-
});
|
|
55
|
-
};
|
|
56
|
-
for (const type of PARSER_TYPES) {
|
|
57
|
-
normalModuleFactory.hooks.parser.for(type).tap(NAME, handler);
|
|
58
|
-
}
|
|
20
|
+
return Deno.env.get(name);
|
|
21
|
+
}
|
|
22
|
+
apply(compiler) {
|
|
23
|
+
compiler.hooks.compilation.tap(NAME, (_compilation, {
|
|
24
|
+
normalModuleFactory
|
|
25
|
+
}) => {
|
|
26
|
+
const handler = parser => {
|
|
27
|
+
parser.hooks.call.for("Deno.env.get").tap(NAME, expr => {
|
|
28
|
+
const [arg] = expr.arguments;
|
|
29
|
+
if (expr.arguments.length !== 1 || arg.type !== "Literal" || typeof arg.value !== "string") {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
const name = arg.value;
|
|
33
|
+
if (!this.#isAllowed(name)) {
|
|
34
|
+
throw new Error(`Env var is not allowed in bundling: ${name}`);
|
|
35
|
+
}
|
|
36
|
+
const value = this.#value(name, compiler);
|
|
37
|
+
const dep = new Webpack.dependencies.ConstDependency(value === undefined ? "undefined" : JSON.stringify(value), expr.range);
|
|
38
|
+
if (expr.loc) dep.loc = expr.loc;
|
|
39
|
+
parser.state.module.addPresentationalDependency(dep);
|
|
40
|
+
return true;
|
|
59
41
|
});
|
|
60
|
-
|
|
42
|
+
};
|
|
43
|
+
for (const type of PARSER_TYPES) {
|
|
44
|
+
normalModuleFactory.hooks.parser.for(type).tap(NAME, handler);
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
}
|
|
61
48
|
}
|
|
49
|
+
//# sourceMappingURL=denoEnv.js.map
|
package/denoEnv.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":[],"sources":["denoEnv.ts"],"sourcesContent":["import Webpack, { type Compiler } from \"webpack\";\n\ntype JavascriptParser = Webpack.javascript.JavascriptParser;\n\nconst NAME = \"DenoEnvPlugin\";\n\nconst PARSER_TYPES = [\n \"javascript/auto\",\n \"javascript/dynamic\",\n \"javascript/esm\",\n] as const;\n\nexport type DenoEnvOptions = {\n allowedEnv?: (string | RegExp)[];\n};\n\n/**\n * DenoEnvPlugin replaces calls to `Deno.env.get` with a constant expression of environment variable name.\n */\nexport class DenoEnvPlugin {\n #allowed: (string | RegExp)[];\n constructor(opts: DenoEnvOptions = {}) {\n this.#allowed = [\n ...opts.allowedEnv ?? [],\n /^FRESH_PUBLIC_/,\n \"NODE_ENV\",\n \"DENO_DEPLOYMENT_ID\",\n \"GITHUB_SHA\",\n \"CI_COMMIT_SHA\",\n \"CI\",\n ];\n }\n #isAllowed(name: string) {\n return this.#allowed.some((allowed) =>\n allowed instanceof RegExp ? allowed.test(name) : allowed === name\n );\n }\n #value(name: string, compiler: Compiler) {\n if (name === \"NODE_ENV\") {\n const mode = compiler.options.mode;\n if (mode !== undefined && mode !== \"none\") return mode;\n }\n return Deno.env.get(name);\n }\n apply(compiler: Compiler) {\n compiler.hooks.compilation.tap(\n NAME,\n (_compilation, { normalModuleFactory }) => {\n const handler = (parser: JavascriptParser) => {\n parser.hooks.call.for(\"Deno.env.get\").tap(NAME, (expr) => {\n const [arg] = expr.arguments;\n if (\n expr.arguments.length !== 1 || arg.type !== \"Literal\" ||\n typeof arg.value !== \"string\"\n ) {\n return;\n }\n const name = arg.value;\n if (!this.#isAllowed(name)) {\n throw new Error(`Env var is not allowed in bundling: ${name}`);\n }\n const value = this.#value(name, compiler);\n const dep = new Webpack.dependencies.ConstDependency(\n value === undefined ? \"undefined\" : JSON.stringify(value),\n expr.range!,\n );\n if (expr.loc) dep.loc = expr.loc;\n parser.state.module.addPresentationalDependency(dep);\n return true;\n });\n };\n for (const type of PARSER_TYPES) {\n normalModuleFactory.hooks.parser.for(type).tap(NAME, handler);\n }\n },\n );\n }\n}\n"],"mappings":"AAAA,OAAO,OAAO,MAAyB,SAAS;AAIhD,MAAM,IAAI,GAAG,eAAe;AAE5B,MAAM,YAAY,GAAG,CACnB,iBAAiB,EACjB,oBAAoB,EACpB,gBAAgB,CACR;AAMV;AACA;AACA;AACA,OAAO,MAAM,aAAa,CAAC;EACzB,CAAC,OAAO;EACR,WAAW,CAAC,IAAoB,GAAG,CAAC,CAAC,EAAE;IACrC,IAAI,CAAC,CAAC,OAAO,GAAG,CACd,IAAG,IAAI,CAAC,UAAU,IAAI,EAAE,GACxB,gBAAgB,EAChB,UAAU,EACV,oBAAoB,EACpB,YAAY,EACZ,eAAe,EACf,IAAI,CACL;EACH;EACA,CAAC,SAAS,CAAC,IAAY,EAAE;IACvB,OAAO,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,CAAE,OAAO,IAChC,OAAO,YAAY,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,OAAO,KAAK,IAC/D,CAAC;EACH;EACA,CAAC,KAAK,CAAC,IAAY,EAAE,QAAkB,EAAE;IACvC,IAAI,IAAI,KAAK,UAAU,EAAE;MACvB,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI;MAClC,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,MAAM,EAAE,OAAO,IAAI;IACxD;IACA,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC;EAC3B;EACA,KAAK,CAAC,QAAkB,EAAE;IACxB,QAAQ,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,CAC5B,IAAI,EACJ,CAAC,YAAY,EAAE;MAAE;IAAoB,CAAC,KAAK;MACzC,MAAM,OAAO,GAAI,MAAwB,IAAK;QAC5C,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,GAAG,CAAC,IAAI,EAAG,IAAI,IAAK;UACxD,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,SAAS;UAC5B,IACE,IAAI,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,IAAI,GAAG,CAAC,IAAI,KAAK,SAAS,IACrD,OAAO,GAAG,CAAC,KAAK,KAAK,QAAQ,EAC7B;YACA;UACF;UACA,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK;UACtB,IAAI,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE;YAC1B,MAAM,IAAI,KAAK,CAAC,uCAAuC,IAAI,EAAE,CAAC;UAChE;UACA,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC;UACzC,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC,YAAY,CAAC,eAAe,CAClD,KAAK,KAAK,SAAS,GAAG,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EACzD,IAAI,CAAC,KACP,CAAC;UACD,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG;UAChC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,2BAA2B,CAAC,GAAG,CAAC;UACpD,OAAO,IAAI;QACb,CAAC,CAAC;MACJ,CAAC;MACD,KAAK,MAAM,IAAI,IAAI,YAAY,EAAE;QAC/B,mBAAmB,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC;MAC/D;IACF,CACF,CAAC;EACH;AACF","ignoreList":[]}
|
package/fresh.js
CHANGED
|
@@ -1,268 +1,245 @@
|
|
|
1
|
-
|
|
2
|
-
if (typeof path === "string" && /^\.\.?\//.test(path)) {
|
|
3
|
-
return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
|
|
4
|
-
return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
|
|
5
|
-
});
|
|
6
|
-
}
|
|
7
|
-
return path;
|
|
8
|
-
};
|
|
9
|
-
import { crawlFsItem, } from "@freshpack/core/internal-dev";
|
|
1
|
+
import { crawlFsItem } from "@freshpack/core/internal-dev";
|
|
10
2
|
import Webpack from "webpack";
|
|
11
|
-
import { assertAbsolutePath, assertDirURL, manglePath, stripFileUrl
|
|
3
|
+
import { assertAbsolutePath, assertDirURL, manglePath, stripFileUrl } from "./util.js";
|
|
12
4
|
import { assert } from "@std/assert";
|
|
13
5
|
import { IslandPreparer, ProdBuildCache } from "@freshpack/core/internal";
|
|
14
|
-
import { extname as extnamePosix, join as joinPosix, relative as relativePosix
|
|
6
|
+
import { extname as extnamePosix, join as joinPosix, relative as relativePosix } from "@std/path/posix";
|
|
15
7
|
import { contentType as getStdContentType } from "@std/media-types/content-type";
|
|
16
8
|
import { encodeHex } from "@std/encoding";
|
|
17
9
|
import { UnmapPlugin } from "./unmap.js";
|
|
18
10
|
import { DenoEnvPlugin } from "./denoEnv.js";
|
|
19
11
|
import { ViteIgnorePlugin } from "./viteComment.js";
|
|
20
12
|
import { RawImportsPlugin } from "./rawImports.js";
|
|
13
|
+
import { ImportMetaResolveAssetPlugin } from "./importMetaResolve.js";
|
|
21
14
|
import { js, toJsRaw } from "./quasiquote.js";
|
|
22
15
|
export function assertFreshCompilation(compilation) {
|
|
23
|
-
|
|
24
|
-
"freshRoot" in compilation, "missing fresh data in compilation, did you add WebpackFreshEntries plugin?");
|
|
16
|
+
assert("freshRoutes" in compilation && "freshIslands" in compilation && "freshRoot" in compilation, "missing fresh data in compilation, did you add WebpackFreshEntries plugin?");
|
|
25
17
|
}
|
|
26
18
|
function getMainChunkName(basePath, e) {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
19
|
+
const entryChunk = e.getEntrypointChunk();
|
|
20
|
+
const files = [...entryChunk.files].map(v => joinPosix(basePath, v));
|
|
21
|
+
return files[0];
|
|
30
22
|
}
|
|
31
23
|
function getChunkFiles(basePath, e) {
|
|
32
|
-
|
|
24
|
+
return e.getFiles().map(v => joinPosix(basePath, v));
|
|
33
25
|
}
|
|
34
26
|
export class FreshPlugin {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
if (!importHelper) {
|
|
50
|
-
console.warn("[FreshPlugin]", "importHelper is not set, jsr release of @freshpack/webpack doesn't work without it: https://github.com/denoland/deno/discussions/26266#discussioncomment-12198284");
|
|
51
|
-
this.importHelper = (path) => import(__rewriteRelativeImportExtension(path));
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
pathRelativeToBase(path) {
|
|
55
|
-
return relativePosix(this.baseUrl.pathname, path);
|
|
27
|
+
/**
|
|
28
|
+
* @param baseUrl Location of fresh project root directory, you can specify it as `new URL('.', import.meta.url)` in build.ts
|
|
29
|
+
* @param importHelper JSR dynamic file import workaround: You should pass `(path) => import(path)` here, where the function
|
|
30
|
+
* should be defined anywhere outside of JSR published package. See this for details: https://github.com/denoland/deno/discussions/26266
|
|
31
|
+
* This function will always be called with absolute path.
|
|
32
|
+
*/
|
|
33
|
+
constructor(baseUrl, importHelper, options = {}) {
|
|
34
|
+
this.baseUrl = baseUrl;
|
|
35
|
+
this.importHelper = importHelper;
|
|
36
|
+
this.options = options;
|
|
37
|
+
assertDirURL(this.baseUrl);
|
|
38
|
+
if (!importHelper) {
|
|
39
|
+
console.warn("[FreshPlugin]", "importHelper is not set, jsr release of @freshpack/webpack doesn't work without it: https://github.com/denoland/deno/discussions/26266#discussioncomment-12198284");
|
|
40
|
+
this.importHelper = path => import(path);
|
|
56
41
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
42
|
+
}
|
|
43
|
+
pathRelativeToBase(path) {
|
|
44
|
+
return relativePosix(this.baseUrl.pathname, path);
|
|
45
|
+
}
|
|
46
|
+
#dist;
|
|
47
|
+
pathRelativeToDist(path) {
|
|
48
|
+
assert(this.#dist, "dist path was not determined yet");
|
|
49
|
+
return relativePosix(this.#dist, path);
|
|
50
|
+
}
|
|
51
|
+
apply(compiler) {
|
|
52
|
+
{
|
|
53
|
+
// HACK: Webpack does not export EntryDependency, and it is impossible to use EntryPlugin, as
|
|
54
|
+
// it wants to modify make stage, yet we have already reached this stage when we want to use
|
|
55
|
+
// this plugin.
|
|
56
|
+
//
|
|
57
|
+
// Solvable by creating custom dependency plugin, or requiring user to manually specify
|
|
58
|
+
// at least one entry... Or by registering EntryDependency manually as done here.
|
|
59
|
+
const EntryDependency = Webpack.EntryPlugin.createDependency(`dummy`, {}).constructor;
|
|
60
|
+
compiler.hooks.compilation.tap(FreshPlugin.name, (compilation, {
|
|
61
|
+
normalModuleFactory
|
|
62
|
+
}) => {
|
|
63
|
+
compilation.dependencyFactories.set(EntryDependency, normalModuleFactory);
|
|
64
|
+
});
|
|
61
65
|
}
|
|
62
|
-
apply(compiler)
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
66
|
+
new UnmapPlugin().apply(compiler);
|
|
67
|
+
new DenoEnvPlugin(this.options.env).apply(compiler);
|
|
68
|
+
new ViteIgnorePlugin().apply(compiler);
|
|
69
|
+
new RawImportsPlugin(this.options.rawImports).apply(compiler);
|
|
70
|
+
new ImportMetaResolveAssetPlugin().apply(compiler);
|
|
71
|
+
// Some @std and other packages detect deno on presence of Deno global, dead-code-elimnate this stuff
|
|
72
|
+
new Webpack.DefinePlugin({
|
|
73
|
+
Deno: "undefined"
|
|
74
|
+
}).apply(compiler);
|
|
75
|
+
compiler.hooks.make.tapPromise(FreshPlugin.name, async _compilation => {
|
|
76
|
+
const compilation = _compilation;
|
|
77
|
+
this.#dist = compilation.outputOptions.path;
|
|
78
|
+
const compilationId = Date.now().toString(36);
|
|
79
|
+
|
|
80
|
+
// Ensure hot chunks are resolved from correct path, they can't contain compilationId in name
|
|
81
|
+
compilation.outputOptions.publicPath = "/";
|
|
82
|
+
{
|
|
83
|
+
// Chunks are content-addressed in prod, and have readable names using standard fresh cache pruning in dev
|
|
84
|
+
if (compiler.options.mode === "production") {
|
|
85
|
+
compilation.outputOptions.filename = `_fresh/js/c/[contenthash].mjs`;
|
|
86
|
+
compilation.outputOptions.chunkFilename = `_fresh/js/c/[contenthash].mjs`;
|
|
87
|
+
compilation.outputOptions.workerChunkFilename = `_fresh/js/c/[contenthash].mjs`;
|
|
88
|
+
} else {
|
|
89
|
+
compilation.outputOptions.filename = `_fresh/js/${compilationId}/[id].mjs`;
|
|
90
|
+
compilation.outputOptions.chunkFilename = `_fresh/js/${compilationId}/[id].mjs`;
|
|
91
|
+
compilation.outputOptions.workerChunkFilename = `_fresh/js/${compilationId}/[id].mjs`;
|
|
74
92
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
compiler.
|
|
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
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
for (const _asset of compilation.getAssets()) {
|
|
159
|
-
const asset = compilation.getAsset(_asset.name);
|
|
160
|
-
const file_ = assets[asset.name]
|
|
161
|
-
.buffer();
|
|
162
|
-
const file = file_;
|
|
163
|
-
const hash = await crypto.subtle.digest("SHA-1", file.buffer);
|
|
164
|
-
const ext = extnamePosix(asset.name);
|
|
165
|
-
const contentType = getStdContentType(ext) ?? "text/plain";
|
|
166
|
-
const name = "/" + asset.name;
|
|
167
|
-
staticFiles.set(name, {
|
|
168
|
-
name,
|
|
169
|
-
filePath: asset.name,
|
|
170
|
-
contentType,
|
|
171
|
-
hash: encodeHex(hash),
|
|
172
|
-
data: file,
|
|
173
|
-
size: file.length,
|
|
174
|
-
});
|
|
175
|
-
staticFilesOut.set(name, toJsRaw({
|
|
176
|
-
name,
|
|
177
|
-
filePath: js `new URL(${asset.name}, import.meta.url).pathname`,
|
|
178
|
-
hash: encodeHex(hash),
|
|
179
|
-
contentType,
|
|
180
|
-
}));
|
|
181
|
-
}
|
|
182
|
-
cacheOut.push(js `const staticFiles=${staticFilesOut}`);
|
|
183
|
-
cacheOut.push(js `export default new ProdBuildCache(${compilation.freshRoot}, ${({
|
|
184
|
-
version: compilationId,
|
|
185
|
-
clientEntry,
|
|
186
|
-
entryAssets: toJsRaw(clientEntryAssets),
|
|
187
|
-
islands: js `islands`,
|
|
188
|
-
fsRoutes: js `fsRoutes`,
|
|
189
|
-
staticFiles: js `staticFiles`,
|
|
190
|
-
})})`);
|
|
191
|
-
// Here ProdBuildCache is being used as MemoryBuildCache from fresh
|
|
192
|
-
const cache = new ProdBuildCache(compilation.freshRoot, {
|
|
193
|
-
version: compilationId,
|
|
194
|
-
clientEntry,
|
|
195
|
-
fsRoutes,
|
|
196
|
-
staticFiles,
|
|
197
|
-
islands,
|
|
198
|
-
entryAssets: clientEntryAssets,
|
|
199
|
-
});
|
|
200
|
-
cache.readFile = (pathname) => {
|
|
201
|
-
const st = staticFiles.get(pathname);
|
|
202
|
-
if (!st) {
|
|
203
|
-
return Promise.resolve(null);
|
|
204
|
-
}
|
|
205
|
-
return Promise.resolve({
|
|
206
|
-
contentType: st.contentType,
|
|
207
|
-
hash: st.hash,
|
|
208
|
-
readable: new ReadableStream({
|
|
209
|
-
start(v) {
|
|
210
|
-
v.enqueue(st.data);
|
|
211
|
-
v.close();
|
|
212
|
-
},
|
|
213
|
-
}),
|
|
214
|
-
size: st.size,
|
|
215
|
-
close() { },
|
|
216
|
-
});
|
|
217
|
-
};
|
|
218
|
-
compilation.prodBuildCache = cache;
|
|
219
|
-
compilation.emitAsset("./cache.mjs", new compiler.webpack.sources.RawSource(cacheOut.map((v) => v._jsRaw).join("\n")));
|
|
220
|
-
});
|
|
221
|
-
const item = await crawlFsItem({
|
|
222
|
-
islandDir: stripFileUrl(new URL("islands", this.baseUrl).href),
|
|
223
|
-
routeDir: stripFileUrl(new URL("routes", this.baseUrl).href),
|
|
224
|
-
ignore: [],
|
|
225
|
-
});
|
|
226
|
-
compilation.freshRoutes = item.routes;
|
|
227
|
-
compilation.freshIslands = [];
|
|
228
|
-
compilation.freshRoot = this.pathRelativeToBase(".");
|
|
229
|
-
const addEntryPromises = [];
|
|
230
|
-
let isId = 0;
|
|
231
|
-
for (const island of item.islands) {
|
|
232
|
-
const name = compiler.options.mode === "production"
|
|
233
|
-
? `is${isId++}`
|
|
234
|
-
: manglePath(island);
|
|
235
|
-
compilation.freshIslands.push({ entryName: name, filePath: island });
|
|
236
|
-
addEntryPromises.push(new Promise((res, rej) => compilation.addEntry("", Webpack.EntryPlugin.createDependency(`${island}`, {
|
|
237
|
-
name,
|
|
238
|
-
}), {
|
|
239
|
-
name,
|
|
240
|
-
library: {
|
|
241
|
-
type: "module",
|
|
242
|
-
},
|
|
243
|
-
}, (err) => {
|
|
244
|
-
if (err)
|
|
245
|
-
return rej(err);
|
|
246
|
-
res();
|
|
247
|
-
})));
|
|
248
|
-
}
|
|
249
|
-
{
|
|
250
|
-
const name = "client-entry";
|
|
251
|
-
const file = stripFileUrl(new URL("./client.ts", this.baseUrl).href);
|
|
252
|
-
addEntryPromises.push(new Promise((res, rej) => compilation.addEntry("", Webpack.EntryPlugin.createDependency(file, {
|
|
253
|
-
name,
|
|
254
|
-
}), {
|
|
255
|
-
name,
|
|
256
|
-
library: {
|
|
257
|
-
type: "module",
|
|
258
|
-
},
|
|
259
|
-
}, (e) => {
|
|
260
|
-
if (e)
|
|
261
|
-
return rej(e);
|
|
262
|
-
res();
|
|
263
|
-
})));
|
|
264
|
-
}
|
|
265
|
-
await Promise.all(addEntryPromises);
|
|
93
|
+
// Assets are always content-addressed
|
|
94
|
+
compilation.outputOptions.assetModuleFilename = `_fresh/js/c/[hash][ext][query]`;
|
|
95
|
+
compilation.outputOptions.webassemblyModuleFilename = `_fresh/js/c/[hash].wasm`;
|
|
96
|
+
}
|
|
97
|
+
compilation.hooks.processAssets.tapPromise({
|
|
98
|
+
name: FreshPlugin.name,
|
|
99
|
+
stage: compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_SUMMARIZE
|
|
100
|
+
}, async assets => {
|
|
101
|
+
compilation.getAssets();
|
|
102
|
+
const cacheOut = [js`import{IslandPreparer,ProdBuildCache}from"@freshpack/core/internal"`, js`const islands=new Map()`, js`const islandPreparer=new IslandPreparer()`];
|
|
103
|
+
const staticFiles = new Map();
|
|
104
|
+
const islands = new Map();
|
|
105
|
+
const islandPreparer = new IslandPreparer();
|
|
106
|
+
for (const island of compilation.freshIslands) {
|
|
107
|
+
const entrypoint = compilation.entrypoints.get(island.entryName);
|
|
108
|
+
assert(entrypoint, `unable to find island entrypoint: ${island.entryName}`);
|
|
109
|
+
const file = getMainChunkName(`/`, entrypoint);
|
|
110
|
+
islandPreparer.prepare(islands, await this.importHelper(island.filePath), file, island.entryName, []);
|
|
111
|
+
const importPath = this.pathRelativeToDist(island.filePath);
|
|
112
|
+
cacheOut.push(js`islandPreparer.prepare(islands,await import(${importPath}),${file},${island.entryName},[])`);
|
|
113
|
+
}
|
|
114
|
+
const fsRoutesOut = [];
|
|
115
|
+
const fsRoutes = await Promise.all(compilation.freshRoutes.map(async v => {
|
|
116
|
+
const importPath = this.pathRelativeToDist(v.filePath);
|
|
117
|
+
fsRoutesOut.push(toJsRaw({
|
|
118
|
+
id: v.id,
|
|
119
|
+
mod: v.lazy ? js`()=>import(${importPath})` : js`await import(${importPath})`,
|
|
120
|
+
type: v.type,
|
|
121
|
+
pattern: v.pattern,
|
|
122
|
+
routePattern: v.routePattern
|
|
123
|
+
}));
|
|
124
|
+
assertAbsolutePath(v.filePath);
|
|
125
|
+
return {
|
|
126
|
+
...v,
|
|
127
|
+
mod: v.lazy ? () => this.importHelper(v.filePath) : await this.importHelper(v.filePath)
|
|
128
|
+
};
|
|
129
|
+
}));
|
|
130
|
+
cacheOut.push(js`const fsRoutes=${fsRoutesOut}`);
|
|
131
|
+
const clientEntrypoint = compilation.entrypoints.get("client-entry");
|
|
132
|
+
assert(clientEntrypoint, `unable to find client entrypoint`);
|
|
133
|
+
const clientEntry = getMainChunkName(`/`, clientEntrypoint);
|
|
134
|
+
const clientEntryAssets = getChunkFiles(`/`, clientEntrypoint);
|
|
135
|
+
const staticFilesOut = new Map();
|
|
136
|
+
for (const _asset of compilation.getAssets()) {
|
|
137
|
+
const asset = compilation.getAsset(_asset.name);
|
|
138
|
+
const file_ = assets[asset.name].buffer();
|
|
139
|
+
const file = file_;
|
|
140
|
+
const hash = await crypto.subtle.digest("SHA-1", file.buffer);
|
|
141
|
+
const ext = extnamePosix(asset.name);
|
|
142
|
+
const contentType = getStdContentType(ext) ?? "text/plain";
|
|
143
|
+
const name = "/" + asset.name;
|
|
144
|
+
staticFiles.set(name, {
|
|
145
|
+
name,
|
|
146
|
+
filePath: asset.name,
|
|
147
|
+
contentType,
|
|
148
|
+
hash: encodeHex(hash),
|
|
149
|
+
data: file,
|
|
150
|
+
size: file.length
|
|
151
|
+
});
|
|
152
|
+
staticFilesOut.set(name, toJsRaw({
|
|
153
|
+
name,
|
|
154
|
+
filePath: js`new URL(${asset.name}, import.meta.url).pathname`,
|
|
155
|
+
hash: encodeHex(hash),
|
|
156
|
+
contentType
|
|
157
|
+
}));
|
|
158
|
+
}
|
|
159
|
+
cacheOut.push(js`const staticFiles=${staticFilesOut}`);
|
|
160
|
+
cacheOut.push(js`export default new ProdBuildCache(${compilation.freshRoot}, ${{
|
|
161
|
+
version: compilationId,
|
|
162
|
+
clientEntry,
|
|
163
|
+
entryAssets: toJsRaw(clientEntryAssets),
|
|
164
|
+
islands: js`islands`,
|
|
165
|
+
fsRoutes: js`fsRoutes`,
|
|
166
|
+
staticFiles: js`staticFiles`
|
|
167
|
+
}})`);
|
|
168
|
+
// Here ProdBuildCache is being used as MemoryBuildCache from fresh
|
|
169
|
+
const cache = new ProdBuildCache(compilation.freshRoot, {
|
|
170
|
+
version: compilationId,
|
|
171
|
+
clientEntry,
|
|
172
|
+
fsRoutes,
|
|
173
|
+
staticFiles,
|
|
174
|
+
islands,
|
|
175
|
+
entryAssets: clientEntryAssets
|
|
266
176
|
});
|
|
267
|
-
|
|
177
|
+
cache.readFile = pathname => {
|
|
178
|
+
const st = staticFiles.get(pathname);
|
|
179
|
+
if (!st) {
|
|
180
|
+
return Promise.resolve(null);
|
|
181
|
+
}
|
|
182
|
+
return Promise.resolve({
|
|
183
|
+
contentType: st.contentType,
|
|
184
|
+
hash: st.hash,
|
|
185
|
+
readable: new ReadableStream({
|
|
186
|
+
start(v) {
|
|
187
|
+
v.enqueue(st.data);
|
|
188
|
+
v.close();
|
|
189
|
+
}
|
|
190
|
+
}),
|
|
191
|
+
size: st.size,
|
|
192
|
+
close() {}
|
|
193
|
+
});
|
|
194
|
+
};
|
|
195
|
+
compilation.prodBuildCache = cache;
|
|
196
|
+
compilation.emitAsset("./cache.mjs", new compiler.webpack.sources.RawSource(cacheOut.map(v => v._jsRaw).join("\n")));
|
|
197
|
+
});
|
|
198
|
+
const item = await crawlFsItem({
|
|
199
|
+
islandDir: stripFileUrl(new URL("islands", this.baseUrl).href),
|
|
200
|
+
routeDir: stripFileUrl(new URL("routes", this.baseUrl).href),
|
|
201
|
+
ignore: []
|
|
202
|
+
});
|
|
203
|
+
compilation.freshRoutes = item.routes;
|
|
204
|
+
compilation.freshIslands = [];
|
|
205
|
+
compilation.freshRoot = this.pathRelativeToBase(".");
|
|
206
|
+
const addEntryPromises = [];
|
|
207
|
+
let isId = 0;
|
|
208
|
+
for (const island of item.islands) {
|
|
209
|
+
const name = compiler.options.mode === "production" ? `is${isId++}` : manglePath(island);
|
|
210
|
+
compilation.freshIslands.push({
|
|
211
|
+
entryName: name,
|
|
212
|
+
filePath: island
|
|
213
|
+
});
|
|
214
|
+
addEntryPromises.push(new Promise((res, rej) => compilation.addEntry("", Webpack.EntryPlugin.createDependency(`${island}`, {
|
|
215
|
+
name
|
|
216
|
+
}), {
|
|
217
|
+
name,
|
|
218
|
+
library: {
|
|
219
|
+
type: "module"
|
|
220
|
+
}
|
|
221
|
+
}, err => {
|
|
222
|
+
if (err) return rej(err);
|
|
223
|
+
res();
|
|
224
|
+
})));
|
|
225
|
+
}
|
|
226
|
+
{
|
|
227
|
+
const name = "client-entry";
|
|
228
|
+
const file = stripFileUrl(new URL("./client.ts", this.baseUrl).href);
|
|
229
|
+
addEntryPromises.push(new Promise((res, rej) => compilation.addEntry("", Webpack.EntryPlugin.createDependency(file, {
|
|
230
|
+
name
|
|
231
|
+
}), {
|
|
232
|
+
name,
|
|
233
|
+
library: {
|
|
234
|
+
type: "module"
|
|
235
|
+
}
|
|
236
|
+
}, e => {
|
|
237
|
+
if (e) return rej(e);
|
|
238
|
+
res();
|
|
239
|
+
})));
|
|
240
|
+
}
|
|
241
|
+
await Promise.all(addEntryPromises);
|
|
242
|
+
});
|
|
243
|
+
}
|
|
268
244
|
}
|
|
245
|
+
//# sourceMappingURL=fresh.js.map
|