Skip to content

Commit

Permalink
fix(esbuild-meta): handle missing stats path
Browse files Browse the repository at this point in the history
  • Loading branch information
ChristopherPHolder committed Jul 3, 2024
1 parent 14ec44f commit ea51338
Show file tree
Hide file tree
Showing 7 changed files with 100 additions and 21 deletions.
16 changes: 16 additions & 0 deletions packages/esbuild-meta/e2e/__snapshots__/filter.test.e2e.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`filter command > should have a help option 1`] = `
"esbuild-meta filter
Filters the meta file to only include chunks required by specified entry points
Options:
-s, --statsPath The path to the stats.json file [string] [required]
-o, --outPath The path where the new file should be saved [string] [default: "initial-stats.json"]
--excludeDynamicImports, --eDI Should the dynamic imports be filtered out of the output chunk imports [boolean] [default: false]
-e, --entryPoints Entry points that should be considered for the bundle [array] [default: ["main-","polyfills-"]]
-v, --version Show version number [boolean]
-h, --help Show help [boolean]
"
`;
28 changes: 28 additions & 0 deletions packages/esbuild-meta/e2e/filter.test.e2e.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { describe, expect, it } from 'vitest';
import { cliProcess } from './utils.js';
import { DEMAND_STATS_PATH } from '../src/lib/filter-meta.js';
import { INVALID_FILE_PATH_ERROR_MSG } from '../src/lib/utils.js';

describe('filter command', () => {
it('should have a help option', async () => {
const { stdout, stderr, code } = await cliProcess('esbuild-meta filter --help');
expect(stdout).toMatchSnapshot();
expect(stderr).toBeFalsy();
expect(code).toBe(0);
});

it('should demand stats path option', async () => {
const { stdout, stderr, code } = await cliProcess('esbuild-meta filter');
expect(stderr).toContain(DEMAND_STATS_PATH);
expect(stdout).toBeFalsy();
expect(code).toBe(1);
});

it('should throw if stats path does not point to a file', async () => {
const INVALID_STATS_FILE = 'invalid-path.json';
const { stdout, stderr, code } = await cliProcess(`esbuild-meta filter --statsPath ${INVALID_STATS_FILE}`);
expect(stderr).toContain(INVALID_FILE_PATH_ERROR_MSG('invalid-path.json'));
expect(stdout).toBeFalsy();
expect(code).toBe(1);
});
});
26 changes: 16 additions & 10 deletions packages/esbuild-meta/e2e/root.test.e2e.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,32 @@
import { describe, it, expect, beforeAll } from 'vitest';
import { version } from '../package.json';

import { commandOutput } from './utils.js';
import { cliProcess, CliProcessOutput } from './utils.js';

describe('--help', () => {
let helpOutput: string;
let output: CliProcessOutput;

beforeAll(() => {
helpOutput = commandOutput('esbuild-meta --help');
beforeAll(async () => {
output = await cliProcess('esbuild-meta --help');
});

it('should show help', () => {
expect(helpOutput).toMatchSnapshot();
it('should show help', async () => {
const { stdout, stderr, code } = output;
expect(stdout).toMatchSnapshot();
expect(stderr).toBeFalsy();
expect(code).toBe(0);
});

it('should alias to -h', () => {
expect(commandOutput('esbuild-meta -h')).toBe(helpOutput);
it('should alias to -h', async () => {
expect(await cliProcess('esbuild-meta --help')).toEqual(output);
});
});

describe('--version', () => {
it('should show version', () => {
expect(commandOutput('esbuild-meta --version')).toContain(version);
it('should show version', async () => {
const {stdout, stderr, code} = await cliProcess('esbuild-meta --version');
expect(stdout).toContain(version);
expect(stderr).toBeFalsy();
expect(code).toBe(0);
});
});
20 changes: 18 additions & 2 deletions packages/esbuild-meta/e2e/utils.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
import { execSync } from 'child_process';
import { spawn } from 'node:child_process';

export const commandOutput = (command: string) => execSync(command).toString();
export type CliProcessOutput = {
stdout: string;
stderr: string;
code: number | null;
}

export const cliProcess = (command: string) => {
return new Promise<CliProcessOutput>((resolve) => {
const process = spawn(command, [], { stdio: 'pipe', shell: true });

let stdout = '';
let stderr = '';
process.stdout.on('data', (data) => stdout += String(data));
process.stderr.on('data', (data) => stderr += String(data));
process.on('close', code => resolve({ stdout, stderr, code }));
})
}
14 changes: 8 additions & 6 deletions packages/esbuild-meta/src/lib/filter-meta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@ import {
makeJson,
} from './utils.js';

const distPath = {
alias: 'd',
export const DEMAND_STATS_PATH = 'The path to a stats.json file is required';

const statsPath = {
alias: 's',
type: 'string',
default: 'dist',
description: 'The path to the stats.json file'
description: 'The path to the stats.json file',
demandOption: DEMAND_STATS_PATH,
} as const satisfies Options;

const outPath = {
Expand All @@ -37,7 +39,7 @@ const entryPoints = {
description: 'Entry points that should be considered for the bundle',
} as const satisfies Options;

const filterMetaOptions = { distPath, outPath, excludeDynamicImports, entryPoints };
const filterMetaOptions = { statsPath, outPath, excludeDynamicImports, entryPoints };

type FilterMetaOptions = InferredOptionTypes<typeof filterMetaOptions>;
type FilterMetaCommandModule = CommandModule<unknown, FilterMetaOptions>;
Expand All @@ -47,7 +49,7 @@ const filterMetaBuilder: CommandBuilder<unknown, FilterMetaOptions> = (argv: Arg
}

const filterMetaHandler: FilterMetaCommandModule['handler'] = (argv: FilterMetaOptions) => {
const meta = getJson<Metafile>([argv.distPath]);
const meta = getJson<Metafile>(argv.statsPath);
const entryPoints = extractEntryPoints(meta, argv.entryPoints);
filterMetaFromEntryPoints(meta, entryPoints);
if (argv.excludeDynamicImports) {
Expand Down
14 changes: 11 additions & 3 deletions packages/esbuild-meta/src/lib/utils.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
import { readFileSync, writeFileSync } from 'node:fs';
import { join } from 'node:path';
import { join, normalize } from 'node:path';
import { Metafile } from 'esbuild';

export function getJson<T = any>(path: string[]) {
return JSON.parse(readFileSync(join(...path), {encoding: 'utf-8'})) as T;
export const INVALID_FILE_PATH_ERROR_MSG = (path: string) => `No file found at ${path}`;

export function getJson<T = any>(path: string) {
const normalizedPath = normalize(path);
try {
return JSON.parse(readFileSync(normalizedPath, {encoding: 'utf-8'})) as T;
}
catch (e) {
throw new Error(INVALID_FILE_PATH_ERROR_MSG(normalizedPath));
}
}

export function makeJson(path: string, file: any) {
Expand Down
3 changes: 3 additions & 0 deletions packages/esbuild-meta/vitest.config.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ export default defineConfig({

test: {
watch: false,
pool: 'threads',
poolOptions: { threads: { singleThread: true } },
testTimeout: 140_000,
reporters: ['default'],
globals: true,
cache: { dir: '../../node_modules/.vitest' },
Expand Down

0 comments on commit ea51338

Please sign in to comment.