@yao-pkg/pkg 6.13.0 → 6.14.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/README.md CHANGED
@@ -53,7 +53,7 @@ After installing it, run `pkg --help` without arguments to see list of options:
53
53
  – Makes executable for particular target machine
54
54
  $ pkg -t node14-win-arm64 index.js
55
55
  – Makes executables for target machines of your choice
56
- $ pkg -t node16-linux,node18-linux,node18-win index.js
56
+ $ pkg -t node20-linux,node22-linux,node22-win index.js
57
57
  – Bakes '--expose-gc' and '--max-heap-size=34' into executable
58
58
  $ pkg --options "expose-gc,max-heap-size=34" index.js
59
59
  – Consider packageA and packageB to be public
@@ -82,7 +82,7 @@ The entrypoint of your project is a mandatory CLI argument. It may be:
82
82
  `pkg` can generate executables for several target machines at a
83
83
  time. You can specify a comma-separated list of targets via `--targets`
84
84
  option. A canonical target consists of 3 elements, separated by
85
- dashes, for example `node18-macos-x64` or `node14-linux-arm64`:
85
+ dashes, for example `node20-macos-x64` or `node22-linux-arm64`:
86
86
 
87
87
  - **nodeRange** (node8), node10, node12, node14, node16 or latest
88
88
  - **platform** alpine, linux, linuxstatic, win, macos, (freebsd)
@@ -422,6 +422,37 @@ await exec(['app.js', '--target', 'host', '--output', 'app.exe']);
422
422
  // do something with app.exe, run, test, upload, deploy, etc
423
423
  ```
424
424
 
425
+ ## ECMAScript Modules (ESM) Support
426
+
427
+ Starting from version **6.13.0**, pkg has improved support for ECMAScript Modules (ESM). Most ESM features are now automatically transformed to CommonJS during the packaging process.
428
+
429
+ ### Supported ESM Features
430
+
431
+ The following ESM features are now supported and will work in your packaged executables:
432
+
433
+ - **`import` and `export` statements** - Automatically transformed to `require()` and `module.exports`
434
+ - **Top-level `await`** - Wrapped in an async IIFE to work in CommonJS context
435
+ - **Top-level `for await...of`** - Wrapped in an async IIFE to work in CommonJS context
436
+ - **`import.meta.url`** - Polyfilled to provide the file URL of the current module
437
+ - **`import.meta.dirname`** - Polyfilled to provide the directory path (Node.js 20.11+ property)
438
+ - **`import.meta.filename`** - Polyfilled to provide the file path (Node.js 20.11+ property)
439
+
440
+ ### Known Limitations
441
+
442
+ While most ESM features work, there are some limitations to be aware of:
443
+
444
+ 1. **Modules with both top-level await and exports**: Modules that use `export` statements alongside top-level `await` cannot be wrapped in an async IIFE and will not be transformed to bytecode. These modules will be included as source code instead.
445
+
446
+ 2. **`import.meta.main`** and other custom properties: Only the standard `import.meta` properties listed above are polyfilled. Custom properties added by your code or other tools may not work as expected.
447
+
448
+ 3. **Dynamic imports**: `import()` expressions work but may have limitations depending on the module being imported.
449
+
450
+ ### Best Practices
451
+
452
+ - For entry point scripts (the main file you're packaging), feel free to use top-level await
453
+ - For library modules that will be imported by other code, avoid using both exports and top-level await together
454
+ - Test your packaged executable to ensure all ESM features work as expected in your specific use case
455
+
425
456
  ## Use custom Node.js binary
426
457
 
427
458
  In case you want to use custom node binary, you can set `PKG_NODE_PATH` environment variable to the path of the node binary you want to use and `pkg` will use it instead of the default one.
@@ -535,43 +566,45 @@ or
535
566
  Note: make sure not to use --debug flag in production.
536
567
 
537
568
  ### Injecting Windows Executable Metadata After Packaging
538
- Executables created with `pkg` are based on a Node.js binary and, by default,
539
- inherit its embedded metadata such as version number, product name, company
540
- name, icon, and description. This can be misleading or unpolished in
569
+
570
+ Executables created with `pkg` are based on a Node.js binary and, by default,
571
+ inherit its embedded metadata such as version number, product name, company
572
+ name, icon, and description. This can be misleading or unpolished in
541
573
  distributed applications.
542
574
 
543
575
  There are two ways to customize the metadata of the resulting `.exe`:
576
+
544
577
  1. **Use a custom Node.js binary** with your own metadata already embedded.
545
578
  See: [Use Custom Node.js Binary](#use-custom-nodejs-binary)
546
579
 
547
- 2. **Post-process the generated executable** using
548
- [`resedit`](https://www.npmjs.com/package/resedit), a Node.js-compatible
549
- tool for modifying Windows executable resources. This allows injecting
580
+ 2. **Post-process the generated executable** using
581
+ [`resedit`](https://www.npmjs.com/package/resedit), a Node.js-compatible
582
+ tool for modifying Windows executable resources. This allows injecting
550
583
  correct version info, icons, copyright,
551
584
  and more.
552
585
 
553
586
  This section focuses on the second approach: post-processing the packaged
554
- binary using [`resedit`](https://www.npmjs.com/package/resedit).
587
+ binary using [`resedit`](https://www.npmjs.com/package/resedit).
555
588
 
556
589
  > ⚠️ Other tools may corrupt the executable, resulting in runtime errors such as
557
- > `Pkg: Error reading from file.` –
590
+ > `Pkg: Error reading from file.` –
558
591
  > [`resedit`](https://www.npmjs.com/package/resedit) has proven to work reliably
559
592
  > with `pkg`-generated binaries.
560
593
 
561
594
  Below is a working example for post-processing an `.exe` file using the Node.js API of [`resedit`](https://www.npmjs.com/package/resedit):
562
595
 
563
596
  ```ts
564
- import * as ResEdit from "resedit";
565
- import * as fs from "fs";
566
- import * as path from "path";
597
+ import * as ResEdit from 'resedit';
598
+ import * as fs from 'fs';
599
+ import * as path from 'path';
567
600
 
568
601
  // Set your inputs:
569
- const exePath = "dist/my-tool.exe"; // Path to the generated executable
570
- const outputPath = exePath; // Overwrite or use a different path
571
- const version = "1.2.3"; // Your application version
602
+ const exePath = 'dist/my-tool.exe'; // Path to the generated executable
603
+ const outputPath = exePath; // Overwrite or use a different path
604
+ const version = '1.2.3'; // Your application version
572
605
 
573
- const lang = 1033; // en-US
574
- const codepage = 1200; // Unicode
606
+ const lang = 1033; // en-US
607
+ const codepage = 1200; // Unicode
575
608
 
576
609
  const exeData = fs.readFileSync(exePath);
577
610
  const exe = ResEdit.NtExecutable.from(exeData);
@@ -580,19 +613,22 @@ const res = ResEdit.NtExecutableResource.from(exe);
580
613
  const viList = ResEdit.Resource.VersionInfo.fromEntries(res.entries);
581
614
  const vi = viList[0];
582
615
 
583
- const [major, minor, patch] = version.split(".");
616
+ const [major, minor, patch] = version.split('.');
584
617
  vi.setFileVersion(Number(major), Number(minor), Number(patch), 0, lang);
585
618
  vi.setProductVersion(Number(major), Number(minor), Number(patch), 0, lang);
586
619
 
587
- vi.setStringValues({ lang, codepage }, {
588
- FileDescription: "ACME CLI Tool",
589
- ProductName: "ACME Application",
590
- CompanyName: "ACME Corporation",
591
- ProductVersion: version,
592
- FileVersion: version,
593
- OriginalFilename: path.basename(exePath),
594
- LegalCopyright: `© ${new Date().getFullYear()} ACME Corporation`
595
- });
620
+ vi.setStringValues(
621
+ { lang, codepage },
622
+ {
623
+ FileDescription: 'ACME CLI Tool',
624
+ ProductName: 'ACME Application',
625
+ CompanyName: 'ACME Corporation',
626
+ ProductVersion: version,
627
+ FileVersion: version,
628
+ OriginalFilename: path.basename(exePath),
629
+ LegalCopyright: `© ${new Date().getFullYear()} ACME Corporation`,
630
+ },
631
+ );
596
632
 
597
633
  vi.outputToResourceEntries(res.entries);
598
634
  res.outputResource(exe);
@@ -610,6 +646,7 @@ The following command examples inject an icon and metadata into the executable
610
646
  `dist/bin/app.exe`.
611
647
 
612
648
  - **Example (PowerShell on Windows)**
649
+
613
650
  ```powershell
614
651
  npx resedit dist/bin/app.exe dist/bin/app_with_metadata.exe `
615
652
  --icon 1,dist/favicon.ico `
@@ -86,7 +86,6 @@ function reconstructSpecifiers(specs) {
86
86
  return defaults.join(', ');
87
87
  }
88
88
  function reconstruct(node) {
89
- // @ts-expect-error Type mismatch due to @babel/types version in @types/babel__generator
90
89
  let v = (0, generator_1.default)(node, { comments: false }).code.replace(/\n/g, '');
91
90
  let v2;
92
91
  while (true) {
@@ -33,39 +33,70 @@ const esbuild = __importStar(require("esbuild"));
33
33
  const log_1 = require("./log");
34
34
  const common_1 = require("./common");
35
35
  /**
36
- * Detect ESM features that cannot be safely transformed to CommonJS
37
- * These include:
38
- * - Top-level await (no CJS equivalent)
39
- * - import.meta (no CJS equivalent)
36
+ * Wrapper for top-level await support
37
+ * Wraps code in an async IIFE to allow top-level await in CommonJS
38
+ */
39
+ const ASYNC_IIFE_WRAPPER = {
40
+ prefix: '(async () => {\n',
41
+ suffix: '\n})()',
42
+ };
43
+ /**
44
+ * Check if code contains import.meta usage
40
45
  *
41
46
  * @param code - The ESM source code to check
42
- * @param filename - The filename for error reporting
43
- * @returns Array of unsupported features found, or null if parse fails
47
+ * @returns true if import.meta is used, false otherwise
44
48
  */
45
- function detectUnsupportedESMFeatures(code, filename) {
49
+ function hasImportMeta(code) {
46
50
  try {
47
51
  const ast = babel.parse(code, {
48
52
  sourceType: 'module',
49
53
  plugins: [],
50
54
  });
51
55
  if (!ast) {
52
- return null;
56
+ return false;
53
57
  }
54
- const unsupportedFeatures = [];
55
- // @ts-expect-error Type mismatch due to @babel/types version in @types/babel__traverse
58
+ let found = false;
56
59
  (0, traverse_1.default)(ast, {
57
60
  // Detect import.meta usage
58
61
  MetaProperty(path) {
59
62
  if (path.node.meta.name === 'import' &&
60
63
  path.node.property.name === 'meta') {
61
- unsupportedFeatures.push({
62
- feature: 'import.meta',
63
- line: path.node.loc?.start.line ?? null,
64
- column: path.node.loc?.start.column ?? null,
65
- });
64
+ found = true;
65
+ path.stop(); // Stop traversal once found
66
66
  }
67
67
  },
68
- // Detect top-level await
68
+ });
69
+ return found;
70
+ }
71
+ catch (_error) {
72
+ // If we can't parse, assume no import.meta
73
+ return false;
74
+ }
75
+ }
76
+ /**
77
+ * Detect ESM features that require special handling or cannot be transformed
78
+ * These include:
79
+ * - Top-level await (can be handled with async IIFE wrapper)
80
+ *
81
+ * Note: import.meta is now supported via polyfills and is no longer in the unsupported list
82
+ *
83
+ * @param code - The ESM source code to check
84
+ * @param filename - The filename for error reporting
85
+ * @returns Object with arrays of features requiring special handling
86
+ */
87
+ function detectESMFeatures(code, filename) {
88
+ try {
89
+ const ast = babel.parse(code, {
90
+ sourceType: 'module',
91
+ plugins: [],
92
+ });
93
+ if (!ast) {
94
+ return null;
95
+ }
96
+ const topLevelAwait = [];
97
+ const unsupportedFeatures = [];
98
+ (0, traverse_1.default)(ast, {
99
+ // Detect top-level await - can be handled with async IIFE wrapper
69
100
  AwaitExpression(path) {
70
101
  // Check if await is at top level (not inside a function)
71
102
  let parent = path.parentPath;
@@ -82,14 +113,14 @@ function detectUnsupportedESMFeatures(code, filename) {
82
113
  parent = parent.parentPath;
83
114
  }
84
115
  if (isTopLevel) {
85
- unsupportedFeatures.push({
116
+ topLevelAwait.push({
86
117
  feature: 'top-level await',
87
118
  line: path.node.loc?.start.line ?? null,
88
119
  column: path.node.loc?.start.column ?? null,
89
120
  });
90
121
  }
91
122
  },
92
- // Detect for-await-of at top level
123
+ // Detect for-await-of at top level - can be handled with async IIFE wrapper
93
124
  ForOfStatement(path) {
94
125
  if (path.node.await) {
95
126
  let parent = path.parentPath;
@@ -106,7 +137,7 @@ function detectUnsupportedESMFeatures(code, filename) {
106
137
  parent = parent.parentPath;
107
138
  }
108
139
  if (isTopLevel) {
109
- unsupportedFeatures.push({
140
+ topLevelAwait.push({
110
141
  feature: 'top-level for-await-of',
111
142
  line: path.node.loc?.start.line ?? null,
112
143
  column: path.node.loc?.start.column ?? null,
@@ -115,14 +146,51 @@ function detectUnsupportedESMFeatures(code, filename) {
115
146
  }
116
147
  },
117
148
  });
118
- return unsupportedFeatures;
149
+ return { topLevelAwait, unsupportedFeatures };
119
150
  }
120
151
  catch (error) {
121
152
  // If we can't parse, return null to let the transform attempt proceed
122
- log_1.log.debug(`Could not parse ${filename} to detect unsupported ESM features: ${error instanceof Error ? error.message : String(error)}`);
153
+ log_1.log.debug(`Could not parse ${filename} to detect ESM features: ${error instanceof Error ? error.message : String(error)}`);
123
154
  return null;
124
155
  }
125
156
  }
157
+ /**
158
+ * Replace esbuild's empty import_meta object with a proper implementation
159
+ *
160
+ * When esbuild transforms ESM to CJS, it converts `import.meta` to a `const import_meta = {}`.
161
+ * This function replaces that empty object with a proper implementation of import.meta properties.
162
+ *
163
+ * Shims provided:
164
+ * - import.meta.url: File URL of the current module
165
+ * - import.meta.dirname: Directory path of the current module (Node.js 20.11+)
166
+ * - import.meta.filename: File path of the current module (Node.js 20.11+)
167
+ *
168
+ * Based on approach from tsup and esbuild discussions
169
+ * @see https://github.com/egoist/tsup/blob/main/assets/cjs_shims.js
170
+ * @see https://github.com/evanw/esbuild/issues/3839
171
+ *
172
+ * @param code - The transformed CJS code from esbuild
173
+ * @returns Code with import_meta properly implemented
174
+ */
175
+ function replaceImportMetaObject(code) {
176
+ // esbuild generates: const import_meta = {};
177
+ // We need to replace this with a proper implementation
178
+ // Note: We use getters to ensure values are computed at runtime in the correct context
179
+ const shimImplementation = `const import_meta = {
180
+ get url() {
181
+ return require('url').pathToFileURL(__filename).href;
182
+ },
183
+ get dirname() {
184
+ return __dirname;
185
+ },
186
+ get filename() {
187
+ return __filename;
188
+ }
189
+ };`;
190
+ // Replace esbuild's empty import_meta object with our implementation
191
+ // Match: const import_meta = {};
192
+ return code.replace(/const import_meta\s*=\s*\{\s*\};/, shimImplementation);
193
+ }
126
194
  /**
127
195
  * Transform ESM code to CommonJS using esbuild
128
196
  * This allows ESM modules to be compiled to bytecode via vm.Script
@@ -141,10 +209,13 @@ function transformESMtoCJS(code, filename) {
141
209
  isTransformed: false,
142
210
  };
143
211
  }
144
- // First, check for unsupported ESM features that can't be safely transformed
145
- const unsupportedFeatures = detectUnsupportedESMFeatures(code, filename);
146
- if (unsupportedFeatures && unsupportedFeatures.length > 0) {
147
- const featureList = unsupportedFeatures
212
+ // First, check for ESM features that need special handling
213
+ const esmFeatures = detectESMFeatures(code, filename);
214
+ // Handle truly unsupported features (import.meta)
215
+ if (esmFeatures &&
216
+ esmFeatures.unsupportedFeatures &&
217
+ esmFeatures.unsupportedFeatures.length > 0) {
218
+ const featureList = esmFeatures.unsupportedFeatures
148
219
  .map((f) => {
149
220
  const location = f.line !== null ? ` at line ${f.line}` : '';
150
221
  return ` - ${f.feature}${location}`;
@@ -169,15 +240,100 @@ function transformESMtoCJS(code, filename) {
169
240
  isTransformed: false,
170
241
  };
171
242
  }
243
+ // Check if we need to wrap in async IIFE for top-level await
244
+ const hasTopLevelAwait = esmFeatures &&
245
+ esmFeatures.topLevelAwait &&
246
+ esmFeatures.topLevelAwait.length > 0;
247
+ let codeToTransform = code;
248
+ // If top-level await is detected, we need to wrap in async IIFE
249
+ // But we must handle imports and exports specially
250
+ if (hasTopLevelAwait) {
251
+ try {
252
+ // Parse the code to check for exports and collect imports
253
+ const ast = babel.parse(code, {
254
+ sourceType: 'module',
255
+ plugins: [],
256
+ });
257
+ let hasExports = false;
258
+ const codeLines = code.split('\n');
259
+ const importLineIndices = new Set();
260
+ (0, traverse_1.default)(ast, {
261
+ ExportNamedDeclaration() {
262
+ hasExports = true;
263
+ },
264
+ ExportDefaultDeclaration() {
265
+ hasExports = true;
266
+ },
267
+ ExportAllDeclaration() {
268
+ hasExports = true;
269
+ },
270
+ ImportDeclaration(path) {
271
+ // Track import statements by line number
272
+ const { loc } = path.node;
273
+ if (loc) {
274
+ const { start, end } = loc;
275
+ for (let i = start.line; i <= end.line; i += 1) {
276
+ importLineIndices.add(i - 1); // Convert to 0-based index
277
+ }
278
+ }
279
+ },
280
+ });
281
+ if (hasExports) {
282
+ // If the file has exports, we can't wrap it in an IIFE
283
+ // because exports need to be synchronous and at the top level.
284
+ log_1.log.warn(`Module ${filename} has both top-level await and export statements. ` +
285
+ `This combination cannot be safely transformed to CommonJS in pkg's ESM transformer. ` +
286
+ `The original source code will be used as-is; depending on the package visibility and build configuration, ` +
287
+ `bytecode compilation may fail and the module may need to be loaded from source or be skipped.`);
288
+ return {
289
+ code,
290
+ isTransformed: false,
291
+ };
292
+ }
293
+ // If there are imports, extract them to keep outside the async IIFE
294
+ if (importLineIndices.size > 0) {
295
+ const imports = [];
296
+ const rest = [];
297
+ codeLines.forEach((line, index) => {
298
+ if (importLineIndices.has(index)) {
299
+ imports.push(line);
300
+ }
301
+ else {
302
+ rest.push(line);
303
+ }
304
+ });
305
+ // Reconstruct: imports at top, then async IIFE wrapping the rest
306
+ codeToTransform = `${imports.join('\n')}\n${ASYNC_IIFE_WRAPPER.prefix}${rest.join('\n')}${ASYNC_IIFE_WRAPPER.suffix}`;
307
+ log_1.log.debug(`Wrapping ${filename} in async IIFE with imports extracted to top level`);
308
+ }
309
+ else {
310
+ // No imports, wrap everything
311
+ codeToTransform =
312
+ ASYNC_IIFE_WRAPPER.prefix + code + ASYNC_IIFE_WRAPPER.suffix;
313
+ log_1.log.debug(`Wrapping ${filename} in async IIFE to support top-level await`);
314
+ }
315
+ }
316
+ catch (parseError) {
317
+ // If we can't parse, wrap everything and hope for the best
318
+ codeToTransform =
319
+ ASYNC_IIFE_WRAPPER.prefix + code + ASYNC_IIFE_WRAPPER.suffix;
320
+ log_1.log.warn(`Could not parse ${filename} to detect exports/imports (${parseError instanceof Error ? parseError.message : String(parseError)}). ` +
321
+ `Wrapping entire code in async IIFE - this may fail if the module has export or import statements.`);
322
+ }
323
+ }
324
+ // Check if code uses import.meta before transformation
325
+ const usesImportMeta = hasImportMeta(code);
172
326
  try {
173
- const result = esbuild.transformSync(code, {
327
+ // Build esbuild options
328
+ const esbuildOptions = {
174
329
  loader: 'js',
175
330
  format: 'cjs',
176
- target: 'node18',
331
+ target: 'node20',
177
332
  sourcemap: false,
178
333
  minify: false,
179
334
  keepNames: true,
180
- });
335
+ };
336
+ const result = esbuild.transformSync(codeToTransform, esbuildOptions);
181
337
  if (!result || !result.code) {
182
338
  log_1.log.warn(`esbuild transform returned no code for ${filename}`);
183
339
  return {
@@ -185,8 +341,13 @@ function transformESMtoCJS(code, filename) {
185
341
  isTransformed: false,
186
342
  };
187
343
  }
344
+ // Inject import.meta shims after esbuild transformation if needed
345
+ let finalCode = result.code;
346
+ if (usesImportMeta) {
347
+ finalCode = replaceImportMetaObject(result.code);
348
+ }
188
349
  return {
189
- code: result.code,
350
+ code: finalCode,
190
351
  isTransformed: true,
191
352
  };
192
353
  }
@@ -64,19 +64,16 @@ function fabricate(bakes, fabricator, snap, body, cb) {
64
64
  }
65
65
  let stdout = Buffer.alloc(0);
66
66
  function onError(error) {
67
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
68
67
  removeListeners();
69
68
  kill();
70
69
  cb(new Error(`Failed to make bytecode ${fabricator.nodeRange}-${fabricator.arch} for file ${snap} error (${error.message})`));
71
70
  }
72
71
  function onClose(code) {
73
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
74
72
  removeListeners();
75
73
  kill();
76
74
  if (code !== 0) {
77
75
  return cb(new Error(`Failed to make bytecode ${fabricator.nodeRange}-${fabricator.arch} for file ${snap}`));
78
76
  }
79
- // eslint-disable-next-line no-console
80
77
  console.log(stdout.toString());
81
78
  return cb(new Error(`${cmd} closed unexpectedly`));
82
79
  }
@@ -87,7 +84,6 @@ function fabricate(bakes, fabricator, snap, body, cb) {
87
84
  if (stdout.length >= 4 + sizeOfBlob) {
88
85
  const blob = Buffer.alloc(sizeOfBlob);
89
86
  stdout.copy(blob, 0, 4, 4 + sizeOfBlob);
90
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
91
87
  removeListeners();
92
88
  return cb(undefined, blob);
93
89
  }
package/lib-es5/follow.js CHANGED
@@ -114,7 +114,7 @@ function follow(x, opts) {
114
114
  // CJS package - fall through to standard CommonJS resolution
115
115
  // to handle all callbacks properly
116
116
  }
117
- catch (error) {
117
+ catch (_error) {
118
118
  // ESM resolution failed - fall through to standard CommonJS resolution
119
119
  }
120
120
  }
package/lib-es5/help.js CHANGED
@@ -2,7 +2,6 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const colors_1 = require("./colors");
4
4
  function help() {
5
- // eslint-disable-next-line no-console
6
5
  console.log(`
7
6
  ${colors_1.pc.bold('pkg')} [options] <input>
8
7
 
@@ -34,7 +33,7 @@ function help() {
34
33
  ${colors_1.pc.gray('–')} Makes executable for particular target machine
35
34
  ${colors_1.pc.cyan('$ pkg -t node14-win-arm64 index.js')}
36
35
  ${colors_1.pc.gray('–')} Makes executables for target machines of your choice
37
- ${colors_1.pc.cyan('$ pkg -t node16-linux,node18-linux,node18-win index.js')}
36
+ ${colors_1.pc.cyan('$ pkg -t node22-linux,node24-linux,node24-win index.js')}
38
37
  ${colors_1.pc.gray('–')} Bakes '--expose-gc' and '--max-heap-size=34' into executable
39
38
  ${colors_1.pc.cyan('$ pkg --options "expose-gc,max-heap-size=34" index.js')}
40
39
  ${colors_1.pc.gray('–')} Consider packageA and packageB to be public
package/lib-es5/index.js CHANGED
@@ -1,5 +1,4 @@
1
1
  "use strict";
2
- /* eslint-disable require-atomic-updates */
3
2
  var __importDefault = (this && this.__importDefault) || function (mod) {
4
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
5
4
  };
@@ -30,7 +29,6 @@ function isConfiguration(file) {
30
29
  }
31
30
  // http://www.openwall.com/lists/musl/2012/12/08/4
32
31
  const { hostArch, hostPlatform, isValidNodeRange, knownArchs, knownPlatforms, toFancyArch, toFancyPlatform, } = pkg_fetch_1.system;
33
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
34
32
  const hostNodeRange = `node${process.version.match(/^v(\d+)/)[1]}`;
35
33
  function parseTargets(items) {
36
34
  // [ 'node6-macos-x64', 'node6-linux-x64' ]
@@ -191,7 +189,6 @@ async function exec(argv2) {
191
189
  }
192
190
  // version
193
191
  if (argv.v || argv.version) {
194
- // eslint-disable-next-line no-console
195
192
  console.log(version);
196
193
  return;
197
194
  }
@@ -218,7 +215,6 @@ async function exec(argv2) {
218
215
  throw (0, log_1.wasReported)(`Invalid compression algorithm ${algo} ( should be None, Brotli or Gzip)`);
219
216
  }
220
217
  if (doCompress !== compress_type_1.CompressType.None) {
221
- // eslint-disable-next-line no-console
222
218
  console.log('compression: ', compress_type_1.CompressType[doCompress]);
223
219
  }
224
220
  // _
@@ -288,7 +284,7 @@ async function exec(argv2) {
288
284
  if (!(0, fs_1.existsSync)(config)) {
289
285
  throw (0, log_1.wasReported)('Config file does not exist', [config]);
290
286
  }
291
- // eslint-disable-next-line import/no-dynamic-require, global-require
287
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
292
288
  configJson = require(config); // may be either json or js
293
289
  if (!configJson.name &&
294
290
  !configJson.files &&
package/lib-es5/packer.js CHANGED
@@ -1,5 +1,4 @@
1
1
  "use strict";
2
- /* eslint-disable complexity */
3
2
  var __importDefault = (this && this.__importDefault) || function (mod) {
4
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
5
4
  };
@@ -27,13 +26,22 @@ function hasAnyStore(record) {
27
26
  }
28
27
  function packer({ records, entrypoint, bytecode, }) {
29
28
  const stripes = [];
30
- for (const snap in records) {
29
+ // If the entrypoint was a .mjs file that got transformed, update its extension
30
+ if (records[entrypoint]?.wasTransformed && entrypoint.endsWith('.mjs')) {
31
+ entrypoint = `${entrypoint.slice(0, -4)}.js`;
32
+ }
33
+ for (let snap in records) {
31
34
  if (records[snap]) {
32
35
  const record = records[snap];
33
36
  const { file } = record;
34
37
  if (!hasAnyStore(record)) {
35
38
  continue;
36
39
  }
40
+ // If .mjs file was transformed to CJS, rename it to .js in the snapshot
41
+ // This prevents Node.js from treating it as an ES module
42
+ if (record.wasTransformed && snap.endsWith('.mjs')) {
43
+ snap = `${snap.slice(0, -4)}.js`;
44
+ }
37
45
  (0, assert_1.default)(record[common_1.STORE_STAT], 'packer: no STORE_STAT');
38
46
  (0, assert_1.default)(record[common_1.STORE_BLOB] ||
39
47
  record[common_1.STORE_CONTENT] ||
@@ -52,7 +52,7 @@ function resolveWithExports(packageName, subpath, packageRoot) {
52
52
  }
53
53
  return null;
54
54
  }
55
- catch (error) {
55
+ catch (_error) {
56
56
  log_1.log.debug(`Failed to resolve with exports field: ${packageName}${subpath}`);
57
57
  return null;
58
58
  }
package/lib-es5/walker.js CHANGED
@@ -1,5 +1,4 @@
1
1
  "use strict";
2
- /* eslint-disable require-atomic-updates */
3
2
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
3
  if (k2 === undefined) k2 = k;
5
4
  var desc = Object.getOwnPropertyDescriptor(m, k);
@@ -838,7 +837,7 @@ class Walker {
838
837
  record.body = Buffer.from(JSON.stringify(pkgContent, null, 2), 'utf8');
839
838
  }
840
839
  }
841
- catch (error) {
840
+ catch (_error) {
842
841
  // Ignore JSON parsing errors
843
842
  }
844
843
  }
@@ -852,6 +851,10 @@ class Walker {
852
851
  const result = (0, esm_transformer_1.transformESMtoCJS)(record.body.toString('utf8'), record.file);
853
852
  if (result.isTransformed) {
854
853
  record.body = Buffer.from(result.code, 'utf8');
854
+ // Mark .mjs files as transformed so packer can rename them to .js
855
+ if (record.file.endsWith('.mjs')) {
856
+ record.wasTransformed = true;
857
+ }
855
858
  }
856
859
  }
857
860
  catch (error) {
@@ -927,7 +930,6 @@ class Walker {
927
930
  switch (store) {
928
931
  case common_1.STORE_BLOB:
929
932
  case common_1.STORE_CONTENT:
930
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
931
933
  await this.step_STORE_ANY(record, task.marker, store);
932
934
  break;
933
935
  case common_1.STORE_LINKS:
@@ -952,7 +954,7 @@ class Walker {
952
954
  if (this.params.noDictionary?.includes(file)) {
953
955
  continue;
954
956
  }
955
- // eslint-disable-next-line import/no-dynamic-require, global-require, @typescript-eslint/no-var-requires
957
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
956
958
  const config = require(path_1.default.join(dd, file));
957
959
  this.dictionary[name] = config;
958
960
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yao-pkg/pkg",
3
- "version": "6.13.0",
3
+ "version": "6.14.0",
4
4
  "description": "Package your Node.js project into an executable",
5
5
  "main": "lib-es5/index.js",
6
6
  "license": "MIT",
@@ -26,9 +26,9 @@
26
26
  "@babel/parser": "^7.23.0",
27
27
  "@babel/traverse": "^7.23.0",
28
28
  "@babel/types": "^7.23.0",
29
- "esbuild": "^0.24.0",
30
29
  "@yao-pkg/pkg-fetch": "3.5.32",
31
- "into-stream": "^6.0.0",
30
+ "esbuild": "^0.27.3",
31
+ "into-stream": "^9.1.0",
32
32
  "minimist": "^1.2.6",
33
33
  "multistream": "^4.1.0",
34
34
  "picocolors": "^1.1.0",
@@ -37,35 +37,36 @@
37
37
  "resolve": "^1.22.10",
38
38
  "resolve.exports": "^2.0.3",
39
39
  "stream-meter": "^1.0.4",
40
- "tar": "^7.5.6",
40
+ "tar": "^7.5.7",
41
41
  "tinyglobby": "^0.2.11",
42
42
  "unzipper": "^0.12.3"
43
43
  },
44
44
  "devDependencies": {
45
- "@release-it/conventional-changelog": "^7.0.2",
45
+ "@release-it/conventional-changelog": "^10.0.5",
46
46
  "@types/babel__generator": "^7.6.5",
47
47
  "@types/babel__traverse": "^7.20.3",
48
48
  "@types/minimist": "^1.2.2",
49
49
  "@types/multistream": "^4.1.0",
50
- "@types/node": "^16.18.113",
50
+ "@types/node": "^20.0.0",
51
51
  "@types/picomatch": "^3.0.1",
52
52
  "@types/resolve": "^1.20.2",
53
53
  "@types/stream-meter": "^0.0.22",
54
54
  "@types/tar": "^6.1.13",
55
55
  "@types/unzipper": "^0.10.10",
56
- "@typescript-eslint/eslint-plugin": "^6.7.4",
57
- "@typescript-eslint/parser": "^6.7.4",
56
+ "@typescript-eslint/eslint-plugin": "^8.0.0",
57
+ "@typescript-eslint/parser": "^8.0.0",
58
58
  "esbuild-register": "^3.6.0",
59
- "eslint": "^8.50.0",
59
+ "eslint": "^9.0.0",
60
60
  "eslint-config-airbnb-base": "^15.0.0",
61
- "eslint-config-airbnb-typescript": "^17.1.0",
62
- "eslint-config-prettier": "^9.0.0",
63
- "eslint-plugin-import": "^2.28.1",
61
+ "eslint-config-airbnb-typescript": "^18.0.0",
62
+ "eslint-config-prettier": "^10.0.0",
63
+ "eslint-plugin-import": "^2.31.0",
64
+ "globals": "^17.3.0",
64
65
  "json-stable-stringify": "^1.0.1",
65
- "lint-staged": "^15.2.10",
66
+ "lint-staged": "^15.0.0",
66
67
  "prettier": "^3.0.3",
67
- "release-it": "^16.2.1",
68
- "rimraf": "^3.0.2",
68
+ "release-it": "^19.2.4",
69
+ "rimraf": "^6.1.2",
69
70
  "simple-git-hooks": "^2.11.1",
70
71
  "typescript": "^4.7.2"
71
72
  },
@@ -79,9 +80,10 @@
79
80
  "fix": "npm run lint:style -- -w && npm run lint:code -- --fix",
80
81
  "prepare": "npm run build",
81
82
  "prepublishOnly": "npm run lint",
82
- "test": "npm run build && npm run test:host && npm run test:18 && npm run test:20",
83
+ "test": "npm run build && npm run test:host && npm run test:20 && npm run test:22 && npm run test:24",
83
84
  "test:20": "node test/test.js node20 no-npm",
84
- "test:18": "node test/test.js node18 no-npm",
85
+ "test:22": "node test/test.js node22 no-npm",
86
+ "test:24": "node test/test.js node24 no-npm",
85
87
  "test:host": "node test/test.js host only-npm",
86
88
  "bump:fetch": "yarn add @yao-pkg/pkg-fetch --exact",
87
89
  "release": "read -p 'GITHUB_TOKEN: ' GITHUB_TOKEN && export GITHUB_TOKEN=$GITHUB_TOKEN && release-it"
@@ -97,6 +99,15 @@
97
99
  },
98
100
  "packageManager": "yarn@1.22.22",
99
101
  "engines": {
100
- "node": ">=18.0.0"
102
+ "node": ">=20.0.0"
103
+ },
104
+ "resolutions": {
105
+ "lodash": "^4.17.23",
106
+ "@octokit/request-error": "^5.1.1",
107
+ "@octokit/plugin-paginate-rest": "^9.2.2",
108
+ "@octokit/request": "^8.4.1",
109
+ "js-yaml": "^4.1.1",
110
+ "brace-expansion": "^2.0.2",
111
+ "tmp": "^0.2.4"
101
112
  }
102
113
  }
@@ -1,9 +1,3 @@
1
- /* eslint-disable import/no-unresolved */
2
- /* eslint-disable global-require */
3
- /* eslint-disable no-underscore-dangle */
4
- /* eslint-disable prefer-rest-params */
5
- /* eslint-disable prefer-spread */
6
-
7
1
  /* global EXECPATH_FD */
8
2
  /* global PAYLOAD_POSITION */
9
3
  /* global PAYLOAD_SIZE */
@@ -1,5 +1,3 @@
1
- /* eslint-disable global-require */
2
- /* eslint-disable no-console */
3
1
  /* global DICT */
4
2
 
5
3
  'use strict';