1 | import * as fs from 'fs';
|
2 | import { basename, dirname, join } from 'path';
|
3 | import { promisify } from 'util';
|
4 | import { gzip } from 'zlib';
|
5 | import { VERSION, } from 'rollup';
|
6 | const readFile = promisify(fs.readFile);
|
7 | const writeFile = promisify(fs.writeFile);
|
8 | const gzipPromise = promisify(gzip);
|
9 | const isFunction = (arg) => typeof arg === 'function';
|
10 | const isRegExp = (arg) => Object.prototype.toString.call(arg) === '[object RegExp]';
|
11 |
|
12 |
|
13 |
|
14 |
|
15 | function isOutputChunk(file) {
|
16 | return typeof file.code === 'string';
|
17 | }
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 | function 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 |
|
36 | const sourceMapComment = `//# source` + `MappingURL=${url}\n`;
|
37 |
|
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 | :
|
48 | Buffer.from(outputFile.source);
|
49 | }
|
50 | }
|
51 |
|
52 | function 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 |
|
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 | }
|
72 | function gzipPlugin(explicitOptions = {}) {
|
73 | performInitChecks(explicitOptions);
|
74 | const options = {
|
75 |
|
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 |
|
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 |
|
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 |
|
137 | setTimeout(() => options.additionalFiles.map(compressAdditionalFile), options.additionalFilesDelay);
|
138 | }
|
139 | await Promise.all(promises);
|
140 | },
|
141 |
|
142 | ...{
|
143 | apply: 'build',
|
144 | enforce: 'post',
|
145 | },
|
146 | };
|
147 | return plugin;
|
148 | }
|
149 | export default gzipPlugin;
|