UNPKG

6.3 kBJavaScriptView Raw
1import * as fs from 'fs';
2import { basename, dirname, join } from 'path';
3import { promisify } from 'util';
4import { gzip } from 'zlib';
5import { VERSION, } from 'rollup';
6const readFile = promisify(fs.readFile);
7const writeFile = promisify(fs.writeFile);
8const gzipPromise = promisify(gzip);
9const isFunction = (arg) => typeof arg === 'function';
10const isRegExp = (arg) => Object.prototype.toString.call(arg) === '[object RegExp]';
11// functionality partially copied from rollup
12/**
13 * copied from https://github.com/rollup/rollup/blob/master/src/rollup/index.ts#L450
14 */
15function isOutputChunk(file) {
16 return typeof file.code === 'string';
17}
18/**
19 * Gets the string/buffer content from a file object.
20 * Important for adding source map comments
21 *
22 * Copied partially from rollup.writeOutputFile
23 * https://github.com/rollup/rollup/blob/master/src/rollup/index.ts#L454
24 */
25function getOutputFileContent(outputFileName, outputFile, outputOptions) {
26 if (isOutputChunk(outputFile)) {
27 let source;
28 source = outputFile.code;
29 if ((outputOptions.sourcemap === true ||
30 outputOptions.sourcemap === 'inline') &&
31 outputFile.map) {
32 const url = outputOptions.sourcemap === 'inline'
33 ? outputFile.map.toUrl()
34 : `${basename(outputFileName)}.map`;
35 // https://github.com/rollup/rollup/blob/master/src/utils/sourceMappingURL.ts#L1
36 const sourceMapComment = `//# source` + `MappingURL=${url}\n`;
37 // Rollup >= 3.0.0 already includes the comment, older versions do not
38 if (!source.includes(sourceMapComment)) {
39 source += sourceMapComment;
40 }
41 }
42 return source;
43 }
44 else {
45 return typeof outputFile.source === 'string'
46 ? outputFile.source
47 : // just to be sure, as it is typed string | Uint8Array in rollup 2.0.0
48 Buffer.from(outputFile.source);
49 }
50}
51// actual plugin code
52function performInitChecks(options) {
53 if (VERSION < '2.0.0') {
54 console.error('[rollup-plugin-gzip] This plugin supports rollup version >= 2.0.0!');
55 console.error('For older rollup versions, please use an older version of this plugin.');
56 }
57 // check for old options
58 if ('algorithm' in options) {
59 console.warn('[rollup-plugin-gzip] The "algorithm" option is not supported any more! ' +
60 'Use "customCompression" instead to specify a different compression algorithm.');
61 }
62 if ('options' in options) {
63 console.warn('[rollup-plugin-gzip] The "options" option was renamed to "gzipOptions"!');
64 }
65 if ('additional' in options) {
66 console.warn('[rollup-plugin-gzip] The "additional" option was renamed to "additionalFiles"!');
67 }
68 if ('delay' in options) {
69 console.warn('[rollup-plugin-gzip] The "delay" option was renamed to "additionalFilesDelay"!');
70 }
71}
72function gzipPlugin(explicitOptions = {}) {
73 performInitChecks(explicitOptions);
74 const options = {
75 // default options
76 filter: /\.(js|mjs|cjs|json|css|html|wasm|svg)$/,
77 fileName: '.gz',
78 customCompression: (fileContent) => gzipPromise(fileContent, options.gzipOptions),
79 gzipOptions: {},
80 additionalFiles: [],
81 additionalFilesDelay: 0,
82 minSize: 0,
83 ...explicitOptions,
84 };
85 const mapFileName = isFunction(options.fileName)
86 ? options.fileName
87 : (fileName) => fileName + options.fileName;
88 const plugin = {
89 name: 'gzip',
90 async writeBundle(outputOptions, bundle) {
91 const outputDir = outputOptions.file
92 ? dirname(outputOptions.file)
93 : outputOptions.dir || '';
94 const compressBundleFile = async (fileName) => {
95 const fileEntry = bundle[fileName];
96 // filter check
97 if (isRegExp(options.filter) && !fileName.match(options.filter)) {
98 return Promise.resolve();
99 }
100 if (isFunction(options.filter) &&
101 !options.filter(fileName)) {
102 return Promise.resolve();
103 }
104 const fileContent = getOutputFileContent(fileName, fileEntry, outputOptions);
105 // minSize option check
106 if (options.minSize && options.minSize > fileContent.length) {
107 return Promise.resolve();
108 }
109 try {
110 await writeFile(join(outputDir, mapFileName(fileName)), await options.customCompression(fileContent));
111 }
112 catch (error) {
113 console.error(error);
114 return Promise.reject('[rollup-plugin-gzip] Error compressing file ' + fileName);
115 }
116 };
117 const compressAdditionalFile = async (filePath) => {
118 try {
119 const fileContent = await readFile(filePath);
120 await writeFile(mapFileName(filePath), await options.customCompression(fileContent));
121 return Promise.resolve();
122 }
123 catch (error) {
124 console.error(error);
125 return Promise.reject('[rollup-plugin-gzip] Error compressing additional file ' +
126 filePath +
127 '. Please check the spelling of your configured additionalFiles. ' +
128 'You might also have to increase the value of the additionalFilesDelay option.');
129 }
130 };
131 const promises = Object.keys(bundle).map(compressBundleFile);
132 if (!options.additionalFilesDelay) {
133 promises.push(...options.additionalFiles.map(compressAdditionalFile));
134 }
135 else {
136 // if a delay is set, we do not await the compression of additional files
137 setTimeout(() => options.additionalFiles.map(compressAdditionalFile), options.additionalFilesDelay);
138 }
139 await Promise.all(promises);
140 },
141 // vite options
142 ...{
143 apply: 'build',
144 enforce: 'post',
145 },
146 };
147 return plugin;
148}
149export default gzipPlugin;