vite-plugin-singlefile-compression 2.1.2 → 2.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +107 -82
- package/dist/index.d.ts +6 -6
- package/dist/index.js +21 -14
- package/package.json +39 -6
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@ Preview: https://bddjr.github.io/vite-plugin-singlefile-compression/
|
|
|
11
11
|
## Setup
|
|
12
12
|
|
|
13
13
|
```
|
|
14
|
-
npm i vite-plugin-singlefile-compression@latest
|
|
14
|
+
npm i -D vite-plugin-singlefile-compression@latest
|
|
15
15
|
```
|
|
16
16
|
|
|
17
17
|
Then modify `vite.config.ts`, like [test/vite.config.ts](test/vite.config.ts)
|
|
@@ -45,103 +45,128 @@ singleFileCompression({
|
|
|
45
45
|
}),
|
|
46
46
|
```
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
### rename
|
|
49
|
+
|
|
50
|
+
Rename index.html
|
|
51
|
+
|
|
52
|
+
type: `string`
|
|
53
|
+
|
|
54
|
+
### enableCompress
|
|
55
|
+
|
|
56
|
+
Enable compress.
|
|
57
|
+
|
|
58
|
+
default: `true`
|
|
59
|
+
|
|
60
|
+
type: `boolean`
|
|
61
|
+
|
|
62
|
+
### useBase128
|
|
63
|
+
|
|
64
|
+
Use Base128 to encode compressed script.
|
|
65
|
+
If false, use Base64.
|
|
66
|
+
https://www.npmjs.com/package/base128-ascii
|
|
67
|
+
|
|
68
|
+
default: `true`
|
|
69
|
+
|
|
70
|
+
type: `boolean`
|
|
71
|
+
|
|
72
|
+
### compressFormat
|
|
73
|
+
|
|
74
|
+
Compress format.
|
|
75
|
+
|
|
76
|
+
https://developer.mozilla.org/en-US/docs/Web/API/DecompressionStream/DecompressionStream
|
|
77
|
+
|
|
78
|
+
default: `"deflate-raw"`
|
|
79
|
+
|
|
80
|
+
type:
|
|
81
|
+
- `"deflate-raw"`
|
|
82
|
+
- `"deflate"`
|
|
83
|
+
- `"gzip"`
|
|
84
|
+
- `"brotli"`
|
|
85
|
+
- `"zstd"`
|
|
86
|
+
- `"deflateRaw"`
|
|
87
|
+
- `"gz"`
|
|
88
|
+
- `"br"`
|
|
89
|
+
- `"brotliCompress"`
|
|
90
|
+
- `"zstandard"`
|
|
91
|
+
- `"zst"`
|
|
92
|
+
|
|
93
|
+
### compressor
|
|
94
|
+
|
|
95
|
+
Custom compressor.
|
|
96
|
+
|
|
97
|
+
type: `(buf: zlib.InputType) => (Buffer | Uint8Array | Promise<Buffer | Uint8Array>)`
|
|
98
|
+
|
|
99
|
+
### htmlMinifierTerser
|
|
100
|
+
|
|
101
|
+
https://github.com/terser/html-minifier-terser?tab=readme-ov-file#options-quick-reference
|
|
102
|
+
|
|
103
|
+
default: `defaultHtmlMinifierTerserOptions`
|
|
104
|
+
|
|
105
|
+
type:
|
|
106
|
+
- `HtmlMinifierOptions`
|
|
107
|
+
- `boolean`
|
|
108
|
+
|
|
109
|
+
### tryInlineHtmlAssets
|
|
110
|
+
|
|
111
|
+
Try inline html used assets, if inlined or not used in JS.
|
|
112
|
+
|
|
113
|
+
default: `true`
|
|
114
|
+
|
|
115
|
+
type: `boolean`
|
|
116
|
+
|
|
117
|
+
### removeInlinedAssetFiles
|
|
118
|
+
|
|
119
|
+
Remove inlined asset files.
|
|
120
|
+
|
|
121
|
+
default: `true`
|
|
122
|
+
|
|
123
|
+
type: `boolean`
|
|
124
|
+
|
|
125
|
+
### tryInlineHtmlPublicIcon
|
|
126
|
+
|
|
127
|
+
Try inline html icon, if icon is in public dir.
|
|
128
|
+
|
|
129
|
+
default: `true`
|
|
130
|
+
|
|
131
|
+
type: `boolean`
|
|
132
|
+
|
|
133
|
+
### removeInlinedPublicIconFiles
|
|
134
|
+
|
|
135
|
+
Remove inlined html icon files.
|
|
136
|
+
|
|
137
|
+
default: `true`
|
|
138
|
+
|
|
139
|
+
type: `boolean`
|
|
140
|
+
|
|
141
|
+
### useImportMetaPolyfill
|
|
142
|
+
|
|
143
|
+
Use import.meta polyfill.
|
|
144
|
+
|
|
145
|
+
default: `true`
|
|
146
|
+
|
|
147
|
+
type: `boolean`
|
|
49
148
|
|
|
50
|
-
```ts
|
|
51
|
-
export interface Options {
|
|
52
|
-
/**
|
|
53
|
-
* Enable compress.
|
|
54
|
-
* @default true
|
|
55
|
-
*/
|
|
56
|
-
enableCompress?: boolean
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Use Base128 to encode compressed script.
|
|
60
|
-
* If false, use Base64.
|
|
61
|
-
* https://www.npmjs.com/package/base128-ascii
|
|
62
|
-
* @default true
|
|
63
|
-
*/
|
|
64
|
-
useBase128?: boolean
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Compress format.
|
|
68
|
-
*
|
|
69
|
-
* https://developer.mozilla.org/en-US/docs/Web/API/DecompressionStream/DecompressionStream
|
|
70
|
-
*
|
|
71
|
-
* @type {"deflate-raw" | "deflate" | "gzip" | "brotli" | "zstd" | "deflateRaw" | "gz" | "br" | "brotliCompress" | "zstandard" | "zst"}
|
|
72
|
-
*
|
|
73
|
-
* @default "deflate-raw"
|
|
74
|
-
*/
|
|
75
|
-
compressFormat?: CompressFormat | CompressFormatAlias
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Custom compressor.
|
|
79
|
-
*/
|
|
80
|
-
compressor?: Compressor
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* Rename index.html
|
|
84
|
-
*/
|
|
85
|
-
rename?: string
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* https://github.com/terser/html-minifier-terser?tab=readme-ov-file#options-quick-reference
|
|
89
|
-
* @default defaultHtmlMinifierTerserOptions
|
|
90
|
-
*/
|
|
91
|
-
htmlMinifierTerser?: HtmlMinifierOptions | boolean
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* Try inline html used assets, if inlined or not used in JS.
|
|
95
|
-
* @default true
|
|
96
|
-
*/
|
|
97
|
-
tryInlineHtmlAssets?: boolean
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Remove inlined asset files.
|
|
101
|
-
* @default true
|
|
102
|
-
*/
|
|
103
|
-
removeInlinedAssetFiles?: boolean
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Try inline html icon, if icon is in public dir.
|
|
107
|
-
* @default true
|
|
108
|
-
*/
|
|
109
|
-
tryInlineHtmlPublicIcon?: boolean
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* Remove inlined html icon files.
|
|
113
|
-
* @default true
|
|
114
|
-
*/
|
|
115
|
-
removeInlinedPublicIconFiles?: boolean
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* Use import.meta polyfill.
|
|
119
|
-
* @default true
|
|
120
|
-
*/
|
|
121
|
-
useImportMetaPolyfill?: boolean
|
|
122
|
-
}
|
|
123
|
-
```
|
|
124
149
|
|
|
125
150
|
## Effect
|
|
126
151
|
|
|
127
152
|
Preview: https://bddjr.github.io/vite-plugin-singlefile-compression/
|
|
128
153
|
|
|
129
154
|
```
|
|
130
|
-
vite v8.0.
|
|
155
|
+
vite v8.0.3 building client environment for production...
|
|
131
156
|
✓ 42 modules transformed.
|
|
132
157
|
rendering chunks (1)...
|
|
133
158
|
|
|
134
|
-
vite-plugin-singlefile-compression 2.1
|
|
159
|
+
vite-plugin-singlefile-compression 2.2.1 deflate-raw base128-ascii
|
|
135
160
|
|
|
136
161
|
file:///D:/code/js/vite-plugin-singlefile-compression/test/dist/index.html
|
|
137
|
-
|
|
162
|
+
122.739 kB -> 50.220 kB
|
|
138
163
|
|
|
139
164
|
Finish.
|
|
140
165
|
|
|
141
166
|
computing gzip size...
|
|
142
|
-
dist/index.html 50.
|
|
167
|
+
dist/index.html 50.22 kB │ gzip: 43.77 kB
|
|
143
168
|
|
|
144
|
-
✓ built in
|
|
169
|
+
✓ built in 461ms
|
|
145
170
|
```
|
|
146
171
|
|
|
147
172
|
## Clone
|
|
@@ -153,5 +178,5 @@ npm i
|
|
|
153
178
|
cd test
|
|
154
179
|
npm i
|
|
155
180
|
cd ..
|
|
156
|
-
|
|
181
|
+
npm run build
|
|
157
182
|
```
|
package/dist/index.d.ts
CHANGED
|
@@ -18,12 +18,16 @@ declare const compressFormatAlias: Readonly<{
|
|
|
18
18
|
zstandard: "zstd";
|
|
19
19
|
zst: "zstd";
|
|
20
20
|
}>;
|
|
21
|
-
type Compressor = ((buf: zlib.InputType) => (Buffer | Uint8Array));
|
|
22
|
-
type CompressFormat = keyof typeof compressors;
|
|
21
|
+
type Compressor = ((buf: zlib.InputType) => (Buffer | Uint8Array | Promise<Buffer | Uint8Array>));
|
|
22
|
+
type CompressFormat = keyof typeof compressors | CompressionFormat;
|
|
23
23
|
type CompressFormatAlias = keyof typeof compressFormatAlias;
|
|
24
24
|
//#endregion
|
|
25
25
|
//#region _dist/options.d.ts
|
|
26
26
|
interface Options {
|
|
27
|
+
/**
|
|
28
|
+
* Rename index.html
|
|
29
|
+
*/
|
|
30
|
+
rename?: string;
|
|
27
31
|
/**
|
|
28
32
|
* Enable compress.
|
|
29
33
|
* @default true
|
|
@@ -50,10 +54,6 @@ interface Options {
|
|
|
50
54
|
* Custom compressor.
|
|
51
55
|
*/
|
|
52
56
|
compressor?: Compressor;
|
|
53
|
-
/**
|
|
54
|
-
* Rename index.html
|
|
55
|
-
*/
|
|
56
|
-
rename?: string;
|
|
57
57
|
/**
|
|
58
58
|
* https://github.com/terser/html-minifier-terser?tab=readme-ov-file#options-quick-reference
|
|
59
59
|
* @default defaultHtmlMinifierTerserOptions
|
package/dist/index.js
CHANGED
|
@@ -9,7 +9,7 @@ import zlib from "zlib";
|
|
|
9
9
|
import svgToTinyDataUri from "mini-svg-data-uri";
|
|
10
10
|
import mime from "mime";
|
|
11
11
|
//#region _dist/getVersion.js
|
|
12
|
-
var version = "2.1
|
|
12
|
+
var version = "2.2.1";
|
|
13
13
|
//#endregion
|
|
14
14
|
//#region _dist/compress.js
|
|
15
15
|
const compressors = {
|
|
@@ -46,11 +46,18 @@ function switchCompressor(format) {
|
|
|
46
46
|
if (typeof f == "function") return f;
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
|
+
try {
|
|
50
|
+
const cs = new CompressionStream(format);
|
|
51
|
+
return (buf) => new Response(new ReadableStream({ start(controller) {
|
|
52
|
+
controller.enqueue(buf);
|
|
53
|
+
controller.close();
|
|
54
|
+
} }).pipeThrough(cs)).bytes();
|
|
55
|
+
} catch {}
|
|
49
56
|
throw Error(`Could not get compressor: Unknown compress format '${format}', please set your compressor function.`);
|
|
50
57
|
}
|
|
51
|
-
function compress(format, buf, useBase128, compressor) {
|
|
58
|
+
async function compress(format, buf, useBase128, compressor) {
|
|
52
59
|
if (typeof compressor != "function") compressor = switchCompressor(format);
|
|
53
|
-
const outBuf = compressor(buf);
|
|
60
|
+
const outBuf = await compressor(buf);
|
|
54
61
|
if (useBase128) return base128.encode(outBuf).toJSTemplateLiterals();
|
|
55
62
|
if (Buffer.isBuffer(outBuf)) return outBuf.toString("base64");
|
|
56
63
|
if (typeof outBuf.toBase64 == "function") return outBuf.toBase64();
|
|
@@ -82,8 +89,8 @@ const files = {
|
|
|
82
89
|
importmeta: split2(raw.importmeta, "\"<path>\"")
|
|
83
90
|
};
|
|
84
91
|
const template = {
|
|
85
|
-
base(script, format, useBase128, compressor) {
|
|
86
|
-
script = compress(format, script, useBase128, compressor);
|
|
92
|
+
async base(script, format, useBase128, compressor) {
|
|
93
|
+
script = await compress(format, script, useBase128, compressor);
|
|
87
94
|
if (useBase128) return files.base128.replace("<format>", format).split("\"<script>\"", 2).join(script);
|
|
88
95
|
return files.base64.replace("<format>", format).split("<script>", 2).join(script);
|
|
89
96
|
},
|
|
@@ -124,16 +131,16 @@ const defaultHtmlMinifierTerserOptions = {
|
|
|
124
131
|
function getInnerOptions(opt) {
|
|
125
132
|
opt ||= {};
|
|
126
133
|
return {
|
|
127
|
-
enableCompress: opt.enableCompress ?? true,
|
|
128
134
|
rename: opt.rename == null ? void 0 : String(opt.rename),
|
|
135
|
+
enableCompress: opt.enableCompress ?? true,
|
|
136
|
+
useBase128: opt.useBase128 ?? true,
|
|
137
|
+
compressFormat: opt.compressFormat ? compressFormatAlias.hasOwnProperty(opt.compressFormat) ? compressFormatAlias[opt.compressFormat] : String(opt.compressFormat) : "deflate-raw",
|
|
138
|
+
compressor: typeof opt.compressor == "function" ? opt.compressor : void 0,
|
|
129
139
|
htmlMinifierTerser: opt.htmlMinifierTerser == null || opt.htmlMinifierTerser === true ? defaultHtmlMinifierTerserOptions : opt.htmlMinifierTerser,
|
|
130
140
|
tryInlineHtmlAssets: opt.tryInlineHtmlAssets ?? true,
|
|
131
141
|
removeInlinedAssetFiles: opt.removeInlinedAssetFiles ?? true,
|
|
132
142
|
tryInlineHtmlPublicIcon: opt.tryInlineHtmlPublicIcon ?? true,
|
|
133
143
|
removeInlinedPublicIconFiles: opt.removeInlinedPublicIconFiles ?? true,
|
|
134
|
-
useBase128: opt.useBase128 ?? true,
|
|
135
|
-
compressFormat: opt.compressFormat ? compressFormatAlias.hasOwnProperty(opt.compressFormat) ? compressFormatAlias[opt.compressFormat] : String(opt.compressFormat) : "deflate-raw",
|
|
136
|
-
compressor: typeof opt.compressor == "function" ? opt.compressor : void 0,
|
|
137
144
|
useImportMetaPolyfill: opt.useImportMetaPolyfill ?? true
|
|
138
145
|
};
|
|
139
146
|
}
|
|
@@ -148,7 +155,7 @@ function singleFileCompression(opt) {
|
|
|
148
155
|
let conf;
|
|
149
156
|
const innerOptions = getInnerOptions(opt);
|
|
150
157
|
return {
|
|
151
|
-
name: "
|
|
158
|
+
name: "vite-plugin-singlefile-compression",
|
|
152
159
|
enforce: "post",
|
|
153
160
|
config(...args) {
|
|
154
161
|
return setConfig.call(this, innerOptions, ...args);
|
|
@@ -156,8 +163,8 @@ function singleFileCompression(opt) {
|
|
|
156
163
|
configResolved(c) {
|
|
157
164
|
conf = c;
|
|
158
165
|
},
|
|
159
|
-
generateBundle(outputOptions, bundle) {
|
|
160
|
-
return generateBundle(bundle, conf, innerOptions);
|
|
166
|
+
generateBundle(outputOptions, bundle, isWrite) {
|
|
167
|
+
return generateBundle.call(this, bundle, conf, innerOptions);
|
|
161
168
|
}
|
|
162
169
|
};
|
|
163
170
|
}
|
|
@@ -298,7 +305,7 @@ async function generateBundle(bundle, config, options) {
|
|
|
298
305
|
newJSCode.push(code);
|
|
299
306
|
} else inlineHtmlAssets();
|
|
300
307
|
let outputScript = newJSCode.join(";");
|
|
301
|
-
if (options.enableCompress) outputScript = template.base(outputScript, options.compressFormat, options.useBase128, options.compressor);
|
|
308
|
+
if (options.enableCompress) outputScript = await template.base(outputScript, options.compressFormat, options.useBase128, options.compressor);
|
|
302
309
|
else outputScript = outputScript.replaceAll("<\/script", "<\\/script");
|
|
303
310
|
htmlChunk.source = htmlChunk.source.split(fakeScript, 2).join(outputScript);
|
|
304
311
|
console.log(" " + pc.gray(kB(oldSize) + " -> ") + pc.cyanBright(kB(htmlChunk.source.length)) + "\n");
|
|
@@ -308,7 +315,7 @@ async function generateBundle(bundle, config, options) {
|
|
|
308
315
|
for (const name of globalDelete) if (!globalDoNotDelete.has(name)) delete bundle[name];
|
|
309
316
|
}
|
|
310
317
|
if (options.removeInlinedPublicIconFiles) for (const name of globalRemoveDistFileNames) try {
|
|
311
|
-
fs.
|
|
318
|
+
fs.rmSync(path.join(config.build.outDir, name), { force: true });
|
|
312
319
|
} catch (e) {
|
|
313
320
|
console.error(e);
|
|
314
321
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vite-plugin-singlefile-compression",
|
|
3
|
-
"version": "2.1
|
|
3
|
+
"version": "2.2.1",
|
|
4
4
|
"author": "bddjr",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "Compress all assets and embeds them into dist/index.html, making it convenient to share as a single HTML file.",
|
|
@@ -31,10 +31,33 @@
|
|
|
31
31
|
"single",
|
|
32
32
|
"compression",
|
|
33
33
|
"compress",
|
|
34
|
+
"compressionstream",
|
|
35
|
+
"decompres",
|
|
36
|
+
"decompression",
|
|
37
|
+
"decompressionstream",
|
|
38
|
+
"compression streams api",
|
|
39
|
+
"compression streams",
|
|
34
40
|
"gzip",
|
|
41
|
+
"deflate",
|
|
42
|
+
"deflate-raw",
|
|
43
|
+
"deflateraw",
|
|
44
|
+
"br",
|
|
45
|
+
"brotli",
|
|
46
|
+
"zstd",
|
|
47
|
+
"zlib",
|
|
35
48
|
"inline",
|
|
49
|
+
"embed",
|
|
50
|
+
"bundle",
|
|
51
|
+
"bundler",
|
|
36
52
|
"frontend",
|
|
37
53
|
"front-end",
|
|
54
|
+
"framework",
|
|
55
|
+
"hmr",
|
|
56
|
+
"dev-server",
|
|
57
|
+
"build-tool",
|
|
58
|
+
"html",
|
|
59
|
+
"htm",
|
|
60
|
+
"htmlmin",
|
|
38
61
|
"js",
|
|
39
62
|
"javascript",
|
|
40
63
|
"css",
|
|
@@ -42,12 +65,22 @@
|
|
|
42
65
|
"rolldown",
|
|
43
66
|
"rolldown-vite",
|
|
44
67
|
"rollup",
|
|
68
|
+
"min",
|
|
69
|
+
"minification",
|
|
70
|
+
"minifier",
|
|
71
|
+
"minify",
|
|
72
|
+
"optimize",
|
|
73
|
+
"optimizer",
|
|
74
|
+
"pack",
|
|
75
|
+
"packer",
|
|
45
76
|
"vite-plugin-singlefile",
|
|
46
77
|
"vite-plugin-compression",
|
|
47
|
-
"vite-plugin-compression2"
|
|
78
|
+
"vite-plugin-compression2",
|
|
79
|
+
"html-minifier-terser"
|
|
48
80
|
],
|
|
49
81
|
"dependencies": {
|
|
50
82
|
"@types/html-minifier-terser": ">=7.0.2",
|
|
83
|
+
"@types/node": "*",
|
|
51
84
|
"base128-ascii": ">=2.1.11",
|
|
52
85
|
"html-minifier-terser": ">=7.2.0",
|
|
53
86
|
"jsdom": ">=28.1.0",
|
|
@@ -57,14 +90,14 @@
|
|
|
57
90
|
"vite": ">=3.0.0"
|
|
58
91
|
},
|
|
59
92
|
"devDependencies": {
|
|
93
|
+
"@bddjr/rimraf": "^0.1.0",
|
|
60
94
|
"@types/jsdom": ">=28.0.0",
|
|
61
95
|
"@types/node": "^22.19.15",
|
|
62
96
|
"esbuild": "^0.27.4",
|
|
63
|
-
"marked": "^17.0.4",
|
|
64
|
-
"rimraf": ">=6.1.3",
|
|
65
97
|
"rolldown": ">=1.0.0-rc.9",
|
|
66
98
|
"rolldown-plugin-dts": "^0.22.5",
|
|
67
99
|
"rollup": ">=4.59.0",
|
|
68
|
-
"typescript": ">=5.9.3"
|
|
100
|
+
"typescript": ">=5.9.3",
|
|
101
|
+
"vite": ">=8.0.0"
|
|
69
102
|
}
|
|
70
|
-
}
|
|
103
|
+
}
|