Skip to content

Commit 44cb7c4

Browse files
authored
Merge pull request #211 from z0ffy/feature/multi-page
feat: enhance obfuscation process with registry management
2 parents 57a23be + b7f3e75 commit 44cb7c4

File tree

4 files changed

+151
-24
lines changed

4 files changed

+151
-24
lines changed

src/type.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@ export type BundleList = Array<[string, Rollup.OutputChunk]>;
99
export interface WorkerMessage {
1010
config: Config;
1111
chunk: BundleList;
12+
registryState?: string[];
13+
}
14+
15+
export interface WorkerResponse {
16+
results: ObfuscationResult[];
17+
registryState: string[];
1218
}
1319

1420
export type SizeResult = { original: FormatSizeResult; gzip: FormatSizeResult };

src/utils/index.ts

Lines changed: 87 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -105,19 +105,86 @@ export function getChunkName(id: string, manualChunks: string[]): string {
105105
return VENDOR_MODULES;
106106
}
107107

108+
export class ObfuscatedFilesRegistry {
109+
private static instance: ObfuscatedFilesRegistry;
110+
private obfuscatedFiles: Set<string> = new Set();
111+
112+
private constructor() {
113+
}
114+
115+
public static getInstance(): ObfuscatedFilesRegistry {
116+
if (!ObfuscatedFilesRegistry.instance) {
117+
ObfuscatedFilesRegistry.instance = new ObfuscatedFilesRegistry();
118+
}
119+
return ObfuscatedFilesRegistry.instance;
120+
}
121+
122+
public markAsObfuscated(fileName: string): void {
123+
if (!fileName) return;
124+
this.obfuscatedFiles.add(fileName);
125+
}
126+
127+
public isObfuscated(fileName: string): boolean {
128+
if (!fileName) return false;
129+
return this.obfuscatedFiles.has(fileName);
130+
}
131+
132+
public getAllObfuscatedFiles(): string[] {
133+
return Array.from(this.obfuscatedFiles);
134+
}
135+
136+
public clear(): void {
137+
this.obfuscatedFiles.clear();
138+
}
139+
140+
public serialize(): string[] {
141+
return Array.from(this.obfuscatedFiles);
142+
}
143+
144+
public updateFromSerialized(serializedFiles: string[]): void {
145+
if (!serializedFiles || !Array.isArray(serializedFiles)) return;
146+
147+
serializedFiles.forEach((file) => {
148+
this.obfuscatedFiles.add(file);
149+
});
150+
}
151+
}
152+
108153
export function obfuscateBundle(finalConfig: Config, fileName: string, bundleItem: Rollup.OutputChunk): string {
109154
const _log = new Log(finalConfig.log);
155+
const registry = ObfuscatedFilesRegistry.getInstance();
156+
157+
if (registry.isObfuscated(fileName)) {
158+
_log.info(`skipping ${fileName} (already in obfuscated registry)`);
159+
return bundleItem.code;
160+
}
161+
110162
_log.info(`obfuscating ${fileName}...`);
111163
const obfuscatedCode = javascriptObfuscator.obfuscate(bundleItem.code, finalConfig.options).getObfuscatedCode();
112164
_log.info(`obfuscation complete for ${fileName}.`);
165+
166+
registry.markAsObfuscated(fileName);
167+
_log.info(`added ${fileName} to obfuscated files registry`);
168+
113169
return obfuscatedCode;
114170
}
115171

116172
export function obfuscateLibBundle(finalConfig: Config, fileName: string, code: string): { code: string; map: Rollup.SourceMapInput } {
117173
const _log = new Log(finalConfig.log);
174+
const registry = ObfuscatedFilesRegistry.getInstance();
175+
176+
if (registry.isObfuscated(fileName)) {
177+
_log.info(`skipping ${fileName} (already in obfuscated registry)`);
178+
return { code, map: null };
179+
}
180+
118181
_log.info(`obfuscating ${fileName}...`);
119182
const obfuscated = javascriptObfuscator.obfuscate(code, finalConfig.options);
120183
_log.info(`obfuscation complete for ${fileName}.`);
184+
185+
registry.markAsObfuscated(fileName);
186+
_log.info(`added ${fileName} to obfuscated files registry`);
187+
121188
return {
122189
code: obfuscated.getObfuscatedCode(),
123190
map: obfuscated.getSourceMap(),
@@ -127,15 +194,28 @@ export function obfuscateLibBundle(finalConfig: Config, fileName: string, code:
127194
export function createWorkerTask(finalConfig: Config, chunk: BundleList) {
128195
return new Promise((resolve, reject) => {
129196
const worker = new Worker(path.join(__dirname, WORKER_FILE_PATH));
130-
worker.postMessage({ config: finalConfig, chunk });
197+
const registry = ObfuscatedFilesRegistry.getInstance();
198+
199+
worker.postMessage({
200+
config: finalConfig,
201+
chunk,
202+
registryState: registry.serialize(),
203+
});
131204

132205
worker.on('message', (value) => {
133-
chunk.forEach(([fileName, bundleItem]) => {
134-
const result = value.find((i: ObfuscationResult) => i.fileName === fileName);
135-
if (result && result.obfuscatedCode) {
136-
bundleItem.code = result.obfuscatedCode;
137-
}
138-
});
206+
if (value.results && Array.isArray(value.results)) {
207+
chunk.forEach(([fileName, bundleItem]) => {
208+
const result = value.results.find((i: ObfuscationResult) => i.fileName === fileName);
209+
if (result && result.obfuscatedCode) {
210+
bundleItem.code = result.obfuscatedCode;
211+
}
212+
});
213+
}
214+
215+
if (value.registryState && Array.isArray(value.registryState)) {
216+
registry.updateFromSerialized(value.registryState);
217+
}
218+
139219
resolve(value);
140220
worker.unref();
141221
});

src/utils/is.ts

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,23 @@ export function isBoolean(input: any): input is boolean {
2323
return Object.prototype.toString.call(input) === '[object Boolean]';
2424
}
2525

26-
export function isFileNameExcluded(name: string, excludes: (RegExp | string)[]): boolean {
27-
for (const exclude of excludes) {
28-
if (isRegExp(exclude)) {
29-
if (exclude.test(name)) return true;
30-
} else if (isString(exclude)) {
31-
if (name.includes(exclude)) return true;
32-
}
26+
export function isFileNameExcluded(fileName: string, excludes: (RegExp | string)[] | RegExp | string): boolean {
27+
if (!excludes) return false;
28+
29+
if (Array.isArray(excludes)) {
30+
return excludes.some((exclude) => {
31+
if (isString(exclude)) {
32+
return fileName.includes(exclude);
33+
} else if (isRegExp(exclude)) {
34+
return exclude.test(fileName);
35+
}
36+
return false;
37+
});
38+
} else if (isString(excludes)) {
39+
return fileName.includes(excludes);
40+
} else if (isRegExp(excludes)) {
41+
return excludes.test(fileName);
3342
}
43+
3444
return false;
3545
}

src/worker/index.ts

Lines changed: 41 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,46 @@
11
import { parentPort } from 'node:worker_threads';
2-
import { ObfuscationResult, WorkerMessage } from '../type';
3-
import { obfuscateBundle } from '../utils';
2+
import javascriptObfuscator from 'javascript-obfuscator';
3+
import { Log, ObfuscatedFilesRegistry } from '../utils';
4+
import type { ObfuscationResult, WorkerMessage } from '../type';
45

5-
parentPort?.on('message', (message: WorkerMessage) => {
6-
const { config, chunk } = message;
6+
if (parentPort) {
7+
parentPort.on('message', (message: WorkerMessage) => {
8+
const results: ObfuscationResult[] = [];
9+
const _log = new Log(message.config.log);
10+
const registry = ObfuscatedFilesRegistry.getInstance();
711

8-
const result: ObfuscationResult[] = chunk.map(([fileName, bundleItem]) => {
9-
const obfuscatedCode = obfuscateBundle(config, fileName, bundleItem);
12+
if (message.registryState && Array.isArray(message.registryState)) {
13+
registry.updateFromSerialized(message.registryState);
14+
}
1015

11-
return { fileName, obfuscatedCode };
12-
});
16+
for (const [fileName, bundleItem] of message.chunk) {
17+
if (registry.isObfuscated(fileName)) {
18+
_log.info(`skipping ${fileName} (already in obfuscated registry)`);
19+
results.push({
20+
fileName,
21+
obfuscatedCode: bundleItem.code,
22+
});
23+
continue;
24+
}
25+
26+
_log.info(`worker obfuscating ${fileName}...`);
27+
const obfuscated = javascriptObfuscator.obfuscate(bundleItem.code, message.config.options);
28+
_log.info(`worker obfuscation complete for ${fileName}.`);
29+
30+
registry.markAsObfuscated(fileName);
31+
_log.info(`worker added ${fileName} to obfuscated files registry`);
1332

14-
parentPort?.postMessage(result);
15-
});
33+
results.push({
34+
fileName,
35+
obfuscatedCode: obfuscated.getObfuscatedCode(),
36+
});
37+
}
38+
39+
if (parentPort) {
40+
parentPort.postMessage({
41+
results,
42+
registryState: registry.serialize(),
43+
});
44+
}
45+
});
46+
}

0 commit comments

Comments
 (0)