@freshpack/webpack 0.0.0-stage → 1.0.0
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/LICENSE +20 -0
- package/buildCacheUtil.ts +11 -0
- package/denoEnv.ts +78 -0
- package/fresh.ts +391 -0
- package/mod.ts +7 -0
- package/package.json +19 -3
- package/prefresh-forked/index.ts +114 -0
- package/prefresh-forked/loader/index.ts +10 -0
- package/prefresh-forked/loader/runtime.js +70 -0
- package/prefresh-forked/utils/Runtime.ts +79 -0
- package/prefresh-forked/utils/constants.ts +35 -0
- package/prefresh-forked/utils/createTemplate.ts +76 -0
- package/prefresh-forked/utils/injectEntry.ts +28 -0
- package/prefresh-forked/utils/prefresh.ts +59 -0
- package/quasiquote.ts +44 -0
- package/rawBytesLoader.ts +17 -0
- package/rawImports.ts +85 -0
- package/requireHook.ts +22 -0
- package/resolve.ts +588 -0
- package/transpileLoader.ts +59 -0
- package/unmap.ts +154 -0
- package/util.ts +58 -0
- package/viteComment.ts +41 -0
- package/README.md +0 -3
package/unmap.ts
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import type * as Webpack from "webpack";
|
|
2
|
+
import { assert } from "@std/assert";
|
|
3
|
+
|
|
4
|
+
interface UnmapCompilation extends Webpack.Compilation {
|
|
5
|
+
unmapping: Record<string, string>;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export function assertUnmapCompilation(
|
|
9
|
+
compilation: Webpack.Compilation,
|
|
10
|
+
): asserts compilation is UnmapCompilation {
|
|
11
|
+
assert(
|
|
12
|
+
"unmapping" in compilation,
|
|
13
|
+
"missing fresh data in compilation, did you add WebpackFreshEntries plugin?",
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
export class UnmapPlugin {
|
|
17
|
+
apply(compiler: Webpack.Compiler) {
|
|
18
|
+
const mappings = new Map<
|
|
19
|
+
string,
|
|
20
|
+
{ name: string; module: Webpack.Module; loc: Webpack.Dependency["loc"] }
|
|
21
|
+
>();
|
|
22
|
+
const nameToRequest = new Map<string, string>();
|
|
23
|
+
const nameToAsset = new Map<string, string>();
|
|
24
|
+
|
|
25
|
+
compiler.hooks.compilation.tap(
|
|
26
|
+
UnmapPlugin.name,
|
|
27
|
+
(compilation, { normalModuleFactory }) => {
|
|
28
|
+
normalModuleFactory.hooks.parser.for("javascript/auto").tap(
|
|
29
|
+
UnmapPlugin.name,
|
|
30
|
+
(parser) => {
|
|
31
|
+
parser.hooks.call.for("unmap").tap(UnmapPlugin.name, (expr) => {
|
|
32
|
+
const error = (msg: string) => {
|
|
33
|
+
const err = new compiler.webpack.WebpackError(msg);
|
|
34
|
+
err.loc = expr.loc!;
|
|
35
|
+
parser.state.module.addError(
|
|
36
|
+
err,
|
|
37
|
+
);
|
|
38
|
+
};
|
|
39
|
+
if (expr.arguments.length !== 2) {
|
|
40
|
+
return error(`unmap requires (name, new URL()) arguments`);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const nameArg = parser.evaluateExpression(expr.arguments[0]);
|
|
44
|
+
if (!nameArg.isString()) {
|
|
45
|
+
return error(
|
|
46
|
+
`first argument for unmap should be a static string`,
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const urlExpr = expr.arguments[1];
|
|
51
|
+
if (
|
|
52
|
+
urlExpr.type !== "NewExpression" ||
|
|
53
|
+
urlExpr.callee.type !== "Identifier" ||
|
|
54
|
+
urlExpr.callee.name !== "URL"
|
|
55
|
+
) {
|
|
56
|
+
return error(
|
|
57
|
+
`second argument for unmap should be new URL() expression`,
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
const key = `${parser.state.module.identifier()}:${
|
|
61
|
+
urlExpr.range![0]
|
|
62
|
+
}`;
|
|
63
|
+
mappings.set(key, {
|
|
64
|
+
name: nameArg.string!,
|
|
65
|
+
module: parser.state.module,
|
|
66
|
+
loc: expr.loc!,
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
},
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
compilation.hooks.afterOptimizeModules.tap(
|
|
73
|
+
UnmapPlugin.name,
|
|
74
|
+
() => {
|
|
75
|
+
for (const module of compilation.modules) {
|
|
76
|
+
if (!module.dependencies) return;
|
|
77
|
+
|
|
78
|
+
for (const dep of module.dependencies) {
|
|
79
|
+
if (dep.constructor.name !== "URLDependency") continue;
|
|
80
|
+
const dep_ = dep as unknown as { outerRange: [number, number] };
|
|
81
|
+
|
|
82
|
+
const key = `${module.identifier()}:${dep_.outerRange[0]}`;
|
|
83
|
+
const name = mappings.get(key);
|
|
84
|
+
|
|
85
|
+
if (!name) continue;
|
|
86
|
+
|
|
87
|
+
const error = (msg: string) => {
|
|
88
|
+
const err = new compiler.webpack.WebpackError(
|
|
89
|
+
msg,
|
|
90
|
+
);
|
|
91
|
+
err.module = name.module;
|
|
92
|
+
err.loc = name.loc;
|
|
93
|
+
compilation.errors.push(err);
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
const connection = compilation.moduleGraph.getConnection(
|
|
97
|
+
dep,
|
|
98
|
+
);
|
|
99
|
+
if (!connection || !connection.module) {
|
|
100
|
+
error("unable to find connection for url dependency");
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
const mod = connection.module as {
|
|
104
|
+
resource?: string;
|
|
105
|
+
userRequest?: string;
|
|
106
|
+
};
|
|
107
|
+
const request = mod.resource ?? mod.userRequest;
|
|
108
|
+
if (!request) {
|
|
109
|
+
error(`unable to resolve unmap request`);
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
{
|
|
114
|
+
const oldV = nameToRequest.get(name.name);
|
|
115
|
+
if (oldV !== undefined && oldV !== request) {
|
|
116
|
+
error(
|
|
117
|
+
`ResolutionConflict: unmap(${
|
|
118
|
+
JSON.stringify(name.name)
|
|
119
|
+
}, ${
|
|
120
|
+
JSON.stringify(request)
|
|
121
|
+
}) was previously resolved to ${oldV}, use a different unmapping`,
|
|
122
|
+
);
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
nameToRequest.set(name.name, request);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
);
|
|
131
|
+
compilation.hooks.processAssets.tap(UnmapPlugin.name, (assets) => {
|
|
132
|
+
for (const [name, request] of nameToRequest.entries()) {
|
|
133
|
+
for (const [assetName, _asset] of Object.entries(assets)) {
|
|
134
|
+
const info = compilation.assetsInfo.get(assetName);
|
|
135
|
+
if (
|
|
136
|
+
info?.sourceFilename && request.endsWith(info.sourceFilename)
|
|
137
|
+
) {
|
|
138
|
+
nameToAsset.set(name, assetName);
|
|
139
|
+
break;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
const unmapping = Object.fromEntries(nameToAsset);
|
|
144
|
+
const json = JSON.stringify(unmapping);
|
|
145
|
+
compilation.emitAsset(
|
|
146
|
+
"mapped.json",
|
|
147
|
+
new compiler.webpack.sources.RawSource(json),
|
|
148
|
+
);
|
|
149
|
+
(compilation as UnmapCompilation).unmapping = unmapping;
|
|
150
|
+
});
|
|
151
|
+
},
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
}
|
package/util.ts
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { assert } from "@std/assert";
|
|
2
|
+
|
|
3
|
+
export function stripFileUrl(u: string) {
|
|
4
|
+
assert(u.startsWith("file://"), `not a file url: ${u}`);
|
|
5
|
+
return u.slice(7);
|
|
6
|
+
}
|
|
7
|
+
export function resolveNpm(u: string) {
|
|
8
|
+
const path = import.meta.resolve(`npm:${u}`);
|
|
9
|
+
return stripFileUrl(path);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function manglePath(path: string) {
|
|
13
|
+
const tokens = path.replaceAll(/\\/g, "/").split(/([^a-zA-Z0-9_]+)/).filter((
|
|
14
|
+
s,
|
|
15
|
+
) => s);
|
|
16
|
+
|
|
17
|
+
return "_" + tokens.map((s) => {
|
|
18
|
+
if (/^[a-zA-Z0-9_]+$/.test(s)) {
|
|
19
|
+
return s.length + s;
|
|
20
|
+
}
|
|
21
|
+
return s.split("").map((c) => "_" + c.charCodeAt(0).toString(16)).join("");
|
|
22
|
+
}).join("");
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function assertAbsolutePath(path: string) {
|
|
26
|
+
// TODO: Windows
|
|
27
|
+
assert(path.startsWith("/"), `path is not absolute: ${path}`);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function assertDirURL(path: URL) {
|
|
31
|
+
const stat = Deno.statSync(path);
|
|
32
|
+
assert(stat.isDirectory, `path is not a directory: ${path}`);
|
|
33
|
+
}
|
|
34
|
+
export function ensureModPath(path: string) {
|
|
35
|
+
if (path.endsWith("/fakeMod.ts")) return path;
|
|
36
|
+
if (!path.startsWith("https://")) {
|
|
37
|
+
const stat = Deno.statSync(path);
|
|
38
|
+
if (stat.isFile) return path;
|
|
39
|
+
assert(stat.isDirectory, `path is not a directory: ${path}`);
|
|
40
|
+
}
|
|
41
|
+
if (path.endsWith(".ts") || path.endsWith(".js") || path.endsWith(".mjs")) {
|
|
42
|
+
return path;
|
|
43
|
+
}
|
|
44
|
+
if (!path.endsWith("/")) path += "/fakeMod.ts";
|
|
45
|
+
return path;
|
|
46
|
+
}
|
|
47
|
+
export function ensureFilePath(path: string) {
|
|
48
|
+
const stat = Deno.statSync(path);
|
|
49
|
+
assert(stat.isFile, `path is not a file: ${path}`);
|
|
50
|
+
assert(!path.endsWith("/"), "file paths shouldn't end with /");
|
|
51
|
+
return path;
|
|
52
|
+
}
|
|
53
|
+
export function assertResolved(path: string) {
|
|
54
|
+
assert(path.startsWith("https://"), `path is not https: ${path}`);
|
|
55
|
+
}
|
|
56
|
+
export function ensureFileUrl(path: string) {
|
|
57
|
+
return new URL(`file://${ensureFilePath(path)}`);
|
|
58
|
+
}
|
package/viteComment.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type Webpack from "webpack";
|
|
2
|
+
import type { Compiler } from "webpack";
|
|
3
|
+
|
|
4
|
+
type JavascriptParser = Webpack.javascript.JavascriptParser;
|
|
5
|
+
|
|
6
|
+
const NAME = "ViteIgnorePlugin";
|
|
7
|
+
|
|
8
|
+
const PARSER_TYPES = [
|
|
9
|
+
"javascript/auto",
|
|
10
|
+
"javascript/dynamic",
|
|
11
|
+
"javascript/esm",
|
|
12
|
+
] as const;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* ViteIgnorePlugin skips parsing of `import` calls that contain `@vite-inore` in inline comment, similarly
|
|
16
|
+
* to webpack built-in `webpackIgnore: true` annotation
|
|
17
|
+
*/
|
|
18
|
+
export class ViteIgnorePlugin {
|
|
19
|
+
apply(compiler: Compiler) {
|
|
20
|
+
compiler.hooks.compilation.tap(
|
|
21
|
+
NAME,
|
|
22
|
+
(_compilation, { normalModuleFactory }) => {
|
|
23
|
+
const handler = (parser: JavascriptParser) => {
|
|
24
|
+
parser.hooks.importCall.tap({ name: NAME, stage: -10 }, (expr) => {
|
|
25
|
+
const ignored = parser.getComments([
|
|
26
|
+
expr.range![0],
|
|
27
|
+
expr.source.range![1],
|
|
28
|
+
]).some((comment) =>
|
|
29
|
+
comment.type === "Block" &&
|
|
30
|
+
comment.value.includes("@vite-ignore")
|
|
31
|
+
);
|
|
32
|
+
if (ignored) return false;
|
|
33
|
+
});
|
|
34
|
+
};
|
|
35
|
+
for (const type of PARSER_TYPES) {
|
|
36
|
+
normalModuleFactory.hooks.parser.for(type).tap(NAME, handler);
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
}
|
package/README.md
DELETED