@package-verse/esmpack 1.0.8 → 1.0.10
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/empty.js +1 -0
- package/init.js +0 -12
- package/package.json +2 -1
- package/src/pack/FilePacker.ts +8 -2
- package/src/parser/babel.ts +48 -6
- package/src/serve/send/sendJS.ts +8 -47
package/empty.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
// this is just an empty module placeholder for CSS modules
|
package/init.js
CHANGED
|
@@ -1,12 +1,5 @@
|
|
|
1
1
|
const ESMPack = window.ESMPack ||= {};
|
|
2
|
-
ESMPack.installed ||= new Set();
|
|
3
|
-
|
|
4
|
-
ESMPack.markAsInstalled ||= (urls) => Array.isArray(urls)
|
|
5
|
-
? urls.forEach(url => ESMPack.installed.add(url))
|
|
6
|
-
: ESMPack.installed.add(urls);
|
|
7
|
-
|
|
8
2
|
ESMPack.installStyleSheet ||= (url) => {
|
|
9
|
-
|
|
10
3
|
const installCss = (url) => {
|
|
11
4
|
|
|
12
5
|
const link = document.createElement("link");
|
|
@@ -17,11 +10,6 @@ ESMPack.installStyleSheet ||= (url) => {
|
|
|
17
10
|
? "afterbegin"
|
|
18
11
|
: "beforeend", link);
|
|
19
12
|
};
|
|
20
|
-
|
|
21
|
-
if (ESMPack.installed.has(url)) {
|
|
22
|
-
return;
|
|
23
|
-
}
|
|
24
|
-
ESMPack.installed.add(url);
|
|
25
13
|
if(document.readyState === "complete") {
|
|
26
14
|
installCss(url);
|
|
27
15
|
} else {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@package-verse/esmpack",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.10",
|
|
4
4
|
"description": "ESM Pack Packer and Web Server with PostCSS and ESM Loader",
|
|
5
5
|
"homepage": "https://github.com/package-verse/esmpack#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
"postversion": "git push --follow-tags"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
|
+
"@types/babel__core": "^7.20.5",
|
|
24
25
|
"@types/node": "^25.5.0",
|
|
25
26
|
"@types/ws": "^8.18.1",
|
|
26
27
|
"cssnano": "^7.0.6",
|
package/src/pack/FilePacker.ts
CHANGED
|
@@ -8,13 +8,19 @@
|
|
|
8
8
|
* For App.js following packed scripts will be generated.
|
|
9
9
|
* 1. App.pack.js
|
|
10
10
|
* Push Import Maps script tag
|
|
11
|
+
* Add import map for non js modules as well, and for this
|
|
12
|
+
* every nested dependency must be inspected.
|
|
13
|
+
* Json module should load json via hashed-dependency
|
|
14
|
+
* Image module should load path of module via hashed-dependency
|
|
15
|
+
* CSS module should inject full path to the browser
|
|
16
|
+
* Push empty module for CSS
|
|
11
17
|
* Imports all nested dependencies of App.js that should not contain fully qualified path
|
|
12
18
|
* Import dynamically loaded modules as well
|
|
13
|
-
* Loads App.pack.global.css
|
|
14
|
-
* Loads App.pack.local.css
|
|
15
19
|
* Imports App.js dynamically so CSS can be ready before hosting the User interface
|
|
16
20
|
* 2. App.pack.global.css
|
|
17
21
|
* 3. App.pack.local.css
|
|
22
|
+
* 4. App.pack.{hash-of-absolute-module-path}.js <-- this will be a dependency for non js module such as image or json etc.
|
|
23
|
+
* This will load an absolute path via resolve
|
|
18
24
|
*/
|
|
19
25
|
export default class FilePacker {
|
|
20
26
|
|
package/src/parser/babel.ts
CHANGED
|
@@ -1,18 +1,59 @@
|
|
|
1
|
-
import { transformSync } from "@babel/core";
|
|
1
|
+
import { NodePath, TransformOptions, transformSync } from "@babel/core";
|
|
2
2
|
import { readFileSync } from "fs";
|
|
3
3
|
import { ProcessOptions } from "../ProcessArgs.js";
|
|
4
4
|
import { parse } from "path";
|
|
5
|
+
import { CallExpression, ImportDeclaration, ImportExpression } from "@babel/types";
|
|
6
|
+
|
|
5
7
|
|
|
6
8
|
export class Babel {
|
|
7
9
|
|
|
8
|
-
static transform({
|
|
10
|
+
static transform({
|
|
11
|
+
file,
|
|
12
|
+
resolve,
|
|
13
|
+
dynamicResolve
|
|
14
|
+
}: {
|
|
15
|
+
file: string,
|
|
16
|
+
resolve: (url: string, sourceFile: string) => string,
|
|
17
|
+
dynamicResolve?: (url: string, sourceFile: string) => string
|
|
18
|
+
}) {
|
|
9
19
|
|
|
10
20
|
const { base: name } = parse(file);
|
|
11
21
|
|
|
12
|
-
|
|
22
|
+
function CallExpression (node: NodePath<CallExpression>) {
|
|
23
|
+
if (node.node.callee.type !== "Import") {
|
|
24
|
+
return node;
|
|
25
|
+
}
|
|
26
|
+
const sourceFile = (node.hub as any)?.file?.inputMap?.sourcemap?.sources?.[0];
|
|
27
|
+
const [ arg1 ] = node.node.arguments;
|
|
28
|
+
if (!arg1) {
|
|
29
|
+
return node;
|
|
30
|
+
}
|
|
31
|
+
if (arg1.type !== "StringLiteral") {
|
|
32
|
+
return node;
|
|
33
|
+
}
|
|
34
|
+
const v = dynamicResolve(arg1.value, sourceFile);
|
|
35
|
+
if (v !== arg1.value) {
|
|
36
|
+
arg1.value = v || arg1.value;
|
|
37
|
+
}
|
|
38
|
+
return node;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
function ImportExpression(node: NodePath<ImportExpression>) {
|
|
42
|
+
const sourceFile = (node.hub as any)?.file?.inputMap?.sourcemap?.sources?.[0];
|
|
43
|
+
const { source } = node.node;
|
|
44
|
+
if (source.type !== "StringLiteral") {
|
|
45
|
+
return node;
|
|
46
|
+
}
|
|
47
|
+
const v = dynamicResolve(source.value, sourceFile);
|
|
48
|
+
if (v !== source.value) {
|
|
49
|
+
source.value = v || source.value;
|
|
50
|
+
}
|
|
51
|
+
return node;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const presets: TransformOptions = {
|
|
13
55
|
sourceType: "module",
|
|
14
56
|
sourceMaps: true,
|
|
15
|
-
inputSourceMap: true,
|
|
16
57
|
caller: {
|
|
17
58
|
name,
|
|
18
59
|
supportsDynamicImport: true,
|
|
@@ -28,17 +69,18 @@ export class Babel {
|
|
|
28
69
|
return {
|
|
29
70
|
name: "Import Transformer",
|
|
30
71
|
visitor: {
|
|
31
|
-
ImportDeclaration(node) {
|
|
72
|
+
ImportDeclaration(node: NodePath<ImportDeclaration>) {
|
|
32
73
|
const e = node.node;
|
|
33
74
|
let source = e.source?.value;
|
|
34
75
|
if (!source) {
|
|
35
76
|
return node;
|
|
36
77
|
}
|
|
37
|
-
const sourceFile = node.hub?.file?.inputMap?.sourcemap?.sources?.[0];
|
|
78
|
+
const sourceFile = (node.hub as any)?.file?.inputMap?.sourcemap?.sources?.[0];
|
|
38
79
|
source = resolve(source, sourceFile);
|
|
39
80
|
e.source.value = source;
|
|
40
81
|
return node;
|
|
41
82
|
},
|
|
83
|
+
... (dynamicResolve ? { CallExpression, ImportExpression } : {}),
|
|
42
84
|
}
|
|
43
85
|
};
|
|
44
86
|
}
|
package/src/serve/send/sendJS.ts
CHANGED
|
@@ -6,8 +6,11 @@ import { existsSync, readFileSync } from "node:fs";
|
|
|
6
6
|
|
|
7
7
|
export default function sendJS(filePath: string, req: IncomingMessage, res: ServerResponse) {
|
|
8
8
|
|
|
9
|
+
const resolve = (url: string, sourceFile: string) => {
|
|
9
10
|
|
|
10
|
-
|
|
11
|
+
if(!sourceFile) {
|
|
12
|
+
sourceFile = filePath;
|
|
13
|
+
}
|
|
11
14
|
|
|
12
15
|
const originalUrl = url;
|
|
13
16
|
|
|
@@ -58,7 +61,6 @@ export default function sendJS(filePath: string, req: IncomingMessage, res: Serv
|
|
|
58
61
|
// is it referenced from source...
|
|
59
62
|
const dir = path.dirname(filePath);
|
|
60
63
|
const absoluteSourcePath = path.resolve( dir, path.dirname(sourceFile));
|
|
61
|
-
console.log(`Absolute Path is ${absoluteSourcePath}`);
|
|
62
64
|
const referencedAbsolutePath = path.join(absoluteSourcePath, url);
|
|
63
65
|
if (existsSync(referencedAbsolutePath)) {
|
|
64
66
|
const relative = path.relative(dir, referencedAbsolutePath).replaceAll("\\", "/");
|
|
@@ -69,56 +71,15 @@ export default function sendJS(filePath: string, req: IncomingMessage, res: Serv
|
|
|
69
71
|
}
|
|
70
72
|
return originalUrl;
|
|
71
73
|
|
|
72
|
-
}
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
let text = Babel.transform({ file: filePath, resolve, dynamicResolve: resolve});
|
|
73
78
|
|
|
74
79
|
const { base } = parse(filePath);
|
|
75
80
|
|
|
76
81
|
text += `\n//# sourceMappingURL=${base}.map`;
|
|
77
82
|
|
|
78
|
-
// let text = readFileSync(path, "utf-8");
|
|
79
|
-
|
|
80
|
-
// // change references....
|
|
81
|
-
// // text = text.replace(/from\s*\"([^\.][^\"]+)\"/gm, `from "/node_modules/$1"`);
|
|
82
|
-
|
|
83
|
-
// // remap CSS
|
|
84
|
-
// text = RegExpExtra.replaceAll(text, /from\s*\"([^\"]+)\"/gm, (
|
|
85
|
-
// { text, match }
|
|
86
|
-
// ) => {
|
|
87
|
-
// if (text) {
|
|
88
|
-
// return text;
|
|
89
|
-
// }
|
|
90
|
-
// const [matched, g] = match;
|
|
91
|
-
// if (g.endsWith(".css")) {
|
|
92
|
-
// // we need to find source...
|
|
93
|
-
// return `from "/node_modules/${g}.js"`;
|
|
94
|
-
// }
|
|
95
|
-
// if (g.startsWith(".")) {
|
|
96
|
-
// return matched;
|
|
97
|
-
// }
|
|
98
|
-
// return `from "/node_modules/${g}"`;
|
|
99
|
-
// });
|
|
100
|
-
|
|
101
|
-
// text = RegExpExtra.replaceAll(text, /import\s*\"([^\"]+)\"/gm, (
|
|
102
|
-
// { text, match }
|
|
103
|
-
// ) => {
|
|
104
|
-
// if (text) {
|
|
105
|
-
// return text;
|
|
106
|
-
// }
|
|
107
|
-
// const [matched, g] = match;
|
|
108
|
-
// if (g.endsWith(".css")) {
|
|
109
|
-
// // we need to find source...
|
|
110
|
-
// let cssPath = g;
|
|
111
|
-
// if (!cssPath.startsWith(".")) {
|
|
112
|
-
// cssPath = "/node_modules/" + cssPath;
|
|
113
|
-
// }
|
|
114
|
-
// return `import "${cssPath}.js"`;
|
|
115
|
-
// }
|
|
116
|
-
// if (g.startsWith(".")) {
|
|
117
|
-
// return matched;
|
|
118
|
-
// }
|
|
119
|
-
// return `import "/node_modules/${g}"`;
|
|
120
|
-
// });
|
|
121
|
-
|
|
122
83
|
res.writeHead(200, {
|
|
123
84
|
"content-type": "text/javascript",
|
|
124
85
|
"cache-control": "no-cache"
|