11'use strict' ;
2- const { spawnSync, execSync } = require ( 'child_process' ) ;
2+ const { spawnSync } = require ( 'child_process' ) ;
33const path = require ( 'path' ) ;
44const fs = require ( 'fs' ) ;
5+ const binaryenPkg = require . resolve ( 'binaryen/package.json' ) ;
6+ const wasmOptBinPath = path . join ( path . dirname ( binaryenPkg ) , 'bin/wasm-opt' ) ;
7+
58const { EOL } = require ( 'os' ) ;
69
710const logError = ( ...args ) => {
811 console . error ( `w4 opt error: ${ args . join ( EOL ) } ` ) ;
9- }
12+ } ;
13+
14+ const wasmOptFlags = [
15+ '-Oz' ,
16+ '--strip-dwarf' ,
17+ '--strip-producers' ,
18+ '--zero-filled-memory' ,
19+ ] ;
20+
21+ /**
22+ * @type {(bytes: number) => string }
23+ */
24+ const formatKiB = ( bytes ) => {
25+ return ( bytes / 1024 ) . toFixed ( 3 ) + 'KiB' ;
26+ } ;
27+
28+ /**
29+ * @type {(num: number, den: number) => string }
30+ */
31+ const formatPercent = ( num , den ) => {
32+ return `${ ( ( num / den ) * 100 ) . toFixed ( 2 ) } %` ;
33+ } ;
1034
1135/**
1236 * @type {(cart: string, options: { output: string, silent: boolean }) => void }
@@ -17,55 +41,84 @@ function optimizeCart(cart, { output, silent }) {
1741 : path . resolve ( process . cwd ( ) , cart ) ;
1842
1943 const absoluteOutputCartPath = path . isAbsolute ( output )
20- ? output
21- : path . resolve ( process . cwd ( ) , output ) ;
44+ ? output
45+ : path . resolve ( process . cwd ( ) , output ) ;
46+
47+ /**
48+ * @type {import('fs').Stats | null }
49+ */
50+ let inCartStats = null ;
51+ /**
52+ * @type {import('fs').Stats | null }
53+ */
54+ let outCartStats = null ;
2255
23- if ( ! fs . existsSync ( absoluteInputCartPath ) ) {
24- logError ( `cart "${ cart } " not found.` ) ;
56+ try {
57+ inCartStats = fs . statSync ( absoluteInputCartPath ) ;
58+
59+ if ( inCartStats . isDirectory ( ) ) {
60+ logError ( `cart "${ absoluteInputCartPath } " is a directory.` ) ;
2561 process . exitCode = 1 ;
2662 return ;
63+ }
64+ } catch ( err ) {
65+ if ( err ?. code === 'ENOENT' ) {
66+ logError ( `cart "${ absoluteInputCartPath } " not found.` ) ;
67+ } else {
68+ logError ( err ) ;
69+ }
70+
71+ process . exitCode = 1 ;
72+ return ;
2773 }
2874
29- // @see https://nodejs.org/api/child_process.html#child_processspawnsynccommand-args-options
30- const wasmOptProcess = spawnSync (
31- 'npx' ,
32- [
33- '-q' ,
34- '--package' ,
35- 'binaryen' ,
36- '--' ,
37- 'wasm-opt' ,
38- absoluteInputCartPath ,
39- '-o' ,
40- absoluteOutputCartPath ,
41- '-Oz' ,
42- '--strip-dwarf' ,
43- '--strip-producers' ,
44- '--zero-filled-memory' ,
45- ]
46- ) ;
75+ // @see https://nodejs.org/api/child_process.html#child_processspawnsynccommand-args-options
76+ const wasmOptProcess = spawnSync ( wasmOptBinPath , [
77+ absoluteInputCartPath ,
78+ '-o' ,
79+ absoluteOutputCartPath ,
80+ ...wasmOptFlags ,
81+ ] ) ;
4782
4883 // status is the `exitCode`
49- if ( wasmOptProcess . status ) {
84+ if ( wasmOptProcess . status ) {
5085 process . exitCode = wasmOptProcess . status ;
5186
52- logError ( `an error has occurred while running wasm-opt: exit code ${ wasmOptProcess . status } ` ) ;
87+ logError (
88+ `an error has occurred while running wasm-opt. Exit code ${ wasmOptProcess . status } `
89+ ) ;
5390
5491 process . stderr . write ( wasmOptProcess . stderr ) ;
5592 return ;
56- }
57-
93+ }
94+
5895 // wasmOptProcess.error Error | null: `The error object if the child process failed or timed out.`
59- if ( wasmOptProcess . error ) {
96+ if ( wasmOptProcess . error ) {
6097 process . exitCode = 1 ;
61- logError ( `an error has occurred while running wasm-opt: ${ wasmOptProcess . error } ` ) ;
98+ logError (
99+ `an error has occurred while running wasm-opt. Error ${ wasmOptProcess . error } `
100+ ) ;
62101 process . stderr . write ( wasmOptProcess . stderr ) ;
63102
64103 return ;
65104 }
66105
67- if ( ! silent ) {
68- console . log ( `w4 opt${ EOL } - input: ${ absoluteInputCartPath } ${ EOL } - output: ${ absoluteOutputCartPath } ` ) ;
106+ if ( ! silent ) {
107+ outCartStats = fs . statSync ( absoluteOutputCartPath ) ;
108+
109+ process . stdout . write (
110+ [
111+ 'w4 opt' ,
112+ `- input: ${ formatKiB ( inCartStats . size ) } ${ absoluteInputCartPath } ` ,
113+ `- output: ${ formatKiB ( outCartStats . size ) } ${ absoluteOutputCartPath } ` ,
114+ `size reduction: ${ formatPercent (
115+ inCartStats . size - outCartStats . size ,
116+ inCartStats . size
117+ ) } `,
118+ ]
119+ . join ( EOL )
120+ . concat ( EOL )
121+ ) ;
69122 }
70123}
71124
0 commit comments