diff --git a/package-lock.json b/package-lock.json index f4fbedc..9464aab 100644 --- a/package-lock.json +++ b/package-lock.json @@ -408,6 +408,15 @@ "to-fast-properties": "^2.0.0" } }, + "@gfx/zopfli": { + "version": "1.0.15", + "resolved": "https://registry.npmjs.org/@gfx/zopfli/-/zopfli-1.0.15.tgz", + "integrity": "sha512-7mBgpi7UD82fsff5ThQKet0uBTl4BYerQuc+/qA1ELTwWEiIedRTcD3JgiUu9wwZ2kytW8JOb165rSdAt8PfcQ==", + "dev": true, + "requires": { + "base64-js": "^1.3.0" + } + }, "@nodelib/fs.scandir": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", diff --git a/package.json b/package.json index 26089d4..93639c9 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ "author": "", "module": "dist/lib.esm.js", "devDependencies": { + "@gfx/zopfli": "^1.0.15", "@types/commander": "^2.12.2", "chalk": "^4.1.0", "chromedriver": "^84.0.1", diff --git a/src/bench-reporting/reporting.ts b/src/bench-reporting/reporting.ts index 6396bd0..615af31 100644 --- a/src/bench-reporting/reporting.ts +++ b/src/bench-reporting/reporting.ts @@ -5,6 +5,7 @@ import * as Visit from './visit'; import chalk from 'chalk'; import * as Transform from '../transform'; import { compileToStringSync } from 'node-elm-compiler'; +import * as Post from '../postprocess'; export interface Stat { name: string; bytes: number; @@ -443,7 +444,7 @@ export const run = async function ( instance.dir, source, path.join(instance.dir, instance.elmFile), - false, + options.verbose, options.transforms ) fs.writeFileSync( @@ -454,6 +455,14 @@ export const run = async function ( path.join(instance.dir, 'output', 'elm.opt.transformed.js'), transformed ); + if (options.minify) { + await Post.minify(path.join(instance.dir, 'output', 'elm.opt.js'), path.join(instance.dir, 'output', 'elm.opt.min.js')) + await Post.minify(path.join(instance.dir, 'output', 'elm.opt.transformed.js'), path.join(instance.dir, 'output', 'elm.opt.transformed.min.js')) + } + if (options.minify && options.gzip) { + await Post.gzip(path.join(instance.dir, 'output', 'elm.opt.min.js'), path.join(instance.dir, 'output', 'elm.opt.min.js.gz')) + await Post.gzip(path.join(instance.dir, 'output', 'elm.opt.transformed.min.js'), path.join(instance.dir, 'output', 'elm.opt.transformed.min.js.gz')) + } if (options.assetSizes) { assets[instance.name] = assetSizeStats(path.join(instance.dir, 'output')); @@ -597,23 +606,7 @@ export const runWithBreakdown = async function ( } }); - const final = await Transform.transform( - instance.dir, - source, - path.join(instance.dir, instance.elmFile), - false, - options.transforms - ) - fs.writeFileSync( - path.join(instance.dir, 'output', 'elm.opt.js'), - source - ); - fs.writeFileSync( - path.join(instance.dir, 'output', 'elm.opt.transformed.js'), - final - ); - assets[instance.name] = assetSizeStats(path.join(instance.dir, 'output')); for (let browser of options.runBenchmark) { results.push( @@ -641,7 +634,7 @@ export const runWithBreakdown = async function ( instance.dir, source, path.join(instance.dir, instance.elmFile), - false, + options.verbose, steps[i].options ) fs.writeFileSync( @@ -663,6 +656,33 @@ export const runWithBreakdown = async function ( ); } } + fs.writeFileSync( + path.join(instance.dir, 'output', 'elm.opt.js'), + source + ); + const final = await Transform.transform( + instance.dir, + source, + path.join(instance.dir, instance.elmFile), + options.verbose, + options.transforms + ) + fs.writeFileSync( + path.join(instance.dir, 'output', 'elm.opt.transformed.js'), + final + ); + + if (options.minify) { + await Post.minify(path.join(instance.dir, 'output', 'elm.opt.js'), path.join(instance.dir, 'output', 'elm.opt.min.js')) + await Post.minify(path.join(instance.dir, 'output', 'elm.opt.transformed.js'), path.join(instance.dir, 'output', 'elm.opt.transformed.min.js')) + } + if (options.minify && options.gzip) { + await Post.gzip(path.join(instance.dir, 'output', 'elm.opt.min.js'), path.join(instance.dir, 'output', 'elm.opt.min.js.gz')) + await Post.gzip(path.join(instance.dir, 'output', 'elm.opt.transformed.min.js'), path.join(instance.dir, 'output', 'elm.opt.transformed.min.js.gz')) + } + assets[instance.name] = assetSizeStats(path.join(instance.dir, 'output')); + + } return { assets: assets, benchmarks: reformat(results) }; @@ -693,21 +713,6 @@ export const runWithKnockout = async function ( } }); - const final = await Transform.transform( - instance.dir, - source, - path.join(instance.dir, instance.elmFile), - false, - options.transforms - ) - fs.writeFileSync( - path.join(instance.dir, 'output', 'elm.opt.js'), - source - ); - fs.writeFileSync( - path.join(instance.dir, 'output', 'elm.opt.transformed.js'), - final - ); assets[instance.name] = assetSizeStats(path.join(instance.dir, 'output')); for (let browser of options.runBenchmark) { @@ -735,7 +740,7 @@ export const runWithKnockout = async function ( instance.dir, source, path.join(instance.dir, instance.elmFile), - false, + options.verbose, steps[i].options ) fs.writeFileSync( @@ -756,6 +761,31 @@ export const runWithKnockout = async function ( ); } } + + const final = await Transform.transform( + instance.dir, + source, + path.join(instance.dir, instance.elmFile), + options.verbose, + options.transforms + ) + fs.writeFileSync( + path.join(instance.dir, 'output', 'elm.opt.js'), + source + ); + fs.writeFileSync( + path.join(instance.dir, 'output', 'elm.opt.transformed.js'), + final + ); + if (options.minify) { + await Post.minify(path.join(instance.dir, 'output', 'elm.opt.js'), path.join(instance.dir, 'output', 'elm.opt.min.js')) + await Post.minify(path.join(instance.dir, 'output', 'elm.opt.transformed.js'), path.join(instance.dir, 'output', 'elm.opt.transformed.min.js')) + } + if (options.minify && options.gzip) { + await Post.gzip(path.join(instance.dir, 'output', 'elm.opt.min.js'), path.join(instance.dir, 'output', 'elm.opt.min.js.gz')) + await Post.gzip(path.join(instance.dir, 'output', 'elm.opt.transformed.min.js'), path.join(instance.dir, 'output', 'elm.opt.transformed.min.js.gz')) + } + } return { assets: assets, benchmarks: reformat(results) }; diff --git a/src/bench-reporting/run.ts b/src/bench-reporting/run.ts index f41bf0b..b520b52 100644 --- a/src/bench-reporting/run.ts +++ b/src/bench-reporting/run.ts @@ -37,28 +37,28 @@ const test: Transforms = { const options = { compile: true, - gzip: false, - minify: false, + gzip: true, + minify: true, verbose: true, - assetSizes: false, + assetSizes: true, runBenchmark: [ { browser: Browser.Chrome, - headless: false, + headless: true, }, { browser: Browser.Firefox, - headless: false, + headless: true, }, ], transforms: defaultOptions, }; async function go() { - // const report = await Reporting.run(options, [ - // Use `runWithBreakdown` if you want the breakdown - // const report = await Reporting.runWithKnockout(options, [ - const report = await Reporting.runWithBreakdown(options, [ + const report = await Reporting.run(options, [ + // Use `runWithBreakdown` if you want the breakdown + // const report = await Reporting.runWithKnockout(options, [ + // const report = await Reporting.runWithBreakdown(options, [ // { // name: 'Elm Core', // dir: 'testcases/bench', diff --git a/src/bench-reporting/visit.ts b/src/bench-reporting/visit.ts index f3194b1..2642ca3 100644 --- a/src/bench-reporting/visit.ts +++ b/src/bench-reporting/visit.ts @@ -29,8 +29,8 @@ export const benchmark = async ( // https://www.selenium.dev/selenium/docs/api/javascript/module/selenium-webdriver/index_exports_WebDriver.html let result = []; try { - const tagStr: string = tag == null ? '' : ", " + tag; - console.log(name + tagStr + chalk.green(" -> ") + chalk.yellow(options.browser)) + const label: string = tag == null ? name : name + ", " + tag; + console.log(label.padEnd(20, ' ') + chalk.green(" -> ") + chalk.yellow(options.browser)) await driver.get('file://' + Path.resolve(file)); await driver.wait(Webdriver.until.titleIs('done'), 480000); result = await driver.executeScript('return window.results;'); diff --git a/src/postprocess.ts b/src/postprocess.ts index 095adcc..3bd5dc0 100644 --- a/src/postprocess.ts +++ b/src/postprocess.ts @@ -14,6 +14,8 @@ import * as fs from 'fs'; import { prepackFileSync } from 'prepack'; import * as Terser from 'terser'; import { execSync } from 'child_process'; +import * as Compress from "@gfx/zopfli"; +import { resolveModuleName } from 'typescript'; export function prepack(input: string): string { @@ -75,9 +77,21 @@ export async function minify(inputFilename: string, outputFilename: string) { console.log('Error mangling with Terser'); } } -export async function gzip(file: string) { +export async function gzip(file: string, output: string) { // --keep = keep the original file // --force = overwrite the exisign gzip file if it's there - execSync('gzip --keep --force ' + file); + // execSync('gzip --keep --force ' + file); + const fileContents = fs.readFileSync(file, 'utf8'); + const promise = Compress.gzipAsync(fileContents, {}) + .then( + (compressed) => { + fs.writeFileSync( + output, + compressed + ); + } + ); + + await promise; } diff --git a/src/transforms/inlineWrappedFunctions.ts b/src/transforms/inlineWrappedFunctions.ts index 4f40d46..fa9e3ab 100644 --- a/src/transforms/inlineWrappedFunctions.ts +++ b/src/transforms/inlineWrappedFunctions.ts @@ -98,9 +98,7 @@ function reportInlineTransformResult(ctx: InlineContext) { -export const createFunctionInlineTransformer = (logOverview: boolean - -): ts.TransformerFactory => context => { +export const createFunctionInlineTransformer = (logOverview: boolean): ts.TransformerFactory => context => { return sourceFile => { const inlineContext: InlineContext = createInlineContext();