@package-verse/esmpack 1.0.9 → 1.0.11

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@package-verse/esmpack",
3
- "version": "1.0.9",
3
+ "version": "1.0.11",
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",
@@ -1,3 +1,6 @@
1
+ import path from "path";
2
+ import { Babel } from "../parser/babel.js";
3
+
1
4
  /**
2
5
  * File Packer must do following tasks...
3
6
  * 1. Visit every JavaScript file
@@ -10,11 +13,12 @@
10
13
  * Push Import Maps script tag
11
14
  * Add import map for non js modules as well, and for this
12
15
  * every nested dependency must be inspected.
16
+ * Json module should load json via hashed-dependency
17
+ * Image module should load path of module via hashed-dependency
18
+ * CSS module should inject full path to the browser
13
19
  * Push empty module for CSS
14
20
  * Imports all nested dependencies of App.js that should not contain fully qualified path
15
21
  * Import dynamically loaded modules as well
16
- * Loads App.pack.global.css
17
- * Loads App.pack.local.css
18
22
  * Imports App.js dynamically so CSS can be ready before hosting the User interface
19
23
  * 2. App.pack.global.css
20
24
  * 3. App.pack.local.css
@@ -23,8 +27,13 @@
23
27
  */
24
28
  export default class FilePacker {
25
29
 
26
- globalCss = [];
27
- localCss = [];
30
+ readonly absoluteSrc: string;
31
+
32
+ readonly cssImports = [];
33
+
34
+ readonly jsonImports = [];
35
+
36
+ readonly pathImports = [];
28
37
 
29
38
  constructor(
30
39
  public readonly root: string,
@@ -32,10 +41,47 @@ export default class FilePacker {
32
41
  public readonly prefix: string
33
42
  ) {
34
43
  // empty
44
+ // let us make src relative to the root if an absolute path was supplied
45
+ if (path.isAbsolute(this.src)) {
46
+ this.src = path.relative(this.root, this.src);
47
+ }
48
+ this.absoluteSrc = path.resolve(this.root, this.src);
35
49
  }
36
50
 
37
51
  async pack() {
38
52
 
53
+ const resolve = (url, sourceFile) => this.resolve(url, sourceFile);
54
+
55
+ // we don't need the code
56
+ await Babel.transformAsync({
57
+ file: path.join(this.root, this.src),
58
+ resolve,
59
+ dynamicResolve: resolve
60
+ });
61
+
62
+
39
63
  }
40
64
 
65
+ resolve(url: string, sourceFile: string) {
66
+
67
+ const moduleUrl = this.moduleUrl(url, sourceFile);
68
+
69
+ if (url.endsWith(".css")) {
70
+ this.cssImports.push(moduleUrl);
71
+ return url;
72
+ }
73
+ if (url.endsWith(".json")) {
74
+ this.jsonImports.push(moduleUrl);
75
+ return url;
76
+ }
77
+
78
+ if (!url.endsWith(".js")) {
79
+
80
+ }
81
+ return url;
82
+ }
83
+
84
+ moduleUrl(url: string, sourceFile: string) {
85
+ return url;
86
+ }
41
87
  }
@@ -1,18 +1,83 @@
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
+ import { readFile } from "fs/promises";
7
+
5
8
 
6
9
  export class Babel {
7
10
 
8
- static transform({ file, resolve }: { file: string, resolve: (url: string, sourceFile: string) => string }) {
11
+ static transform({
12
+ file,
13
+ resolve,
14
+ dynamicResolve
15
+ }: {
16
+ file: string,
17
+ resolve: (url: string, sourceFile: string) => string,
18
+ dynamicResolve?: (url: string, sourceFile: string) => string
19
+ }) {
20
+
21
+ const presets: TransformOptions = Babel.prepareOptions(file, dynamicResolve, resolve);
22
+
23
+ const p = { ... presets, filename: file };
24
+ const code = readFileSync(file, "utf8");
25
+ const result = transformSync(code, p);
26
+ return result.code;
27
+ }
28
+
29
+ static async transformAsync({
30
+ file,
31
+ resolve,
32
+ dynamicResolve
33
+ }) {
34
+ const presets: TransformOptions = Babel.prepareOptions(file, dynamicResolve, resolve);
35
+
36
+ const p = { ... presets, filename: file };
37
+ const code = await readFile(file, "utf8");
38
+ const result = transformSync(code, p);
39
+ return result.code;
9
40
 
41
+ }
42
+
43
+ private static prepareOptions(file: string, dynamicResolve: (url: string, sourceFile: string) => string, resolve: (url: string, sourceFile: string) => string) {
10
44
  const { base: name } = parse(file);
11
45
 
12
- const presets = {
46
+ function CallExpression(node: NodePath<CallExpression>) {
47
+ if (node.node.callee.type !== "Import") {
48
+ return node;
49
+ }
50
+ const sourceFile = (node.hub as any)?.file?.inputMap?.sourcemap?.sources?.[0];
51
+ const [arg1] = node.node.arguments;
52
+ if (!arg1) {
53
+ return node;
54
+ }
55
+ if (arg1.type !== "StringLiteral") {
56
+ return node;
57
+ }
58
+ const v = dynamicResolve(arg1.value, sourceFile);
59
+ if (v !== arg1.value) {
60
+ arg1.value = v || arg1.value;
61
+ }
62
+ return node;
63
+ };
64
+
65
+ function ImportExpression(node: NodePath<ImportExpression>) {
66
+ const sourceFile = (node.hub as any)?.file?.inputMap?.sourcemap?.sources?.[0];
67
+ const { source } = node.node;
68
+ if (source.type !== "StringLiteral") {
69
+ return node;
70
+ }
71
+ const v = dynamicResolve(source.value, sourceFile);
72
+ if (v !== source.value) {
73
+ source.value = v || source.value;
74
+ }
75
+ return node;
76
+ }
77
+
78
+ const presets: TransformOptions = {
13
79
  sourceType: "module",
14
80
  sourceMaps: true,
15
- inputSourceMap: true,
16
81
  caller: {
17
82
  name,
18
83
  supportsDynamicImport: true,
@@ -24,33 +89,28 @@ export class Babel {
24
89
  getModuleId: () => "v",
25
90
  "plugins": [
26
91
  [
27
- function(babel) {
92
+ function (babel) {
28
93
  return {
29
94
  name: "Import Transformer",
30
95
  visitor: {
31
- ImportDeclaration(node) {
96
+ ImportDeclaration(node: NodePath<ImportDeclaration>) {
32
97
  const e = node.node;
33
98
  let source = e.source?.value;
34
99
  if (!source) {
35
100
  return node;
36
101
  }
37
- const sourceFile = node.hub?.file?.inputMap?.sourcemap?.sources?.[0];
102
+ const sourceFile = (node.hub as any)?.file?.inputMap?.sourcemap?.sources?.[0];
38
103
  source = resolve(source, sourceFile);
39
104
  e.source.value = source;
40
105
  return node;
41
106
  },
107
+ ...(dynamicResolve ? { CallExpression, ImportExpression } : {}),
42
108
  }
43
109
  };
44
110
  }
45
111
  ]
46
-
47
112
  ]
48
113
  };
49
-
50
- const p = { ... presets, filename: file };
51
- const code = readFileSync(file, "utf8");
52
- const result = transformSync(code, p);
53
- return result.code;
114
+ return presets;
54
115
  }
55
-
56
116
  }
@@ -1,6 +1,6 @@
1
- import { readFileSync } from "fs";
1
+ import { existsSync, readFileSync } from "fs";
2
2
  import { ProcessOptions } from "../../ProcessArgs.js";
3
- import { join } from "path";
3
+ import path, { join } from "path/posix";
4
4
 
5
5
  const jsonText = readFileSync(join(ProcessOptions.cwd, "package.json"), "utf-8");
6
6
 
@@ -11,7 +11,22 @@ const imports = {
11
11
  };
12
12
 
13
13
  for (const [key] of Object.entries(packageInfo.dependencies)) {
14
- imports[key + "/"] = "/node_modules/" + key + "/";
14
+
15
+ const modulePackageJsonFilePath = join(ProcessOptions.cwd, "node_modules", key , "package.json");
16
+ if (!existsSync(modulePackageJsonFilePath)) {
17
+ continue;
18
+ }
19
+
20
+ const modulePath = "/node_modules/" + key + "/";
21
+
22
+ // read package.json
23
+ const modulePackageJson = JSON.parse(readFileSync(modulePackageJsonFilePath, "utf-8"));
24
+ imports[key] = path.join(modulePath , modulePackageJson.module
25
+ || (modulePackageJson.type === "module"
26
+ ? modulePackageJson.main : "index.js"));
27
+
28
+ imports[key + "/"] = modulePath;
29
+
15
30
  }
16
31
 
17
32
  export const importMap = { imports };
@@ -1,64 +1,42 @@
1
1
  import { IncomingMessage, ServerResponse } from "node:http";
2
2
  import { Babel } from "../../parser/babel.js";
3
3
  import path, { parse } from "node:path";
4
- import { ProcessOptions } from "../../ProcessArgs.js";
5
- import { existsSync, readFileSync } from "node:fs";
4
+ import { existsSync } from "node:fs";
6
5
 
7
6
  export default function sendJS(filePath: string, req: IncomingMessage, res: ServerResponse) {
8
7
 
8
+ const resolve = (url: string, sourceFile: string) => {
9
9
 
10
- let text = Babel.transform({ file: filePath, resolve(url, sourceFile) {
10
+ if (url.endsWith(".js")) {
11
+ return url;
12
+ }
11
13
 
12
- const originalUrl = url;
14
+ if(!sourceFile) {
15
+ sourceFile = filePath;
16
+ }
13
17
 
14
- // check if it has no extension...
15
- const { ext } = parse(url);
16
- if (!ext) {
18
+ if (!url.startsWith(".")) {
17
19
 
18
- // this is case for tslib, reflect_metadata
19
-
20
- // fetch module...
20
+ // we need to include .js for every module relative path
21
21
  const tokens = url.split("/");
22
22
  let packageName = tokens.shift();
23
23
  if (packageName.startsWith("@")) {
24
24
  packageName += "/" + tokens.shift();
25
25
  }
26
26
 
27
- const packageJsonPath = path.resolve(ProcessOptions.cwd, "node_modules", packageName, "package.json");
28
- if (existsSync(packageJsonPath)) {
29
- const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
30
- const start = packageJson["module"] || packageJson["main"];
31
- return url + "/" + start;
32
- }
33
-
34
- }
35
-
36
-
37
- if (!url.startsWith(".")) {
38
-
39
- if (!url.endsWith(".js")) {
40
- url += ".js";
27
+ if (tokens.length) {
28
+ if (!url.endsWith(".js")) {
29
+ return url + ".js";
30
+ }
41
31
  }
42
32
 
43
33
  return url;
44
34
  }
45
35
 
46
- const jsFile = path.resolve(path.dirname(filePath), url);
47
- if (existsSync(jsFile)) {
48
- if (!jsFile.endsWith(".js")) {
49
- url += ".js";
50
- }
51
- return url;
52
- }
53
-
54
- if (url.endsWith(".js")) {
55
- return url;
56
- }
57
36
 
58
37
  // is it referenced from source...
59
38
  const dir = path.dirname(filePath);
60
39
  const absoluteSourcePath = path.resolve( dir, path.dirname(sourceFile));
61
- console.log(`Absolute Path is ${absoluteSourcePath}`);
62
40
  const referencedAbsolutePath = path.join(absoluteSourcePath, url);
63
41
  if (existsSync(referencedAbsolutePath)) {
64
42
  const relative = path.relative(dir, referencedAbsolutePath).replaceAll("\\", "/");
@@ -67,58 +45,18 @@ export default function sendJS(filePath: string, req: IncomingMessage, res: Serv
67
45
  }
68
46
  return relative;
69
47
  }
70
- return originalUrl;
71
48
 
72
- }});
49
+
50
+ return url + ".js";
51
+ };
52
+
53
+
54
+ let text = Babel.transform({ file: filePath, resolve, dynamicResolve: resolve});
73
55
 
74
56
  const { base } = parse(filePath);
75
57
 
76
58
  text += `\n//# sourceMappingURL=${base}.map`;
77
59
 
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
60
  res.writeHead(200, {
123
61
  "content-type": "text/javascript",
124
62
  "cache-control": "no-cache"
@@ -5,7 +5,8 @@ import sendList from "./sendList.js";
5
5
  import sendJS from "./sendJS.js";
6
6
  export default function sendLocalFile(reqPath: string, path: string, req: IncomingMessage, res: ServerResponse) {
7
7
 
8
- if (path.endsWith(".js")) {
8
+ if (path.endsWith(".js")
9
+ && !path.endsWith(".pack.js")) {
9
10
  // send JS
10
11
  return sendJS(path, req, res);
11
12
  }
@@ -1,3 +1,15 @@
1
1
  date-view {
2
2
  color: red;
3
+ display: flex;
4
+ flex-direction: row;
5
+ align-items: center;
6
+ justify-items: center;
7
+ align-content: center;
8
+ justify-content: center;
9
+ gap: 10px;
10
+ }
11
+
12
+ date-view img {
13
+ max-height: 50px;
14
+ max-width: 50px;
3
15
  }