vite-plugin-rebundle 1.2.7 → 1.2.10
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/index.d.ts +2 -2
- package/dist/index.js +2 -1
- package/dist/rebundle.d.ts +12 -8
- package/dist/rebundle.js +114 -106
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { type
|
|
2
|
-
export default function rebundle(options?:
|
|
1
|
+
import { type Options } from './rebundle.js';
|
|
2
|
+
export default function rebundle(options?: Options): import("vite").Plugin<any>;
|
package/dist/index.js
CHANGED
package/dist/rebundle.d.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import * as $utils from '@eposlabs/utils';
|
|
2
2
|
import type { BuildOptions } from 'esbuild';
|
|
3
|
+
import type { OutputBundle, OutputChunk } from 'rollup';
|
|
3
4
|
import type { Plugin } from 'vite';
|
|
5
|
+
export declare const _code_: unique symbol;
|
|
6
|
+
export declare const _sourcemap_: unique symbol;
|
|
4
7
|
export type Options = {
|
|
5
8
|
[chunkName: string]: BuildOptions;
|
|
6
9
|
};
|
|
7
|
-
export type OptionsInput = Options | (() => Options | Promise<Options>);
|
|
8
10
|
export declare class Rebundle extends $utils.Unit {
|
|
9
11
|
private options;
|
|
10
12
|
private config;
|
|
@@ -13,18 +15,20 @@ export declare class Rebundle extends $utils.Unit {
|
|
|
13
15
|
private hasError;
|
|
14
16
|
private port;
|
|
15
17
|
private ws;
|
|
16
|
-
constructor(options:
|
|
18
|
+
constructor(options: Options);
|
|
17
19
|
get vite(): Plugin;
|
|
18
20
|
private onConfig;
|
|
19
21
|
private onConfigResolved;
|
|
20
22
|
private onBuildEnd;
|
|
21
23
|
private onWriteBundle;
|
|
22
|
-
|
|
23
|
-
private
|
|
24
|
-
private outRead;
|
|
25
|
-
private outWrite;
|
|
26
|
-
private ensureWs;
|
|
27
|
-
private getOptions;
|
|
24
|
+
rebundleChunk(chunk: OutputChunk, bundle: OutputBundle): Promise<boolean | undefined>;
|
|
25
|
+
private removeChunk;
|
|
28
26
|
private readChunkFiles;
|
|
27
|
+
private get dist();
|
|
28
|
+
private resolve;
|
|
29
|
+
private read;
|
|
30
|
+
private write;
|
|
31
|
+
private remove;
|
|
32
|
+
private ensureWs;
|
|
29
33
|
private removeDirectoryIfEmpty;
|
|
30
34
|
}
|
package/dist/rebundle.js
CHANGED
|
@@ -6,6 +6,8 @@ import * as $utils from '@eposlabs/utils';
|
|
|
6
6
|
import * as $ws from 'ws';
|
|
7
7
|
import $chalk from 'chalk';
|
|
8
8
|
import $portfinder from 'portfinder';
|
|
9
|
+
export const _code_ = Symbol('rebundle:code');
|
|
10
|
+
export const _sourcemap_ = Symbol('rebundle:sourcemap');
|
|
9
11
|
export class Rebundle extends $utils.Unit {
|
|
10
12
|
options;
|
|
11
13
|
config = null;
|
|
@@ -30,7 +32,7 @@ export class Rebundle extends $utils.Unit {
|
|
|
30
32
|
};
|
|
31
33
|
}
|
|
32
34
|
// ---------------------------------------------------------------------------
|
|
33
|
-
// HOOKS
|
|
35
|
+
// VITE HOOKS
|
|
34
36
|
// ---------------------------------------------------------------------------
|
|
35
37
|
onConfig = async () => {
|
|
36
38
|
this.port = await $portfinder.getPort({ port: 3100 });
|
|
@@ -43,7 +45,7 @@ export class Rebundle extends $utils.Unit {
|
|
|
43
45
|
onConfigResolved = async (config) => {
|
|
44
46
|
// Save resolved config
|
|
45
47
|
this.config = config;
|
|
46
|
-
// Hide
|
|
48
|
+
// Hide js files from output logs (rollup only, not supported in rolldown)
|
|
47
49
|
const info = this.config.logger.info;
|
|
48
50
|
this.config.logger.info = (message, options) => {
|
|
49
51
|
const path = message.split(/\s+/)[0];
|
|
@@ -58,134 +60,140 @@ export class Rebundle extends $utils.Unit {
|
|
|
58
60
|
onWriteBundle = async (_output, bundle) => {
|
|
59
61
|
if (this.hasError)
|
|
60
62
|
return;
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
if (
|
|
71
|
-
|
|
72
|
-
// Delete chunk from bundle to hide log in vite-rolldown.
|
|
73
|
-
// Call for rollup as well for consistency.
|
|
74
|
-
delete bundle[chunk.fileName];
|
|
75
|
-
const chunkPath = this.outPath(chunk.fileName);
|
|
76
|
-
const chunkBuildOptions = options[chunk.name] ?? {};
|
|
77
|
-
const chunkFiles = await this.readChunkFiles(chunk);
|
|
78
|
-
const chunkFilePaths = Object.keys(chunkFiles);
|
|
79
|
-
const chunkChanged = chunkFilePaths.some(path => chunkFiles[path] !== this.chunkFiles[path]);
|
|
80
|
-
// Update files cache
|
|
81
|
-
Object.assign(this.chunkFiles, chunkFiles);
|
|
82
|
-
// Modified? -> Rebundle
|
|
83
|
-
if (chunkChanged) {
|
|
84
|
-
// Build with esbuild
|
|
85
|
-
const result = await $esbuild.build({
|
|
86
|
-
sourcemap: Boolean(this.config.build.sourcemap),
|
|
87
|
-
...chunkBuildOptions,
|
|
88
|
-
outfile: chunkPath,
|
|
89
|
-
entryPoints: [chunkPath],
|
|
90
|
-
bundle: true,
|
|
91
|
-
minify: false,
|
|
92
|
-
keepNames: true,
|
|
93
|
-
allowOverwrite: true,
|
|
94
|
-
});
|
|
95
|
-
if (result.errors.length > 0)
|
|
96
|
-
return;
|
|
97
|
-
// Log successful build
|
|
98
|
-
const { size } = await $fs.stat(chunkPath);
|
|
99
|
-
const _outDir_ = $chalk.dim(`${this.outDir}/`);
|
|
100
|
-
const _fileName_ = $chalk.cyan(chunk.fileName);
|
|
101
|
-
const _rebundle_ = $chalk.dim.cyan('[rebundle]');
|
|
102
|
-
const _size_ = $chalk.bold.dim(`${filesize(size)}`);
|
|
103
|
-
console.log(`${_outDir_}${_fileName_} ${_rebundle_} ${_size_}`);
|
|
104
|
-
// Mark chunk as changed
|
|
105
|
-
changedChunkNames.push(chunk.name);
|
|
106
|
-
// Save chunk content
|
|
107
|
-
this.rebundledContent[chunk.fileName] = await this.outRead(chunk.fileName);
|
|
108
|
-
// Save sourcemap content
|
|
109
|
-
if (chunk.sourcemapFileName) {
|
|
110
|
-
this.rebundledContent[chunk.sourcemapFileName] = await this.outRead(chunk.sourcemapFileName);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
// Overwrite chunk
|
|
114
|
-
await this.outWrite(chunk.fileName, this.rebundledContent[chunk.fileName]);
|
|
115
|
-
chunk.code = this.rebundledContent[chunk.fileName];
|
|
116
|
-
// Overwrite sourcemap
|
|
117
|
-
if (chunk.sourcemapFileName) {
|
|
118
|
-
const sourcemapAsset = bundle[chunk.sourcemapFileName];
|
|
119
|
-
if (sourcemapAsset.type !== 'asset')
|
|
120
|
-
throw this.never;
|
|
121
|
-
await this.outWrite(chunk.sourcemapFileName, this.rebundledContent[chunk.sourcemapFileName]);
|
|
122
|
-
sourcemapAsset.source = this.rebundledContent[chunk.sourcemapFileName];
|
|
123
|
-
}
|
|
63
|
+
if (!this.config)
|
|
64
|
+
throw this.never;
|
|
65
|
+
const chunks = Object.values(bundle).filter(chunkOrAsset => chunkOrAsset.type === 'chunk');
|
|
66
|
+
const entryChunks = chunks.filter(chunk => chunk.isEntry);
|
|
67
|
+
const nonEntryChunks = chunks.filter(chunk => !chunk.isEntry);
|
|
68
|
+
// Rebundle entry chunks
|
|
69
|
+
const modifiedChunkNames = [];
|
|
70
|
+
await Promise.all(entryChunks.map(async (chunk) => {
|
|
71
|
+
const modified = await this.rebundleChunk(chunk, bundle);
|
|
72
|
+
if (modified)
|
|
73
|
+
modifiedChunkNames.push(chunk.name);
|
|
124
74
|
}));
|
|
125
|
-
//
|
|
126
|
-
const nonEntryChunks = Object.values(bundle)
|
|
127
|
-
.filter(chunkOrAsset => chunkOrAsset.type === 'chunk')
|
|
128
|
-
.filter(chunk => !chunk.isEntry);
|
|
129
|
-
// Remove all non-entry chunks
|
|
75
|
+
// Remove non-entry chunks
|
|
130
76
|
for (const chunk of nonEntryChunks) {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
77
|
+
await this.removeChunk(chunk, bundle);
|
|
78
|
+
}
|
|
79
|
+
// Notify about modified chunks
|
|
80
|
+
if (this.config.build.watch && modifiedChunkNames.length > 0) {
|
|
81
|
+
const ws = await this.ensureWs();
|
|
82
|
+
ws.clients.forEach(client => client.send(JSON.stringify(modifiedChunkNames)));
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
// ---------------------------------------------------------------------------
|
|
86
|
+
// CHUNK METHODS
|
|
87
|
+
// ---------------------------------------------------------------------------
|
|
88
|
+
async rebundleChunk(chunk, bundle) {
|
|
89
|
+
if (!this.config)
|
|
90
|
+
throw this.never;
|
|
91
|
+
// Delete chunk from bundle to hide log for vite-rolldown.
|
|
92
|
+
// Call for rollup as well for consistency.
|
|
93
|
+
delete bundle[chunk.fileName];
|
|
94
|
+
const chunkPath = this.resolve(chunk.fileName);
|
|
95
|
+
const chunkBuildOptions = this.options[chunk.name] ?? {};
|
|
96
|
+
const chunkFiles = await this.readChunkFiles(chunk);
|
|
97
|
+
const chunkFilePaths = Object.keys(chunkFiles);
|
|
98
|
+
const chunkChanged = chunkFilePaths.some(path => chunkFiles[path] !== this.chunkFiles[path]);
|
|
99
|
+
// Update files cache
|
|
100
|
+
Object.assign(this.chunkFiles, chunkFiles);
|
|
101
|
+
// Not modified? -> Use pervious content
|
|
102
|
+
if (!chunkChanged) {
|
|
103
|
+
// Overwrite vite's code
|
|
104
|
+
const code = this.rebundledContent[chunk.fileName];
|
|
105
|
+
await this.write(chunk.fileName, code);
|
|
106
|
+
// Overwrite vite's sourcemap
|
|
135
107
|
if (chunk.sourcemapFileName) {
|
|
136
|
-
|
|
137
|
-
|
|
108
|
+
const sourcemap = this.rebundledContent[chunk.sourcemapFileName];
|
|
109
|
+
if (sourcemap)
|
|
110
|
+
await this.write(chunk.sourcemapFileName, sourcemap);
|
|
138
111
|
}
|
|
139
|
-
|
|
140
|
-
const dir = $path.dirname(this.outPath(chunk.fileName));
|
|
141
|
-
await this.removeDirectoryIfEmpty(dir);
|
|
112
|
+
return false;
|
|
142
113
|
}
|
|
143
|
-
//
|
|
144
|
-
|
|
145
|
-
|
|
114
|
+
// Build with esbuild
|
|
115
|
+
const result = await $esbuild.build({
|
|
116
|
+
sourcemap: Boolean(this.config.build.sourcemap),
|
|
117
|
+
...chunkBuildOptions,
|
|
118
|
+
outfile: chunkPath,
|
|
119
|
+
entryPoints: [chunkPath],
|
|
120
|
+
bundle: true,
|
|
121
|
+
allowOverwrite: true,
|
|
122
|
+
});
|
|
123
|
+
// Errors? -> Ignore, esbuild will show errors in console
|
|
124
|
+
if (result.errors.length > 0)
|
|
125
|
+
return;
|
|
126
|
+
// Log successful build
|
|
127
|
+
const { size } = await $fs.stat(chunkPath);
|
|
128
|
+
const _dist_ = $chalk.dim(`${this.dist}/`);
|
|
129
|
+
const _fileName_ = $chalk.cyan(chunk.fileName);
|
|
130
|
+
const _rebundle_ = $chalk.dim.cyan('[rebundle]');
|
|
131
|
+
const _size_ = $chalk.bold.dim(`${filesize(size)}`);
|
|
132
|
+
console.log(`${_dist_}${_fileName_} ${_rebundle_} ${_size_}`);
|
|
133
|
+
// Save code
|
|
134
|
+
const code = await this.read(chunk.fileName);
|
|
135
|
+
if (!code)
|
|
136
|
+
throw this.never;
|
|
137
|
+
this.rebundledContent[chunk.fileName] = code;
|
|
138
|
+
// Save sourcemap
|
|
139
|
+
if (chunk.sourcemapFileName) {
|
|
140
|
+
const sourcemap = await this.read(chunk.sourcemapFileName);
|
|
141
|
+
if (sourcemap)
|
|
142
|
+
this.rebundledContent[chunk.sourcemapFileName] = sourcemap;
|
|
146
143
|
}
|
|
147
|
-
|
|
144
|
+
return true;
|
|
145
|
+
}
|
|
146
|
+
async removeChunk(chunk, bundle) {
|
|
147
|
+
await this.remove(chunk.fileName);
|
|
148
|
+
delete bundle[chunk.fileName];
|
|
149
|
+
if (chunk.sourcemapFileName) {
|
|
150
|
+
await this.remove(chunk.sourcemapFileName);
|
|
151
|
+
delete bundle[chunk.sourcemapFileName];
|
|
152
|
+
}
|
|
153
|
+
// Recursively remove containing directory if empty
|
|
154
|
+
const dir = $path.dirname(this.resolve(chunk.fileName));
|
|
155
|
+
await this.removeDirectoryIfEmpty(dir);
|
|
156
|
+
}
|
|
157
|
+
async readChunkFiles(chunk) {
|
|
158
|
+
const files = {};
|
|
159
|
+
const usedPaths = [chunk.fileName, ...chunk.imports];
|
|
160
|
+
await Promise.all(usedPaths.map(async (path) => {
|
|
161
|
+
const content = await this.read(path);
|
|
162
|
+
if (!content)
|
|
163
|
+
throw this.never;
|
|
164
|
+
files[path] = content;
|
|
165
|
+
}));
|
|
166
|
+
return files;
|
|
167
|
+
}
|
|
148
168
|
// ---------------------------------------------------------------------------
|
|
149
169
|
// HELPERS
|
|
150
170
|
// ---------------------------------------------------------------------------
|
|
151
|
-
get
|
|
171
|
+
get dist() {
|
|
152
172
|
if (!this.config)
|
|
153
173
|
throw this.never;
|
|
154
174
|
return this.config.build.outDir;
|
|
155
175
|
}
|
|
156
|
-
|
|
157
|
-
return $path.join(this.
|
|
176
|
+
resolve(path) {
|
|
177
|
+
return $path.join(this.dist, path);
|
|
178
|
+
}
|
|
179
|
+
async read(path) {
|
|
180
|
+
const [content] = await $utils.safe($fs.readFile(this.resolve(path), 'utf-8'));
|
|
181
|
+
return content;
|
|
158
182
|
}
|
|
159
|
-
async
|
|
160
|
-
|
|
183
|
+
async write(path, content) {
|
|
184
|
+
await $fs.writeFile(this.resolve(path), content, 'utf-8');
|
|
161
185
|
}
|
|
162
|
-
async
|
|
163
|
-
await $fs.
|
|
186
|
+
async remove(path) {
|
|
187
|
+
await $utils.safe($fs.unlink(this.resolve(path)));
|
|
164
188
|
}
|
|
165
189
|
async ensureWs() {
|
|
166
190
|
if (this.ws)
|
|
167
191
|
return this.ws;
|
|
168
192
|
if (!this.port)
|
|
169
193
|
throw this.never;
|
|
170
|
-
if (!this.config)
|
|
171
|
-
throw this.never;
|
|
172
|
-
if (!this.config.build.watch)
|
|
173
|
-
return null;
|
|
174
194
|
this.ws = new $ws.WebSocketServer({ port: this.port });
|
|
175
195
|
return this.ws;
|
|
176
196
|
}
|
|
177
|
-
async getOptions() {
|
|
178
|
-
if (typeof this.options !== 'function')
|
|
179
|
-
return this.options;
|
|
180
|
-
return await this.options();
|
|
181
|
-
}
|
|
182
|
-
async readChunkFiles(chunk) {
|
|
183
|
-
const files = {};
|
|
184
|
-
await Promise.all([chunk.fileName, ...chunk.imports].map(async (path) => {
|
|
185
|
-
files[path] = await this.outRead(path);
|
|
186
|
-
}));
|
|
187
|
-
return files;
|
|
188
|
-
}
|
|
189
197
|
async removeDirectoryIfEmpty(dir) {
|
|
190
198
|
const files = await $fs.readdir(dir);
|
|
191
199
|
if (files.length > 0)
|