@@ -6,6 +6,7 @@ import fs from "fs";
66import os from "os" ;
77import path from "path" ;
88import cp from "child_process" ;
9+ import { minifySync } from "vite" ;
910import { ctx } from "./context.js" ;
1011import { getTemplateDir } from "./utils.js" ;
1112import {
@@ -194,6 +195,35 @@ export const renderAssetsRc = (pakAbsPath: string): string =>
194195 return `N2DASSETS RCDATA "${ forward } "\n` ;
195196} ;
196197
198+ /**
199+ * @description ホストスクリプト(js/bootstrap.js 等)を minify + 難読化する純関数。
200+ * Oxc(vite 同梱)でコメント除去・空白圧縮・ローカル識別子マングルを行う。
201+ * `globalThis.*` 等のグローバル名はゲームが参照するため保持される。
202+ * 失敗時は元コードをそのまま返す(埋め込み自体は継続)。
203+ * Minify/obfuscate a host script; returns the original on failure.
204+ *
205+ * @param {string } name ファイル名 (拡張子で構文判定)
206+ * @param {string } code 元の JavaScript
207+ * @return {string }
208+ * @method
209+ * @public
210+ */
211+ export const minifyJs = ( name : string , code : string ) : string =>
212+ {
213+ try {
214+ const result = minifySync ( name , code ) ;
215+ if ( result . errors && result . errors . length > 0 ) {
216+ const msg = ( result . errors [ 0 ] as any ) ?. message ?? String ( result . errors [ 0 ] ) ;
217+ console . log ( pc . yellow ( `Xbox: minify skipped for ${ name } (${ msg } ); embedding as-is.` ) ) ;
218+ return code ;
219+ }
220+ return result . code ;
221+ } catch ( error ) {
222+ console . log ( pc . yellow ( `Xbox: minify failed for ${ name } ; embedding as-is. ${ error } ` ) ) ;
223+ return code ;
224+ }
225+ } ;
226+
197227/**
198228 * @description Xbox ホストの assets/app とホストスクリプト(js/bootstrap.js 等)を
199229 * 単一の pak バイナリへまとめ、`assets.pak` と RCDATA 参照用の
@@ -247,10 +277,26 @@ const embedXboxAssets = (): Promise<void> =>
247277 }
248278
249279 // (key, データ) を読み込み、pak バイナリへ直列化する。
280+ // js/ のホストスクリプト(bootstrap.js/selftest.js)は minify + 難読化する。
281+ // assets/app の JS は vite が本番ビルドで minify 済みのためそのまま。
282+ let minified = 0 ;
250283 const pakEntries : [ string , Buffer ] [ ] = entries . map (
251- ( [ key , abs ] ) : [ string , Buffer ] => [ key , fs . readFileSync ( abs ) ]
284+ ( [ key , abs ] ) : [ string , Buffer ] => {
285+ if ( key . startsWith ( "js/" ) && key . endsWith ( ".js" ) ) {
286+ const src = fs . readFileSync ( abs , { "encoding" : "utf8" } ) ;
287+ const out = minifyJs ( key , src ) ;
288+ if ( out . length < src . length ) {
289+ ++ minified ;
290+ }
291+ return [ key , Buffer . from ( out , "utf8" ) ] ;
292+ }
293+ return [ key , fs . readFileSync ( abs ) ] ;
294+ }
252295 ) ;
253296 const pak : Buffer = buildPak ( pakEntries ) ;
297+ if ( minified > 0 ) {
298+ console . log ( pc . green ( `Minified ${ minified } host script(s) before embedding.` ) ) ;
299+ }
254300 fs . writeFileSync ( pakPath , pak ) ;
255301
256302 // rc.exe が assets.pak を RCDATA "N2DASSETS" として取り込む .rc を生成する。
0 commit comments