Skip to content

Commit

Permalink
perf(cli): Dynamic import sharp and gltf-validator dependencies. (#1091)
Browse files Browse the repository at this point in the history
  • Loading branch information
donmccurdy authored Sep 14, 2023
1 parent 23f5f30 commit cc8bfba
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 28 deletions.
29 changes: 17 additions & 12 deletions packages/cli/src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import micromatch from 'micromatch';
import { gzip } from 'node-gzip';
import fetch from 'node-fetch';
import mikktspace from 'mikktspace';
import sharp from 'sharp';
import { MeshoptEncoder, MeshoptSimplifier } from 'meshoptimizer';
import { ready as resampleReady, resample as resampleWASM } from 'keyframe-resample';
import { Logger, NodeIO, PropertyType, VertexLayout, vec2, Transform } from '@gltf-transform/core';
Expand Down Expand Up @@ -198,7 +197,7 @@ Example:
default: TableFormat.PRETTY,
})
.action(({ args, options, logger }) => {
validate(args.input as string, options as unknown as ValidateOptions, logger as unknown as Logger);
return validate(args.input as string, options as unknown as ValidateOptions, logger as unknown as Logger);
});

program.section('Package', '📦');
Expand Down Expand Up @@ -358,9 +357,10 @@ commands or using the scripting API.
toktx({ mode: Mode.ETC1S, quality: 255 }),
);
} else if (opts.textureCompress !== false) {
const { default: encoder } = await import('sharp');
transforms.push(
textureCompress({
encoder: sharp,
encoder,
targetFormat: opts.textureCompress === 'auto' ? undefined : opts.textureCompress,
resize: [opts.textureSize, opts.textureSize],
}),
Expand Down Expand Up @@ -1115,9 +1115,10 @@ preserving original aspect ratio. Texture dimensions are never increased.
})
.action(async ({ args, options, logger }) => {
const pattern = options.pattern ? micromatch.makeRe(String(options.pattern), MICROMATCH_OPTIONS) : null;
const { default: encoder } = await import('sharp');
return Session.create(io, logger, args.input, args.output).transform(
textureCompress({
encoder: sharp,
encoder,
resize: [options.width, options.height] as vec2,
resizeFilter: options.filter as TextureResizeFilter,
pattern,
Expand Down Expand Up @@ -1384,13 +1385,14 @@ program
.option('--quality <quality>', 'Quality, 1-100', { validator: Validator.NUMBER })
.option('--effort <effort>', 'Level of CPU effort to reduce file size, 0-100', { validator: Validator.NUMBER })
.option('--lossless <lossless>', 'Use lossless compression mode', { validator: Validator.BOOLEAN, default: false })
.action(({ args, options, logger }) => {
.action(async ({ args, options, logger }) => {
const formats = micromatch.makeRe(String(options.formats), MICROMATCH_OPTIONS);
const slots = micromatch.makeRe(String(options.slots), MICROMATCH_OPTIONS);
const { default: encoder } = await import('sharp');
return Session.create(io, logger, args.input, args.output).transform(
textureCompress({
targetFormat: 'avif',
encoder: sharp,
encoder,
formats,
slots,
quality: options.quality as number,
Expand Down Expand Up @@ -1419,13 +1421,14 @@ program
validator: Validator.BOOLEAN,
default: false,
})
.action(({ args, options, logger }) => {
.action(async ({ args, options, logger }) => {
const formats = micromatch.makeRe(String(options.formats), MICROMATCH_OPTIONS);
const slots = micromatch.makeRe(String(options.slots), MICROMATCH_OPTIONS);
const { default: encoder } = await import('sharp');
return Session.create(io, logger, args.input, args.output).transform(
textureCompress({
targetFormat: 'webp',
encoder: sharp,
encoder,
formats,
slots,
quality: options.quality as number,
Expand All @@ -1450,13 +1453,14 @@ program
.option('--slots <slots>', 'Texture slots to include (glob)', { validator: Validator.STRING, default: '*' })
.option('--quality <quality>', 'Quality, 1-100', { validator: Validator.NUMBER })
.option('--effort <effort>', 'Level of CPU effort to reduce file size, 0-100', { validator: Validator.NUMBER })
.action(({ args, options, logger }) => {
.action(async ({ args, options, logger }) => {
const formats = micromatch.makeRe(String(options.formats), MICROMATCH_OPTIONS);
const slots = micromatch.makeRe(String(options.slots), MICROMATCH_OPTIONS);
const { default: encoder } = await import('sharp');
return Session.create(io, logger, args.input, args.output).transform(
textureCompress({
targetFormat: 'png',
encoder: sharp,
encoder,
formats,
slots,
quality: options.quality as number,
Expand All @@ -1478,13 +1482,14 @@ program
})
.option('--slots <slots>', 'Texture slots to include (glob)', { validator: Validator.STRING, default: '*' })
.option('--quality <quality>', 'Quality, 1-100', { validator: Validator.NUMBER })
.action(({ args, options, logger }) => {
.action(async ({ args, options, logger }) => {
const formats = micromatch.makeRe(String(options.formats), MICROMATCH_OPTIONS);
const slots = micromatch.makeRe(String(options.slots), MICROMATCH_OPTIONS);
const { default: encoder } = await import('sharp');
return Session.create(io, logger, args.input, args.output).transform(
textureCompress({
targetFormat: 'jpeg',
encoder: sharp,
encoder,
formats,
slots,
quality: options.quality as number,
Expand Down
30 changes: 14 additions & 16 deletions packages/cli/src/validate.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import fs from 'fs';
import path from 'path';
import validator from 'gltf-validator';
import fs from 'node:fs/promises';
import path from 'node:path';
import type { ILogger } from '@gltf-transform/core';
import { formatHeader, formatTable, TableFormat } from './util.js';

Expand All @@ -18,20 +17,19 @@ interface ValidatorMessage {
severity: number;
}

export function validate(input: string, options: ValidateOptions, logger: ILogger): void {
const buffer = fs.readFileSync(input);
export async function validate(input: string, options: ValidateOptions, logger: ILogger): Promise<void> {
const [buffer, validator] = await Promise.all([fs.readFile(input), import('gltf-validator')]);
return validator
.validateBytes(new Uint8Array(buffer), {
maxIssues: options.limit,
ignoredIssues: options.ignore,
externalResourceFunction: (uri: string) =>
new Promise((resolve, reject) => {
uri = path.resolve(path.dirname(input), decodeURIComponent(uri));
fs.readFile(uri, (err, data) => {
if (err) logger.warn(`Unable to validate "${uri}": ${err.toString()}.`);
err ? reject(err.toString()) : resolve(data);
});
}),
externalResourceFunction: (uri: string) => {
uri = path.resolve(path.dirname(input), decodeURIComponent(uri));
return fs.readFile(uri).catch((err) => {
logger.warn(`Unable to validate "${uri}": ${err.toString()}.`);
throw err.toString();
});
},
})
.then(async (report: ValidatorReport) => {
await printIssueSection('error', 0, report, logger, options.format);
Expand All @@ -46,7 +44,7 @@ async function printIssueSection(
severity: number,
report: ValidatorReport,
logger: ILogger,
format: TableFormat
format: TableFormat,
): Promise<void> {
console.log(formatHeader(header));
const messages = report.issues.messages.filter((msg) => msg.severity === severity);
Expand All @@ -55,8 +53,8 @@ async function printIssueSection(
(await formatTable(
format,
['code', 'message', 'severity', 'pointer'],
messages.map((m) => Object.values(m))
)) + '\n\n'
messages.map((m) => Object.values(m)),
)) + '\n\n',
);
} else {
logger.info(`No ${header}s found.`);
Expand Down

0 comments on commit cc8bfba

Please sign in to comment.