vite-plugin-rebundle 1.13.0 → 1.14.0
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/dist/rebundle.d.ts +7 -20
- package/dist/rebundle.js +48 -105
- package/package.json +4 -1
- package/src/rebundle.ts +68 -144
package/dist/rebundle.d.ts
CHANGED
|
@@ -1,10 +1,6 @@
|
|
|
1
|
-
import { Unit } from '@eposlabs/utils';
|
|
2
1
|
import { InputOptions, OutputOptions } from 'rolldown';
|
|
3
|
-
import { OutputChunk, OutputBundle } from 'rollup';
|
|
4
2
|
import { Plugin } from 'vite';
|
|
5
3
|
|
|
6
|
-
declare const _code_: unique symbol;
|
|
7
|
-
declare const _sourcemap_: unique symbol;
|
|
8
4
|
type RolldownOptions = {
|
|
9
5
|
input?: InputOptions;
|
|
10
6
|
output?: OutputOptions;
|
|
@@ -12,34 +8,25 @@ type RolldownOptions = {
|
|
|
12
8
|
type BundleOptions = {
|
|
13
9
|
[bundleName: string]: RolldownOptions;
|
|
14
10
|
};
|
|
15
|
-
declare class Rebundle
|
|
16
|
-
private
|
|
11
|
+
declare class Rebundle {
|
|
12
|
+
private commonOptions;
|
|
17
13
|
private bundleOptions;
|
|
18
14
|
private config;
|
|
19
|
-
private
|
|
20
|
-
private
|
|
21
|
-
private hasError;
|
|
15
|
+
private originals;
|
|
16
|
+
private rebundled;
|
|
22
17
|
private port;
|
|
23
18
|
private ws;
|
|
24
|
-
constructor(
|
|
19
|
+
constructor(commonOptions?: RolldownOptions | null, bundleOptions?: BundleOptions);
|
|
25
20
|
get vite(): Plugin;
|
|
26
21
|
private onConfig;
|
|
27
22
|
private onConfigResolved;
|
|
28
|
-
private onBuildEnd;
|
|
29
|
-
private onGenerateBundle;
|
|
30
23
|
private onWriteBundle;
|
|
31
|
-
rebundleChunk(chunk: OutputChunk, bundle: OutputBundle): Promise<boolean | undefined>;
|
|
32
|
-
private readChunkFiles;
|
|
33
|
-
private getChunks;
|
|
34
24
|
private get dist();
|
|
35
|
-
private prefixed;
|
|
36
|
-
private unprefixed;
|
|
37
|
-
private readFromDist;
|
|
38
25
|
private removeFromDist;
|
|
39
26
|
private ensureWs;
|
|
40
27
|
private removeDirectoryIfEmpty;
|
|
41
28
|
private merge;
|
|
42
29
|
}
|
|
43
|
-
declare function rebundle(
|
|
30
|
+
declare function rebundle(commonOptions?: RolldownOptions | null, bundleOptions?: BundleOptions): Plugin<any>;
|
|
44
31
|
|
|
45
|
-
export { type BundleOptions, Rebundle, type RolldownOptions,
|
|
32
|
+
export { type BundleOptions, Rebundle, type RolldownOptions, rebundle as default, rebundle };
|
package/dist/rebundle.js
CHANGED
|
@@ -1,26 +1,22 @@
|
|
|
1
1
|
// src/rebundle.ts
|
|
2
|
-
import {
|
|
2
|
+
import { is, safe } from "@eposlabs/utils";
|
|
3
3
|
import chalk from "chalk";
|
|
4
4
|
import { filesize } from "filesize";
|
|
5
|
-
import { readdir,
|
|
5
|
+
import { readdir, rmdir, stat, unlink, writeFile } from "fs/promises";
|
|
6
6
|
import { dirname, extname, join } from "path";
|
|
7
7
|
import { getPort } from "portfinder";
|
|
8
8
|
import { rolldown } from "rolldown";
|
|
9
9
|
import { WebSocketServer } from "ws";
|
|
10
|
-
var
|
|
11
|
-
|
|
12
|
-
var Rebundle = class extends Unit {
|
|
13
|
-
generalOptions;
|
|
10
|
+
var Rebundle = class {
|
|
11
|
+
commonOptions;
|
|
14
12
|
bundleOptions;
|
|
15
13
|
config = null;
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
hasError = false;
|
|
14
|
+
originals = {};
|
|
15
|
+
rebundled = {};
|
|
19
16
|
port = null;
|
|
20
17
|
ws = null;
|
|
21
|
-
constructor(
|
|
22
|
-
|
|
23
|
-
this.generalOptions = generalOptions ?? {};
|
|
18
|
+
constructor(commonOptions, bundleOptions) {
|
|
19
|
+
this.commonOptions = commonOptions ?? {};
|
|
24
20
|
this.bundleOptions = bundleOptions ?? {};
|
|
25
21
|
}
|
|
26
22
|
get vite() {
|
|
@@ -30,8 +26,6 @@ var Rebundle = class extends Unit {
|
|
|
30
26
|
enforce: "post",
|
|
31
27
|
config: this.onConfig,
|
|
32
28
|
configResolved: this.onConfigResolved,
|
|
33
|
-
buildEnd: this.onBuildEnd,
|
|
34
|
-
generateBundle: this.onGenerateBundle,
|
|
35
29
|
writeBundle: this.onWriteBundle
|
|
36
30
|
};
|
|
37
31
|
}
|
|
@@ -54,110 +48,61 @@ var Rebundle = class extends Unit {
|
|
|
54
48
|
info(message, options);
|
|
55
49
|
};
|
|
56
50
|
};
|
|
57
|
-
onBuildEnd = (error) => {
|
|
58
|
-
this.hasError = !!error;
|
|
59
|
-
};
|
|
60
|
-
onGenerateBundle = async (_options, bundle) => {
|
|
61
|
-
const chunks = this.getChunks(bundle);
|
|
62
|
-
for (const chunk of chunks) {
|
|
63
|
-
if (!chunk.isEntry) continue;
|
|
64
|
-
chunk.fileName = this.prefixed(chunk.fileName);
|
|
65
|
-
}
|
|
66
|
-
};
|
|
67
51
|
onWriteBundle = async (_output, bundle) => {
|
|
68
|
-
if (this.hasError) return;
|
|
69
|
-
if (!this.config) throw this.never;
|
|
70
|
-
const chunks = this.getChunks(bundle);
|
|
71
52
|
const modifiedChunkNames = [];
|
|
72
53
|
await Promise.all(
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
54
|
+
Object.values(bundle).map(async (chunkOrAsset) => {
|
|
55
|
+
const chunk = chunkOrAsset.type === "chunk" && chunkOrAsset.isEntry ? chunkOrAsset : null;
|
|
56
|
+
if (!chunk) return;
|
|
57
|
+
const chunkFilePath = join(this.dist, chunk.fileName);
|
|
58
|
+
const modified = [chunk.fileName, ...chunk.imports].some((name) => {
|
|
59
|
+
return bundle[name].type === "chunk" && bundle[name].code !== this.originals[name];
|
|
60
|
+
});
|
|
61
|
+
if (!modified) {
|
|
62
|
+
await writeFile(chunkFilePath, this.rebundled[chunk.fileName]);
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
const build = await rolldown({
|
|
66
|
+
...this.merge(this.commonOptions.input ?? {}, this.bundleOptions[chunk.name]?.input ?? {}),
|
|
67
|
+
input: chunkFilePath
|
|
68
|
+
});
|
|
69
|
+
const result = await build.write({
|
|
70
|
+
...this.merge(this.commonOptions.output ?? {}, this.bundleOptions[chunk.name]?.output ?? {}),
|
|
71
|
+
sourcemap: false,
|
|
72
|
+
file: chunkFilePath
|
|
73
|
+
});
|
|
74
|
+
const { size } = await stat(join(this.dist, chunk.fileName));
|
|
75
|
+
const _dist_ = chalk.dim(`${this.dist}/`);
|
|
76
|
+
const _fileName_ = chalk.cyan(chunk.fileName);
|
|
77
|
+
const _rebundle_ = chalk.dim.cyan("[rebundle]");
|
|
78
|
+
const _size_ = chalk.bold.dim(`${filesize(size)}`);
|
|
79
|
+
console.log(`${_dist_}${_fileName_} ${_rebundle_} ${_size_}`);
|
|
80
|
+
modifiedChunkNames.push(chunk.name);
|
|
81
|
+
this.rebundled[chunk.fileName] = result.output[0].code;
|
|
77
82
|
})
|
|
78
83
|
);
|
|
79
|
-
for (const
|
|
80
|
-
|
|
81
|
-
|
|
84
|
+
for (const chunkOrAsset of Object.values(bundle)) {
|
|
85
|
+
const chunk = chunkOrAsset.type === "chunk" ? chunkOrAsset : null;
|
|
86
|
+
if (!chunk) continue;
|
|
87
|
+
this.originals[chunk.fileName] = chunk.code;
|
|
82
88
|
delete bundle[chunk.fileName];
|
|
89
|
+
if (!chunk.isEntry) {
|
|
90
|
+
await this.removeFromDist(chunk.fileName);
|
|
91
|
+
}
|
|
83
92
|
}
|
|
93
|
+
if (!this.config) throw "never";
|
|
84
94
|
if (this.config.build.watch && modifiedChunkNames.length > 0) {
|
|
85
95
|
const ws = await this.ensureWs();
|
|
86
96
|
ws.clients.forEach((client) => client.send(JSON.stringify(modifiedChunkNames)));
|
|
87
97
|
}
|
|
88
98
|
};
|
|
89
99
|
// ---------------------------------------------------------------------------
|
|
90
|
-
// CHUNK METHODS
|
|
91
|
-
// ---------------------------------------------------------------------------
|
|
92
|
-
async rebundleChunk(chunk, bundle) {
|
|
93
|
-
if (!this.config) throw this.never;
|
|
94
|
-
delete bundle[chunk.fileName];
|
|
95
|
-
const chunkFiles = await this.readChunkFiles(chunk);
|
|
96
|
-
const chunkFilePaths = Object.keys(chunkFiles);
|
|
97
|
-
const chunkModified = chunkFilePaths.some((path) => chunkFiles[path] !== this.originalFiles[path]);
|
|
98
|
-
Object.assign(this.originalFiles, chunkFiles);
|
|
99
|
-
if (!chunkModified) {
|
|
100
|
-
await this.removeFromDist(chunk.fileName);
|
|
101
|
-
return false;
|
|
102
|
-
}
|
|
103
|
-
const [result] = await safe(async () => {
|
|
104
|
-
const inputPath = join(this.dist, chunk.fileName);
|
|
105
|
-
const outputPath = join(this.dist, this.unprefixed(chunk.fileName));
|
|
106
|
-
const build = await rolldown({
|
|
107
|
-
...this.merge(this.generalOptions.input ?? {}, this.bundleOptions[chunk.name]?.input ?? {}),
|
|
108
|
-
input: inputPath
|
|
109
|
-
});
|
|
110
|
-
const result2 = await build.write({
|
|
111
|
-
...this.merge(this.generalOptions.output ?? {}, this.bundleOptions[chunk.name]?.output ?? {}),
|
|
112
|
-
sourcemap: false,
|
|
113
|
-
file: outputPath
|
|
114
|
-
});
|
|
115
|
-
return result2;
|
|
116
|
-
});
|
|
117
|
-
if (!result) return;
|
|
118
|
-
const { size } = await stat(join(this.dist, this.unprefixed(chunk.fileName)));
|
|
119
|
-
const _dist_ = chalk.dim(`${this.dist}/`);
|
|
120
|
-
const _fileName_ = chalk.cyan(this.unprefixed(chunk.fileName));
|
|
121
|
-
const _rebundle_ = chalk.dim.cyan("[rebundle]");
|
|
122
|
-
const _size_ = chalk.bold.dim(`${filesize(size)}`);
|
|
123
|
-
console.log(`${_dist_}${_fileName_} ${_rebundle_} ${_size_}`);
|
|
124
|
-
const code = result.output[0].code;
|
|
125
|
-
if (!code) throw this.never;
|
|
126
|
-
this.rebundledFiles[chunk.fileName] = code;
|
|
127
|
-
await this.removeFromDist(chunk.fileName);
|
|
128
|
-
return true;
|
|
129
|
-
}
|
|
130
|
-
async readChunkFiles(chunk) {
|
|
131
|
-
const files = {};
|
|
132
|
-
const usedPaths = [chunk.fileName, ...chunk.imports];
|
|
133
|
-
await Promise.all(
|
|
134
|
-
usedPaths.map(async (path) => {
|
|
135
|
-
const content = await this.readFromDist(path);
|
|
136
|
-
files[path] = content ?? "";
|
|
137
|
-
})
|
|
138
|
-
);
|
|
139
|
-
return files;
|
|
140
|
-
}
|
|
141
|
-
getChunks(bundle) {
|
|
142
|
-
return Object.values(bundle).filter((chunkOrAsset) => chunkOrAsset.type === "chunk");
|
|
143
|
-
}
|
|
144
|
-
// ---------------------------------------------------------------------------
|
|
145
100
|
// HELPERS
|
|
146
101
|
// ---------------------------------------------------------------------------
|
|
147
102
|
get dist() {
|
|
148
|
-
if (!this.config) throw
|
|
103
|
+
if (!this.config) throw "never";
|
|
149
104
|
return this.config.build.outDir;
|
|
150
105
|
}
|
|
151
|
-
prefixed(fileName) {
|
|
152
|
-
return `rebundle-original-${fileName}`;
|
|
153
|
-
}
|
|
154
|
-
unprefixed(fileName) {
|
|
155
|
-
return fileName.replace("rebundle-original-", "");
|
|
156
|
-
}
|
|
157
|
-
async readFromDist(path) {
|
|
158
|
-
const [content] = await safe(readFile(join(this.dist, path), "utf-8"));
|
|
159
|
-
return content;
|
|
160
|
-
}
|
|
161
106
|
async removeFromDist(path) {
|
|
162
107
|
path = join(this.dist, path);
|
|
163
108
|
const dir = dirname(path);
|
|
@@ -166,7 +111,7 @@ var Rebundle = class extends Unit {
|
|
|
166
111
|
}
|
|
167
112
|
async ensureWs() {
|
|
168
113
|
if (this.ws) return this.ws;
|
|
169
|
-
if (!this.port) throw
|
|
114
|
+
if (!this.port) throw "never";
|
|
170
115
|
this.ws = new WebSocketServer({ port: this.port });
|
|
171
116
|
return this.ws;
|
|
172
117
|
}
|
|
@@ -188,14 +133,12 @@ var Rebundle = class extends Unit {
|
|
|
188
133
|
return result;
|
|
189
134
|
}
|
|
190
135
|
};
|
|
191
|
-
function rebundle(
|
|
192
|
-
return new Rebundle(
|
|
136
|
+
function rebundle(commonOptions, bundleOptions) {
|
|
137
|
+
return new Rebundle(commonOptions, bundleOptions).vite;
|
|
193
138
|
}
|
|
194
139
|
var rebundle_default = rebundle;
|
|
195
140
|
export {
|
|
196
141
|
Rebundle,
|
|
197
|
-
_code_,
|
|
198
|
-
_sourcemap_,
|
|
199
142
|
rebundle_default as default,
|
|
200
143
|
rebundle
|
|
201
144
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vite-plugin-rebundle",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.14.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "imkost",
|
|
@@ -20,6 +20,9 @@
|
|
|
20
20
|
"source": "./src/rebundle.ts",
|
|
21
21
|
"import": "./dist/rebundle.js",
|
|
22
22
|
"types": "./dist/rebundle.d.ts"
|
|
23
|
+
},
|
|
24
|
+
"./ts": {
|
|
25
|
+
"import": "./src/rebundle.ts"
|
|
23
26
|
}
|
|
24
27
|
},
|
|
25
28
|
"files": [
|
package/src/rebundle.ts
CHANGED
|
@@ -1,17 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { is, safe } from '@eposlabs/utils'
|
|
2
2
|
import chalk from 'chalk'
|
|
3
3
|
import { filesize } from 'filesize'
|
|
4
|
-
import { readdir,
|
|
4
|
+
import { readdir, rmdir, stat, unlink, writeFile } from 'node:fs/promises'
|
|
5
5
|
import { dirname, extname, join } from 'node:path'
|
|
6
6
|
import { getPort } from 'portfinder'
|
|
7
7
|
import { rolldown, type InputOptions, type OutputOptions } from 'rolldown'
|
|
8
|
-
import type { NormalizedOutputOptions, OutputBundle
|
|
8
|
+
import type { NormalizedOutputOptions, OutputBundle } from 'rollup'
|
|
9
9
|
import type { Plugin, ResolvedConfig } from 'vite'
|
|
10
10
|
import { WebSocketServer } from 'ws'
|
|
11
11
|
|
|
12
|
-
export const _code_ = Symbol('rebundle:code')
|
|
13
|
-
export const _sourcemap_ = Symbol('rebundle:sourcemap')
|
|
14
|
-
|
|
15
12
|
export type RolldownOptions = {
|
|
16
13
|
input?: InputOptions
|
|
17
14
|
output?: OutputOptions
|
|
@@ -21,19 +18,17 @@ export type BundleOptions = {
|
|
|
21
18
|
[bundleName: string]: RolldownOptions
|
|
22
19
|
}
|
|
23
20
|
|
|
24
|
-
export class Rebundle
|
|
25
|
-
private
|
|
21
|
+
export class Rebundle {
|
|
22
|
+
private commonOptions: RolldownOptions
|
|
26
23
|
private bundleOptions: BundleOptions
|
|
27
24
|
private config: ResolvedConfig | null = null
|
|
28
|
-
private
|
|
29
|
-
private
|
|
30
|
-
private hasError = false
|
|
25
|
+
private originals: Record<string, string> = {}
|
|
26
|
+
private rebundled: Record<string, string> = {}
|
|
31
27
|
private port: number | null = null
|
|
32
28
|
private ws: WebSocketServer | null = null
|
|
33
29
|
|
|
34
|
-
constructor(
|
|
35
|
-
|
|
36
|
-
this.generalOptions = generalOptions ?? {}
|
|
30
|
+
constructor(commonOptions?: RolldownOptions | null, bundleOptions?: BundleOptions) {
|
|
31
|
+
this.commonOptions = commonOptions ?? {}
|
|
37
32
|
this.bundleOptions = bundleOptions ?? {}
|
|
38
33
|
}
|
|
39
34
|
|
|
@@ -44,8 +39,6 @@ export class Rebundle extends Unit {
|
|
|
44
39
|
enforce: 'post',
|
|
45
40
|
config: this.onConfig,
|
|
46
41
|
configResolved: this.onConfigResolved,
|
|
47
|
-
buildEnd: this.onBuildEnd,
|
|
48
|
-
generateBundle: this.onGenerateBundle,
|
|
49
42
|
writeBundle: this.onWriteBundle,
|
|
50
43
|
}
|
|
51
44
|
}
|
|
@@ -56,7 +49,6 @@ export class Rebundle extends Unit {
|
|
|
56
49
|
|
|
57
50
|
private onConfig = async () => {
|
|
58
51
|
this.port = await getPort({ port: 3100 })
|
|
59
|
-
|
|
60
52
|
return {
|
|
61
53
|
define: { 'import.meta.env.REBUNDLE_PORT': JSON.stringify(this.port) },
|
|
62
54
|
build: { sourcemap: false },
|
|
@@ -76,157 +68,89 @@ export class Rebundle extends Unit {
|
|
|
76
68
|
}
|
|
77
69
|
}
|
|
78
70
|
|
|
79
|
-
private onBuildEnd = (error?: Error) => {
|
|
80
|
-
this.hasError = !!error
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
private onGenerateBundle = async (_options: NormalizedOutputOptions, bundle: OutputBundle) => {
|
|
84
|
-
// Prefix all entry chunks, so Vite writes to temporary files instead of final files
|
|
85
|
-
const chunks = this.getChunks(bundle)
|
|
86
|
-
for (const chunk of chunks) {
|
|
87
|
-
if (!chunk.isEntry) continue
|
|
88
|
-
chunk.fileName = this.prefixed(chunk.fileName)
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
71
|
private onWriteBundle = async (_output: NormalizedOutputOptions, bundle: OutputBundle) => {
|
|
93
|
-
if (this.hasError) return
|
|
94
|
-
if (!this.config) throw this.never
|
|
95
|
-
|
|
96
|
-
const chunks = this.getChunks(bundle)
|
|
97
72
|
const modifiedChunkNames: string[] = []
|
|
98
73
|
|
|
99
74
|
// Rebundle entry chunks
|
|
100
75
|
await Promise.all(
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
const
|
|
104
|
-
if (
|
|
76
|
+
Object.values(bundle).map(async chunkOrAsset => {
|
|
77
|
+
// Only process entry chunks
|
|
78
|
+
const chunk = chunkOrAsset.type === 'chunk' && chunkOrAsset.isEntry ? chunkOrAsset : null
|
|
79
|
+
if (!chunk) return
|
|
80
|
+
const chunkFilePath = join(this.dist, chunk.fileName)
|
|
81
|
+
|
|
82
|
+
// Check if chunk is modified
|
|
83
|
+
const modified = [chunk.fileName, ...chunk.imports].some(name => {
|
|
84
|
+
return bundle[name].type === 'chunk' && bundle[name].code !== this.originals[name]
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
// Not modified? -> Overwrite Vite's output with cached rebundled content
|
|
88
|
+
if (!modified) {
|
|
89
|
+
await writeFile(chunkFilePath, this.rebundled[chunk.fileName])
|
|
90
|
+
return
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Modified? -> Rebundle with rolldown
|
|
94
|
+
const build = await rolldown({
|
|
95
|
+
...this.merge(this.commonOptions.input ?? {}, this.bundleOptions[chunk.name]?.input ?? {}),
|
|
96
|
+
input: chunkFilePath,
|
|
97
|
+
})
|
|
98
|
+
const result = await build.write({
|
|
99
|
+
...this.merge(this.commonOptions.output ?? {}, this.bundleOptions[chunk.name]?.output ?? {}),
|
|
100
|
+
sourcemap: false,
|
|
101
|
+
file: chunkFilePath,
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
// Log successful build
|
|
105
|
+
const { size } = await stat(join(this.dist, chunk.fileName))
|
|
106
|
+
const _dist_ = chalk.dim(`${this.dist}/`)
|
|
107
|
+
const _fileName_ = chalk.cyan(chunk.fileName)
|
|
108
|
+
const _rebundle_ = chalk.dim.cyan('[rebundle]')
|
|
109
|
+
const _size_ = chalk.bold.dim(`${filesize(size)}`)
|
|
110
|
+
console.log(`${_dist_}${_fileName_} ${_rebundle_} ${_size_}`)
|
|
111
|
+
|
|
112
|
+
// Keep track of modified chunks
|
|
113
|
+
modifiedChunkNames.push(chunk.name)
|
|
114
|
+
|
|
115
|
+
// Cache rebundled code
|
|
116
|
+
this.rebundled[chunk.fileName] = result.output[0].code
|
|
105
117
|
}),
|
|
106
118
|
)
|
|
107
119
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
120
|
+
for (const chunkOrAsset of Object.values(bundle)) {
|
|
121
|
+
// Process chunks only
|
|
122
|
+
const chunk = chunkOrAsset.type === 'chunk' ? chunkOrAsset : null
|
|
123
|
+
if (!chunk) continue
|
|
124
|
+
|
|
125
|
+
// Save original chunk code
|
|
126
|
+
this.originals[chunk.fileName] = chunk.code
|
|
111
127
|
|
|
112
|
-
//
|
|
113
|
-
await this.removeFromDist(chunk.fileName)
|
|
128
|
+
// Delete chunk from the `bundle` to hide log for `rolldown-vite`. Call for `rollup` for consistency.
|
|
114
129
|
delete bundle[chunk.fileName]
|
|
130
|
+
|
|
131
|
+
// Non-entry chunk? -> Remove its file
|
|
132
|
+
if (!chunk.isEntry) {
|
|
133
|
+
await this.removeFromDist(chunk.fileName)
|
|
134
|
+
}
|
|
115
135
|
}
|
|
116
136
|
|
|
117
137
|
// Notify about modified chunks
|
|
138
|
+
if (!this.config) throw 'never'
|
|
118
139
|
if (this.config.build.watch && modifiedChunkNames.length > 0) {
|
|
119
140
|
const ws = await this.ensureWs()
|
|
120
141
|
ws.clients.forEach(client => client.send(JSON.stringify(modifiedChunkNames)))
|
|
121
142
|
}
|
|
122
143
|
}
|
|
123
144
|
|
|
124
|
-
// ---------------------------------------------------------------------------
|
|
125
|
-
// CHUNK METHODS
|
|
126
|
-
// ---------------------------------------------------------------------------
|
|
127
|
-
|
|
128
|
-
async rebundleChunk(chunk: OutputChunk, bundle: OutputBundle) {
|
|
129
|
-
if (!this.config) throw this.never
|
|
130
|
-
|
|
131
|
-
// Delete chunk from bundle to hide log for rolldown-vite. Call for rollup for consistency.
|
|
132
|
-
delete bundle[chunk.fileName]
|
|
133
|
-
|
|
134
|
-
// Read chunk files
|
|
135
|
-
const chunkFiles = await this.readChunkFiles(chunk)
|
|
136
|
-
|
|
137
|
-
// Check if some of chunk files were modified
|
|
138
|
-
const chunkFilePaths = Object.keys(chunkFiles)
|
|
139
|
-
const chunkModified = chunkFilePaths.some(path => chunkFiles[path] !== this.originalFiles[path])
|
|
140
|
-
|
|
141
|
-
// Save chunk files content for next comparison
|
|
142
|
-
Object.assign(this.originalFiles, chunkFiles)
|
|
143
|
-
|
|
144
|
-
// Chunk was not modified? -> Don't rebundle, just remove Vite's output
|
|
145
|
-
if (!chunkModified) {
|
|
146
|
-
await this.removeFromDist(chunk.fileName)
|
|
147
|
-
return false
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// Build with rolldown
|
|
151
|
-
const [result] = await safe(async () => {
|
|
152
|
-
const inputPath = join(this.dist, chunk.fileName)
|
|
153
|
-
const outputPath = join(this.dist, this.unprefixed(chunk.fileName))
|
|
154
|
-
|
|
155
|
-
const build = await rolldown({
|
|
156
|
-
...this.merge(this.generalOptions.input ?? {}, this.bundleOptions[chunk.name]?.input ?? {}),
|
|
157
|
-
input: inputPath,
|
|
158
|
-
})
|
|
159
|
-
|
|
160
|
-
const result = await build.write({
|
|
161
|
-
...this.merge(this.generalOptions.output ?? {}, this.bundleOptions[chunk.name]?.output ?? {}),
|
|
162
|
-
sourcemap: false,
|
|
163
|
-
file: outputPath,
|
|
164
|
-
})
|
|
165
|
-
|
|
166
|
-
return result
|
|
167
|
-
})
|
|
168
|
-
if (!result) return
|
|
169
|
-
|
|
170
|
-
// Log successful build
|
|
171
|
-
const { size } = await stat(join(this.dist, this.unprefixed(chunk.fileName)))
|
|
172
|
-
const _dist_ = chalk.dim(`${this.dist}/`)
|
|
173
|
-
const _fileName_ = chalk.cyan(this.unprefixed(chunk.fileName))
|
|
174
|
-
const _rebundle_ = chalk.dim.cyan('[rebundle]')
|
|
175
|
-
const _size_ = chalk.bold.dim(`${filesize(size)}`)
|
|
176
|
-
console.log(`${_dist_}${_fileName_} ${_rebundle_} ${_size_}`)
|
|
177
|
-
|
|
178
|
-
// Save code
|
|
179
|
-
const code = result.output[0].code
|
|
180
|
-
if (!code) throw this.never
|
|
181
|
-
this.rebundledFiles[chunk.fileName] = code
|
|
182
|
-
|
|
183
|
-
// Remove Vite's output
|
|
184
|
-
await this.removeFromDist(chunk.fileName)
|
|
185
|
-
|
|
186
|
-
// Return modified status
|
|
187
|
-
return true
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
private async readChunkFiles(chunk: OutputChunk) {
|
|
191
|
-
const files: Record<string, string> = {}
|
|
192
|
-
const usedPaths = [chunk.fileName, ...chunk.imports]
|
|
193
|
-
|
|
194
|
-
await Promise.all(
|
|
195
|
-
usedPaths.map(async path => {
|
|
196
|
-
const content = await this.readFromDist(path)
|
|
197
|
-
files[path] = content ?? ''
|
|
198
|
-
}),
|
|
199
|
-
)
|
|
200
|
-
|
|
201
|
-
return files
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
private getChunks(bundle: OutputBundle) {
|
|
205
|
-
return Object.values(bundle).filter(chunkOrAsset => chunkOrAsset.type === 'chunk')
|
|
206
|
-
}
|
|
207
|
-
|
|
208
145
|
// ---------------------------------------------------------------------------
|
|
209
146
|
// HELPERS
|
|
210
147
|
// ---------------------------------------------------------------------------
|
|
211
148
|
|
|
212
149
|
private get dist() {
|
|
213
|
-
if (!this.config) throw
|
|
150
|
+
if (!this.config) throw 'never'
|
|
214
151
|
return this.config.build.outDir
|
|
215
152
|
}
|
|
216
153
|
|
|
217
|
-
private prefixed(fileName: string) {
|
|
218
|
-
return `rebundle-original-${fileName}`
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
private unprefixed(fileName: string) {
|
|
222
|
-
return fileName.replace('rebundle-original-', '')
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
private async readFromDist(path: string) {
|
|
226
|
-
const [content] = await safe(readFile(join(this.dist, path), 'utf-8'))
|
|
227
|
-
return content
|
|
228
|
-
}
|
|
229
|
-
|
|
230
154
|
private async removeFromDist(path: string) {
|
|
231
155
|
path = join(this.dist, path)
|
|
232
156
|
const dir = dirname(path)
|
|
@@ -236,7 +160,7 @@ export class Rebundle extends Unit {
|
|
|
236
160
|
|
|
237
161
|
private async ensureWs() {
|
|
238
162
|
if (this.ws) return this.ws
|
|
239
|
-
if (!this.port) throw
|
|
163
|
+
if (!this.port) throw 'never'
|
|
240
164
|
this.ws = new WebSocketServer({ port: this.port })
|
|
241
165
|
return this.ws
|
|
242
166
|
}
|
|
@@ -262,8 +186,8 @@ export class Rebundle extends Unit {
|
|
|
262
186
|
}
|
|
263
187
|
}
|
|
264
188
|
|
|
265
|
-
export function rebundle(
|
|
266
|
-
return new Rebundle(
|
|
189
|
+
export function rebundle(commonOptions?: RolldownOptions | null, bundleOptions?: BundleOptions) {
|
|
190
|
+
return new Rebundle(commonOptions, bundleOptions).vite
|
|
267
191
|
}
|
|
268
192
|
|
|
269
193
|
export default rebundle
|