Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow sirv to looks for precompiled gzip and brotli files by default #1672

Merged
merged 2 commits into from Jun 11, 2021
Merged

Allow sirv to looks for precompiled gzip and brotli files by default #1672

merged 2 commits into from Jun 11, 2021

Conversation

istarkov
Copy link
Contributor

@istarkov istarkov commented Jun 11, 2021

This should not change anyting for users who doesnt use brotli or gzip precompiled asset files. But brotli gives real advantages over gzip in compression size.

In absense of sirv config, probably it can be a good default.

For compressing we use following script.

import * as zlib from 'zlib';
import { pipeline } from 'stream';
import { promisify } from 'util';

import * as fs from 'fs';
import { totalist } from 'totalist/sync/index.js';
import yargs from 'yargs';

const supportedAlgs = ['gz', 'br'];

const argv = yargs(process.argv.slice(2))
  .describe('alg', 'Compression algorithm gz or br')
  .choices('alg', supportedAlgs)
  .describe('dir', 'Directory to compress files')
  .string('dir')
  .array('ext')
  .default('ext', ['js', 'css', 'json', 'svg'])
  .demandOption(['alg', 'dir'], 'alg and dir must be provided')
  .check(argv => {
    if (!fs.statSync(argv.dir).isDirectory()) {
      throw new Error(`"${argv.dir}" is not directory`);
    }

    return true; // tell Yargs that the arguments passed the check
  })
  .example([
    ['$0 --alg br --dir .build/assets', 'Use brotli compression'],
    ['$0 --alg gz --dir .build/assets', 'Use gz compression'],
    [
      '$0 --alg gz --dir .build/assets --ext css json',
      'Use gz compression for files with css and json extensions',
    ],
  ]).argv;

const files: string[] = [];

if (!('dir' in argv)) {
  throw new Error('argv is a promise');
}

totalist(argv.dir, (_, abs) => {
  files.push(abs);
});

const pipe = promisify(pipeline);

const compress = async () => {
  const sizes = [];
  for (const file of files) {
    if (
      argv.ext.some(ext => file.endsWith(`.${ext}`)) &&
      !supportedAlgs.some(alg => file.endsWith(`.${alg}`))
    ) {
      const destFile = `${file}.${argv.alg}`;
      const compressionMethod =
        argv.alg === 'gz' ? zlib.createGzip() : zlib.createBrotliCompress();
      const source = fs.createReadStream(file);
      const destination = fs.createWriteStream(destFile);
      await pipe(source, compressionMethod, destination);
      const inSize = Math.round((100 * fs.statSync(file).size) / 1024) / 100;
      const outSize =
        Math.round((100 * fs.statSync(destFile).size) / 1024) / 100;

      sizes.push({ inSize, outSize, file });
    }
  }

  console.table(sizes);
};

compress().then(() => null);

@benmccann benmccann requested a review from lukeed June 11, 2021 15:24
Copy link
Member

@lukeed lukeed left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically this means sirv is doing more checks on every request (< 1ms) but that's totally fine 😆 If this part of the app were ever to be exposed to the config layer, it'd be a good thing to expose (with some forced SK overrides)

@benmccann
Copy link
Member

@istarkov can you add a patch changeset so that this PR can be merged and released? (pnpx changeset)

@benmccann
Copy link
Member

benmccann commented Jun 11, 2021

I'm curious if there's any Vite or Rollup plugin that you could use rather than a custom script

@istarkov
Copy link
Contributor Author

I'm curious if there's any Vite or Rollup plugin that you could use rather than a custom script

Yes some plugins exists https://www.npmjs.com/package/rollup-plugin-brotli and same for gzip,
custom script just allows to use it not only for build assets and for other things too.

@benmccann benmccann merged commit 9a7195b into sveltejs:master Jun 11, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants