| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293 |
- import fs from 'node:fs';
- import path from 'node:path';
- import { fileURLToPath } from 'node:url';
- const projectRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
- const buildRoot = path.join(projectRoot, 'build', 'wechatgame');
- const ccDepsWithoutPhysics = [
- 'plugin:cocos/2d.js',
- 'plugin:cocos/sorting.js',
- 'plugin:cocos/3d.js',
- './affine-transform.js',
- './animation.js',
- 'plugin:cocos/audio.js',
- 'plugin:cocos/base.js',
- './custom-pipeline.js',
- 'plugin:cocos/dragon-bones.js',
- 'plugin:cocos/gfx-webgl.js',
- 'plugin:cocos/graphics.js',
- 'plugin:cocos/intersection-2d.js',
- 'plugin:cocos/light-probe.js',
- 'plugin:cocos/mask.js',
- 'plugin:cocos/particle.js',
- 'plugin:cocos/particle-2d.js',
- 'plugin:cocos/primitive.js',
- 'plugin:cocos/profiler.js',
- 'plugin:cocos/rich-text.js',
- './skeletal-animation.js',
- 'plugin:cocos/spine.js',
- 'plugin:cocos/terrain.js',
- 'plugin:cocos/tiled-map.js',
- 'plugin:cocos/tween.js',
- 'plugin:cocos/ui.js',
- 'plugin:cocos/ui-skew.js',
- 'plugin:cocos/video.js',
- 'plugin:cocos/webview.js',
- ];
- function readJson(file) {
- return JSON.parse(fs.readFileSync(file, 'utf8'));
- }
- function writeJson(file, data) {
- fs.writeFileSync(file, JSON.stringify(data));
- }
- function safeBuildPath(relPath) {
- const target = path.resolve(buildRoot, relPath);
- if (target !== buildRoot && !target.startsWith(buildRoot + path.sep)) {
- throw new Error(`Refusing to touch path outside build root: ${target}`);
- }
- return target;
- }
- function removeBuildPath(relPath) {
- fs.rmSync(safeBuildPath(relPath), { recursive: true, force: true });
- }
- function rewriteCcWithoutPhysics() {
- const ccPath = safeBuildPath(path.join('cocos-js', 'cc.js'));
- if (!fs.existsSync(ccPath)) return;
- const body = `System.register(${JSON.stringify(ccDepsWithoutPhysics)}, function (_export, _context) {
- "use strict";
- function exportAll(module) {
- var exportObj = {};
- for (var key in module) {
- if (key !== "default" && key !== "__esModule") exportObj[key] = module[key];
- }
- _export(exportObj);
- }
- return {
- setters: [${ccDepsWithoutPhysics.map(() => 'exportAll').join(', ')}],
- execute: function () {}
- };
- });
- `;
- fs.writeFileSync(ccPath, body);
- }
- function removeFirstScreen() {
- const gamePath = safeBuildPath('game.js');
- if (!fs.existsSync(gamePath)) return;
- let source = fs.readFileSync(gamePath, 'utf8');
- source = source.replace("const firstScreen = require('./first-screen');\r\n\r\n", '');
- source = source.replace("const firstScreen = require('./first-screen');\n\n", '');
- source = source.replace(/firstScreen\.start\('default', 'default', 'false'\)\.then\(\(\) => \{\s*return System\.import\('\.\/application\.js'\);\s*\}\)\.then\(\(module\) => \{\s*return firstScreen\.setProgress\(0\.2\)\.then\(\(\) => Promise\.resolve\(module\)\);\s*\}\)/s, "System.import('./application.js')");
- source = source.replace(/\.then\(\(application\) => \{\s*return firstScreen\.setProgress\(0\.4\)\.then\(\(\) => Promise\.resolve\(application\)\);\s*\}\)/s, '');
- source = source.replace(/return firstScreen\.setProgress\(0\.6\)\.then\(\(\) => Promise\.resolve\(module\)\);/g, 'return module;');
- source = source.replace(/return firstScreen\.end\(\)\.then\(\(\) => application\.start\(\)\);/g, 'return application.start();');
- fs.writeFileSync(gamePath, source);
- removeBuildPath('first-screen.js');
- removeBuildPath('logo.png');
- removeBuildPath('slogan.png');
- }
- function patchFullscreenCanvas() {
- const gamePath = safeBuildPath('game.js');
- if (!fs.existsSync(gamePath)) return;
- let source = fs.readFileSync(gamePath, 'utf8');
- source = source.replace(/\/\/ Adapt for IOS, swap if opposite[\s\S]*?const importMap = require\("src\/import-map\.js"\)\.default;/, 'const importMap = require("src/import-map.js").default;');
- source = source.replace(/\nfunction __steelGetLandscapeFrame \(\) \{[\s\S]*?\nwx\.onWindowResize && wx\.onWindowResize\(__steelApplyFullscreenCanvas\);\n\n?/, '\n');
- const shim = `
- function __steelGetLandscapeFrame () {
- const info = (wx.getWindowInfo && wx.getWindowInfo()) || wx.getSystemInfoSync();
- const add = function (list, width, height) {
- if (!width || !height || width <= 0 || height <= 0) return;
- list.push({ width: Math.max(width, height), height: Math.min(width, height) });
- };
- const candidates = [];
- add(candidates, info.windowWidth, info.windowHeight);
- add(candidates, info.screenWidth, info.screenHeight);
- add(candidates, canvas.width, canvas.height);
- add(candidates, canvas.clientWidth, canvas.clientHeight);
- const frame = candidates.reduce(function (best, item) {
- return item.width / Math.max(1, item.height) > best.width / Math.max(1, best.height) ? item : best;
- }, { width: 1624, height: 750 });
- const dpr = info.pixelRatio || info.devicePixelRatio || window.devicePixelRatio || 1;
- return { width: frame.width, height: frame.height, dpr };
- }
- function __steelSetWindowValue (key, value) {
- try {
- const descriptor = Object.getOwnPropertyDescriptor(window, key);
- if (!descriptor || descriptor.configurable) {
- Object.defineProperty(window, key, { value, configurable: true, writable: true });
- } else if (descriptor.writable) {
- window[key] = value;
- }
- } catch (error) {}
- }
- function __steelApplyFullscreenCanvas () {
- if (!canvas) return;
- const frame = __steelGetLandscapeFrame();
- const pixelWidth = Math.max(1, Math.round(frame.width * frame.dpr));
- const pixelHeight = Math.max(1, Math.round(frame.height * frame.dpr));
- __steelSetWindowValue('innerWidth', frame.width);
- __steelSetWindowValue('innerHeight', frame.height);
- __steelSetWindowValue('screen', {
- width: frame.width,
- height: frame.height,
- availWidth: frame.width,
- availHeight: frame.height,
- availLeft: 0,
- availTop: 0
- });
- canvas.width = pixelWidth;
- canvas.height = pixelHeight;
- canvas.style = canvas.style || {};
- canvas.style.top = '0px';
- canvas.style.left = '0px';
- canvas.style.width = frame.width + 'px';
- canvas.style.height = frame.height + 'px';
- canvas.getBoundingClientRect = function () {
- return { top: 0, left: 0, width: frame.width, height: frame.height };
- };
- console.log('[SteelAssaultGame] wx fullscreen canvas ' + frame.width + 'x' + frame.height + ' dpr ' + frame.dpr + ' backing ' + pixelWidth + 'x' + pixelHeight);
- }
- __steelApplyFullscreenCanvas();
- wx.onWindowResize && wx.onWindowResize(__steelApplyFullscreenCanvas);
- `;
- source = source.replace(/require\('\.\/web-adapter'\);\r?\n/, `require('./web-adapter');\n${shim}\n`);
- fs.writeFileSync(gamePath, source);
- }
- function disablePhysicsSettingOnly() {
- const settingsPath = safeBuildPath(path.join('src', 'settings.json'));
- if (!fs.existsSync(settingsPath)) return;
- const settings = readJson(settingsPath);
- settings.physics = { physicsEngine: '' };
- if (settings.splashScreen) {
- settings.splashScreen.totalTime = 0;
- if (settings.splashScreen.logo) settings.splashScreen.logo.image = '';
- }
- writeJson(settingsPath, settings);
- }
- function removeDefaultPhysicsMaterialAsset() {
- const settingsPath = safeBuildPath(path.join('src', 'settings.json'));
- const internalConfigPath = safeBuildPath(path.join('assets', 'internal', 'config.json'));
- const internalPackPath = safeBuildPath(path.join('assets', 'internal', 'import', '07', '07d3aae9f.json'));
- if (!fs.existsSync(settingsPath) || !fs.existsSync(internalConfigPath) || !fs.existsSync(internalPackPath)) return;
- const settings = readJson(settingsPath);
- if (settings.engine?.builtinAssets) {
- settings.engine.builtinAssets = settings.engine.builtinAssets.filter((uuid) => uuid !== 'd1346436-ac96-4271-b863-1f4fdead95b0');
- writeJson(settingsPath, settings);
- }
- const internalConfig = readJson(internalConfigPath);
- const internalPack = readJson(internalPackPath);
- const packIds = internalConfig.packs?.['07d3aae9f'] ?? [];
- const physicsIndex = packIds.indexOf(22);
- if (physicsIndex >= 0 && Array.isArray(internalPack[5])) {
- internalPack[5].splice(physicsIndex, 1);
- }
- const physicsTypeIndex = Array.isArray(internalPack[3])
- ? internalPack[3].findIndex((entry) => entry?.[0] === 'cc.PhysicsMaterial')
- : -1;
- if (physicsTypeIndex >= 0) {
- internalPack[3].splice(physicsTypeIndex, 1);
- if (Array.isArray(internalPack[4])) {
- internalPack[4] = internalPack[4].filter((entry) => entry?.[0] !== physicsTypeIndex);
- }
- }
- if (internalConfig.packs?.['07d3aae9f']) {
- internalConfig.packs['07d3aae9f'] = packIds.filter((id) => id !== 22);
- }
- delete internalConfig.paths?.['22'];
- if (internalConfig.types) {
- internalConfig.types = internalConfig.types.filter((type) => type !== 'cc.PhysicsMaterial');
- }
- writeJson(internalConfigPath, internalConfig);
- writeJson(internalPackPath, internalPack);
- }
- function removePhysicsEngineFiles() {
- [
- 'cocos-js/physics-framework.js',
- 'cocos-js/physics-ammo.js',
- 'cocos-js/physics-2d-framework.js',
- 'cocos-js/physics-2d-framework-CVNkMl3f.js',
- 'cocos-js/physics-2d-box2d.js',
- 'cocos-js/index-D5MM0hSc.js',
- 'cocos-js/collision-matrix-C-tmFF1b.js',
- 'cocos-js/array-collision-matrix-DU5_JQW3.js',
- 'cocos-js/tuple-dictionary-By7Ih6PO.js',
- 'cocos-js/bullet.release.asm-CtSjh1p_.js',
- 'cocos-js/bullet.release.wasm-CV1y-N0i.js',
- 'cocos-js/bullet.release.wasm-mT4aJDLq.js',
- 'cocos-js/assets/bullet.release.wasm-BIzkn7bF.wasm',
- ].forEach(removeBuildPath);
- }
- function removeUnusedDefaultScene() {
- const mainConfigPath = safeBuildPath(path.join('assets', 'main', 'config.json'));
- if (fs.existsSync(mainConfigPath)) {
- const mainConfig = readJson(mainConfigPath);
- for (const id of ['3', '4', '19']) delete mainConfig.paths?.[id];
- if (mainConfig.scenes) delete mainConfig.scenes['db://assets/scenes/scene.scene'];
- delete mainConfig.packs?.['0699aaa4c'];
- delete mainConfig.packs?.['06add430f'];
- mainConfig.redirect = [];
- mainConfig.types = ['cc.SceneAsset'];
- writeJson(mainConfigPath, mainConfig);
- }
- [
- 'assets/main/import/e6/e612b3cf-fca7-4207-8dcc-5a0b5d305242.json',
- 'assets/main/import/06/0699aaa4c.json',
- 'assets/main/import/06/06add430f.json',
- 'assets/main/import/fd/fd8ec536-a354-4a17-9c74-4f3883c378c8.json',
- 'assets/main/native/6f',
- 'assets/main/native/d0',
- ].forEach(removeBuildPath);
- }
- function totalBuildBytes() {
- let total = 0;
- const walk = (dir) => {
- for (const name of fs.readdirSync(dir)) {
- const file = path.join(dir, name);
- const stat = fs.statSync(file);
- if (stat.isDirectory()) walk(file);
- else total += stat.size;
- }
- };
- walk(buildRoot);
- return total;
- }
- if (!fs.existsSync(buildRoot)) {
- throw new Error(`Wechat build folder not found: ${buildRoot}`);
- }
- removeFirstScreen();
- patchFullscreenCanvas();
- rewriteCcWithoutPhysics();
- disablePhysicsSettingOnly();
- removeDefaultPhysicsMaterialAsset();
- removePhysicsEngineFiles();
- removeUnusedDefaultScene();
- const total = totalBuildBytes();
- console.log(`wechat build size: ${total} bytes (${(total / 1024 / 1024).toFixed(2)} MB)`);
|