Skip to content
This repository was archived by the owner on Jan 13, 2024. It is now read-only.

Commit ea7d72b

Browse files
authored
feature: allow to compress files in virtual file system (#1115)
Bug: #885
1 parent 3027f3f commit ea7d72b

28 files changed

Lines changed: 903 additions & 451 deletions

File tree

.eslintrc

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
{
2+
// note you must disable the base rule as it can report incorrect errors
23
"extends": ["airbnb-base", "prettier"],
34
"rules": {
45
"no-bitwise": "off",
@@ -10,8 +11,10 @@
1011
"consistent-return": "off",
1112
"no-restricted-syntax": "off",
1213
"import/prefer-default-export": "off",
13-
"camelcase": "off"
14-
},
14+
"camelcase": "off",
15+
"no-shadow": "off",
16+
"@typescript-eslint/no-shadow": ["error"]
17+
},
1518
"overrides": [
1619
{
1720
"files": ["*.ts"],

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,16 @@ option to `pkg`. First ensure your computer meets the
192192
requirements to compile original Node.js:
193193
[BUILDING.md](https://github.com/nodejs/node/blob/master/BUILDING.md)
194194

195+
### Compression
196+
197+
Pass `--compress Brotli` or `--compress GZip` to `pkg` to compress further the content of the files store in the exectable.
198+
199+
This option can reduce the size of the embedded file system by up to 60%.
200+
201+
The startup time of the application might be reduced slightly.
202+
203+
`-C` can be used as a shortcut for `--compress `.
204+
195205
### Environment
196206

197207
| Var | Description |

lib/compress_type.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
2+
export enum CompressType {
3+
None = 0,
4+
GZip = 1,
5+
Brotli = 2
6+
};

lib/help.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export default function help() {
1919
--public speed up and disclose the sources of top-level project
2020
--public-packages force specified packages to be considered public
2121
--no-bytecode skip bytecode generation and include source files as plain js
22+
-C, --compress [default=None] compression algorithm = Brotli or GZip
2223
2324
${chalk.dim('Examples:')}
2425
@@ -36,5 +37,11 @@ export default function help() {
3637
${chalk.cyan('$ pkg --public-packages "packageA,packageB" index.js')}
3738
${chalk.gray('–')} Consider all packages to be public
3839
${chalk.cyan('$ pkg --public-packages "*" index.js')}
40+
${chalk.gray('–')} Bakes '--expose-gc' into executable
41+
${chalk.cyan('$ pkg --options expose-gc index.js')}
42+
${chalk.gray(
43+
'–'
44+
)} reduce size of the data packed inside the executable with GZip
45+
${chalk.cyan('$ pkg --compress GZip index.js')}
3946
`);
4047
}

lib/index.ts

Lines changed: 37 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* eslint-disable require-atomic-updates */
22

3-
import { mkdirp, readFile, remove, stat, readFileSync } from 'fs-extra';
3+
import { existsSync, mkdirp, readFile, remove, stat, readFileSync } from 'fs-extra';
44
import { need, system } from 'pkg-fetch';
55
import assert from 'assert';
66
import minimist from 'minimist';
@@ -16,6 +16,7 @@ import refine from './refiner';
1616
import { shutdown } from './fabricator';
1717
import walk, { Marker, WalkerParams } from './walker';
1818
import { Target, NodeTarget, SymLinks } from './types';
19+
import { CompressType } from './compress_type';
1920

2021
const { version } = JSON.parse(
2122
readFileSync(path.join(__dirname, '../package.json'), 'utf-8')
@@ -25,15 +26,6 @@ function isConfiguration(file: string) {
2526
return isPackageJson(file) || file.endsWith('.config.json');
2627
}
2728

28-
async function exists(file: string) {
29-
try {
30-
await stat(file);
31-
return true;
32-
} catch (error) {
33-
return false;
34-
}
35-
}
36-
3729
// http://www.openwall.com/lists/musl/2012/12/08/4
3830

3931
const {
@@ -245,6 +237,8 @@ export async function exec(argv2: string[]) {
245237
't',
246238
'target',
247239
'targets',
240+
'C',
241+
'compress',
248242
],
249243
default: { bytecode: true },
250244
});
@@ -272,7 +266,31 @@ export async function exec(argv2: string[]) {
272266

273267
const forceBuild = argv.b || argv.build;
274268

275-
// _
269+
// doCompress
270+
const algo = argv.C || argv.compress || 'None';
271+
272+
273+
let doCompress: CompressType = CompressType.None;
274+
switch (algo.toLowerCase()) {
275+
case 'brotli':
276+
case 'br':
277+
doCompress = CompressType.Brotli;
278+
break;
279+
case 'gzip':
280+
case 'gz':
281+
doCompress = CompressType.GZip;
282+
break;
283+
case 'none':
284+
break;
285+
default:
286+
// eslint-disable-next-line no-console
287+
throw wasReported(`Invalid compression algorithm ${algo} ( should be None, Brotli or Gzip)`);
288+
289+
}
290+
if (doCompress !== CompressType.None) {
291+
// eslint-disable-next-line no-console
292+
console.log('compression: ', CompressType[doCompress]);
293+
}
276294

277295
if (!argv._.length) {
278296
throw wasReported('Entry file/directory is expected', [
@@ -288,14 +306,13 @@ export async function exec(argv2: string[]) {
288306

289307
let input = path.resolve(argv._[0]);
290308

291-
if (!(await exists(input))) {
309+
if (!existsSync(input)) {
292310
throw wasReported('Input file does not exist', [input]);
293311
}
294312

295313
if ((await stat(input)).isDirectory()) {
296314
input = path.join(input, 'package.json');
297-
298-
if (!(await exists(input))) {
315+
if (!existsSync(input)) {
299316
throw wasReported('Input file does not exist', [input]);
300317
}
301318
}
@@ -330,10 +347,10 @@ export async function exec(argv2: string[]) {
330347
}
331348
}
332349
inputBin = path.resolve(path.dirname(input), bin);
333-
if (!(await exists(inputBin))) {
350+
if (!existsSync(inputBin)) {
334351
throw wasReported(
335352
'Bin file does not exist (taken from package.json ' +
336-
"'bin' property)",
353+
"'bin' property)",
337354
[inputBin]
338355
);
339356
}
@@ -362,8 +379,7 @@ export async function exec(argv2: string[]) {
362379

363380
if (config) {
364381
config = path.resolve(config);
365-
366-
if (!(await exists(config))) {
382+
if (!existsSync(config)) {
367383
throw wasReported('Config file does not exist', [config]);
368384
}
369385

@@ -603,7 +619,7 @@ export async function exec(argv2: string[]) {
603619
log.debug('Targets:', JSON.stringify(targets, null, 2));
604620

605621
for (const target of targets) {
606-
if (target.output && (await exists(target.output))) {
622+
if (target.output && existsSync(target.output)) {
607623
if ((await stat(target.output)).isFile()) {
608624
await remove(target.output);
609625
} else {
@@ -615,14 +631,8 @@ export async function exec(argv2: string[]) {
615631
await mkdirp(path.dirname(target.output));
616632
}
617633

618-
await producer({
619-
backpack,
620-
bakes,
621-
slash: target.platform === 'win' ? '\\' : '/',
622-
target: target as Target,
623-
symLinks,
624-
});
625-
634+
const slash = target.platform === 'win' ? '\\' : '/';
635+
await producer({ backpack, bakes, slash, target: target as Target, symLinks, doCompress });
626636
if (target.platform !== 'win' && target.output) {
627637
await plusx(target.output);
628638
}

lib/packer.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
/* eslint-disable complexity */
22

33
import assert from 'assert';
4-
import fs from 'fs-extra';
5-
import path from 'path';
4+
import * as fs from 'fs-extra';
5+
import * as path from 'path';
66

77
import {
88
STORE_BLOB,
@@ -157,7 +157,7 @@ export default function packer({
157157
}
158158
}
159159
const prelude =
160-
`return (function (REQUIRE_COMMON, VIRTUAL_FILESYSTEM, DEFAULT_ENTRYPOINT, SYMLINKS) {
160+
`return (function (REQUIRE_COMMON, VIRTUAL_FILESYSTEM, DEFAULT_ENTRYPOINT, SYMLINKS, DICT, DOCOMPRESS) {
161161
${bootstrapText}${
162162
log.debugMode ? diagnosticText : ''
163163
}\n})(function (exports) {\n${commonText}\n},\n` +
@@ -166,6 +166,10 @@ export default function packer({
166166
`%DEFAULT_ENTRYPOINT%` +
167167
`\n,\n` +
168168
`%SYMLINKS%` +
169+
'\n,\n' +
170+
'%DICT%' +
171+
'\n,\n' +
172+
'%DOCOMPRESS%' +
169173
`\n);`;
170174

171175
return { prelude, entrypoint, stripes };

0 commit comments

Comments
 (0)