更改为es2020模块适应Cocos/laya引擎
This commit is contained in:
1108
source/package-lock.json
generated
1108
source/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@esengine/ecs-framework",
|
"name": "@esengine/ecs-framework",
|
||||||
"version": "2.1.0",
|
"version": "2.1.6",
|
||||||
"description": "用于Laya、Cocos等游戏引擎的高性能ECS框架",
|
"description": "用于Laya、Cocos等游戏引擎的高性能ECS框架",
|
||||||
"main": "bin/index.js",
|
"main": "bin/index.js",
|
||||||
"types": "bin/index.d.ts",
|
"types": "bin/index.d.ts",
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
"egret"
|
"egret"
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"clean": "rimraf bin wasm",
|
"clean": "rimraf bin wasm dist",
|
||||||
"clean:wasm": "rimraf src/wasm/rust-ecs-core/pkg src/wasm/rust-ecs-core/target",
|
"clean:wasm": "rimraf src/wasm/rust-ecs-core/pkg src/wasm/rust-ecs-core/target",
|
||||||
"build:wasm": "cd src/wasm/rust-ecs-core && wasm-pack build --target web --out-dir ../../../bin/wasm --release",
|
"build:wasm": "cd src/wasm/rust-ecs-core && wasm-pack build --target web --out-dir ../../../bin/wasm --release",
|
||||||
"build:ts": "tsc",
|
"build:ts": "tsc",
|
||||||
@@ -27,21 +27,27 @@
|
|||||||
"build": "npm run build:wasm && npm run build:ts",
|
"build": "npm run build:wasm && npm run build:ts",
|
||||||
"build:watch": "tsc --watch",
|
"build:watch": "tsc --watch",
|
||||||
"rebuild": "npm run clean && npm run clean:wasm && npm run build",
|
"rebuild": "npm run clean && npm run clean:wasm && npm run build",
|
||||||
|
"bundle": "npm run build && node scripts/bundle.js",
|
||||||
|
"compress": "npm run build && node scripts/compress.js",
|
||||||
|
"package": "npm run bundle && npm run compress",
|
||||||
|
"build:npm": "npm run build && node scripts/build-single.js",
|
||||||
"test:benchmark": "npm run build && node bin/Testing/Performance/benchmark.js",
|
"test:benchmark": "npm run build && node bin/Testing/Performance/benchmark.js",
|
||||||
"test:unit": "npm run build && node bin/Testing/test-runner.js",
|
"test:unit": "npm run build && node bin/Testing/test-runner.js",
|
||||||
"benchmark": "node scripts/benchmark.js",
|
"benchmark": "node scripts/benchmark.js",
|
||||||
"preversion": "npm run rebuild",
|
"preversion": "npm run rebuild",
|
||||||
"postversion": "npm publish",
|
"publish:patch": "npm version patch && npm run build:npm && cd dist && npm publish",
|
||||||
"publish:patch": "npm version patch",
|
"publish:minor": "npm version minor && npm run build:npm && cd dist && npm publish",
|
||||||
"publish:minor": "npm version minor",
|
"publish:major": "npm version major && npm run build:npm && cd dist && npm publish",
|
||||||
"publish:major": "npm version major",
|
"publish:npm": "npm run build:npm && cd dist && npm publish"
|
||||||
"publish": "npm publish"
|
|
||||||
},
|
},
|
||||||
"author": "yhh",
|
"author": "yhh",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^20.19.0",
|
"@types/node": "^20.19.0",
|
||||||
|
"archiver": "^7.0.1",
|
||||||
|
"esbuild": "^0.25.5",
|
||||||
"rimraf": "^5.0.0",
|
"rimraf": "^5.0.0",
|
||||||
|
"terser": "^5.41.0",
|
||||||
"typescript": "^5.8.3"
|
"typescript": "^5.8.3"
|
||||||
},
|
},
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
@@ -50,6 +56,5 @@
|
|||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/esengine/ecs-framework.git"
|
"url": "https://github.com/esengine/ecs-framework.git"
|
||||||
},
|
}
|
||||||
"optionalDependencies": {}
|
|
||||||
}
|
}
|
||||||
|
|||||||
279
source/scripts/build-single.js
Normal file
279
source/scripts/build-single.js
Normal file
@@ -0,0 +1,279 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
const esbuild = require('esbuild');
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ECS Framework 单文件构建脚本
|
||||||
|
* 专门用于npm包发布的单文件版本
|
||||||
|
*/
|
||||||
|
|
||||||
|
const config = {
|
||||||
|
// 输入配置
|
||||||
|
entryPoint: './bin/index.js',
|
||||||
|
|
||||||
|
// 输出配置
|
||||||
|
outputDir: './dist',
|
||||||
|
outputFile: 'index.js',
|
||||||
|
|
||||||
|
// 压缩配置
|
||||||
|
minify: true,
|
||||||
|
sourcemap: true,
|
||||||
|
|
||||||
|
// 目标环境 - 适配更多平台
|
||||||
|
target: ['es2017'],
|
||||||
|
format: 'esm',
|
||||||
|
|
||||||
|
// npm包配置
|
||||||
|
generatePackageJson: true,
|
||||||
|
generateTypes: true
|
||||||
|
};
|
||||||
|
|
||||||
|
async function buildSingleFile() {
|
||||||
|
console.log('🚀 构建单文件npm包...');
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 确保输出目录存在
|
||||||
|
if (!fs.existsSync(config.outputDir)) {
|
||||||
|
fs.mkdirSync(config.outputDir, { recursive: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
// 第一步:使用esbuild打包
|
||||||
|
console.log('📦 使用 esbuild 打包...');
|
||||||
|
|
||||||
|
const result = await esbuild.build({
|
||||||
|
entryPoints: [config.entryPoint],
|
||||||
|
bundle: true,
|
||||||
|
minify: config.minify,
|
||||||
|
sourcemap: config.sourcemap,
|
||||||
|
target: config.target,
|
||||||
|
format: config.format,
|
||||||
|
outfile: path.join(config.outputDir, config.outputFile),
|
||||||
|
platform: 'neutral', // 支持多平台
|
||||||
|
|
||||||
|
// 外部依赖
|
||||||
|
external: [],
|
||||||
|
|
||||||
|
// 定义全局变量
|
||||||
|
define: {
|
||||||
|
'process.env.NODE_ENV': '"production"'
|
||||||
|
},
|
||||||
|
|
||||||
|
// 元信息
|
||||||
|
metafile: true,
|
||||||
|
|
||||||
|
// 日志级别
|
||||||
|
logLevel: 'info',
|
||||||
|
|
||||||
|
// 保持类名(便于调试)
|
||||||
|
keepNames: true,
|
||||||
|
|
||||||
|
// 生成更兼容的代码
|
||||||
|
legalComments: 'none'
|
||||||
|
});
|
||||||
|
|
||||||
|
// 显示打包结果
|
||||||
|
if (result.metafile) {
|
||||||
|
const analysis = await esbuild.analyzeMetafile(result.metafile);
|
||||||
|
console.log('📊 打包分析:');
|
||||||
|
console.log(analysis);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 第二步:生成类型定义文件
|
||||||
|
if (config.generateTypes) {
|
||||||
|
console.log('📝 生成类型定义文件...');
|
||||||
|
await generateTypeDefinitions();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 第三步:生成package.json
|
||||||
|
if (config.generatePackageJson) {
|
||||||
|
console.log('📋 生成package.json...');
|
||||||
|
await generatePackageJson();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 第四步:复制必要文件
|
||||||
|
await copyEssentialFiles();
|
||||||
|
|
||||||
|
console.log('✅ 单文件构建完成!');
|
||||||
|
console.log(`📄 主文件: ${path.join(config.outputDir, config.outputFile)}`);
|
||||||
|
|
||||||
|
// 显示文件大小
|
||||||
|
const stats = fs.statSync(path.join(config.outputDir, config.outputFile));
|
||||||
|
console.log(`📏 文件大小: ${(stats.size / 1024).toFixed(2)} KB`);
|
||||||
|
|
||||||
|
console.log('\n🚀 发布到npm:');
|
||||||
|
console.log('cd dist && npm publish');
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('❌ 构建失败:', error);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成类型定义文件
|
||||||
|
*/
|
||||||
|
async function generateTypeDefinitions() {
|
||||||
|
const sourceTypesFile = './bin/index.d.ts';
|
||||||
|
const targetTypesFile = path.join(config.outputDir, 'index.d.ts');
|
||||||
|
|
||||||
|
if (fs.existsSync(sourceTypesFile)) {
|
||||||
|
// 读取原始类型定义
|
||||||
|
let typesContent = fs.readFileSync(sourceTypesFile, 'utf8');
|
||||||
|
|
||||||
|
// 处理相对路径导入,将其转换为绝对导入
|
||||||
|
typesContent = typesContent.replace(/from ['"]\.\//g, "from './");
|
||||||
|
typesContent = typesContent.replace(/from ['"]\.\.\//g, "from './");
|
||||||
|
|
||||||
|
// 添加版本信息注释
|
||||||
|
const header = `/**
|
||||||
|
* @esengine/ecs-framework
|
||||||
|
* 高性能ECS框架 - 适用于Cocos Creator和Laya引擎
|
||||||
|
* 版本: ${require('../package.json').version}
|
||||||
|
* 构建时间: ${new Date().toISOString()}
|
||||||
|
*/
|
||||||
|
|
||||||
|
`;
|
||||||
|
|
||||||
|
fs.writeFileSync(targetTypesFile, header + typesContent);
|
||||||
|
console.log(` ✓ 生成: ${targetTypesFile}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成npm包的package.json
|
||||||
|
*/
|
||||||
|
async function generatePackageJson() {
|
||||||
|
const sourcePackage = require('../package.json');
|
||||||
|
|
||||||
|
// 创建完全干净的package.json,只包含发布必需的字段
|
||||||
|
const distPackage = {};
|
||||||
|
|
||||||
|
// 按顺序添加字段,确保没有任何开发相关字段
|
||||||
|
distPackage.name = sourcePackage.name;
|
||||||
|
distPackage.version = sourcePackage.version;
|
||||||
|
distPackage.description = sourcePackage.description;
|
||||||
|
distPackage.main = 'index.js';
|
||||||
|
distPackage.types = 'index.d.ts';
|
||||||
|
distPackage.module = 'index.js';
|
||||||
|
distPackage.type = 'module';
|
||||||
|
|
||||||
|
// 导出配置
|
||||||
|
distPackage.exports = {
|
||||||
|
".": {
|
||||||
|
"import": "./index.js",
|
||||||
|
"types": "./index.d.ts"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 文件配置
|
||||||
|
distPackage.files = [
|
||||||
|
'index.js',
|
||||||
|
'index.js.map',
|
||||||
|
'index.d.ts',
|
||||||
|
'wasm/**/*',
|
||||||
|
'README.md',
|
||||||
|
'LICENSE'
|
||||||
|
];
|
||||||
|
|
||||||
|
// 关键词
|
||||||
|
distPackage.keywords = [
|
||||||
|
...sourcePackage.keywords,
|
||||||
|
'single-file',
|
||||||
|
'bundled',
|
||||||
|
'minified'
|
||||||
|
];
|
||||||
|
|
||||||
|
// 元信息
|
||||||
|
distPackage.author = sourcePackage.author;
|
||||||
|
distPackage.license = sourcePackage.license;
|
||||||
|
|
||||||
|
// Repository信息
|
||||||
|
distPackage.repository = {
|
||||||
|
type: 'git',
|
||||||
|
url: 'git+https://github.com/esengine/ecs-framework.git'
|
||||||
|
};
|
||||||
|
|
||||||
|
// 发布配置
|
||||||
|
distPackage.publishConfig = {
|
||||||
|
access: 'public'
|
||||||
|
};
|
||||||
|
|
||||||
|
// 引擎兼容性
|
||||||
|
distPackage.engines = {
|
||||||
|
node: '>=16.0.0'
|
||||||
|
};
|
||||||
|
|
||||||
|
const packagePath = path.join(config.outputDir, 'package.json');
|
||||||
|
fs.writeFileSync(packagePath, JSON.stringify(distPackage, null, 2));
|
||||||
|
console.log(` ✓ 生成: ${packagePath}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 复制必要文件
|
||||||
|
*/
|
||||||
|
async function copyEssentialFiles() {
|
||||||
|
console.log('📁 复制必要文件...');
|
||||||
|
|
||||||
|
const filesToCopy = [
|
||||||
|
{ src: '../README.md', dest: 'README.md' },
|
||||||
|
{ src: '../LICENSE', dest: 'LICENSE', optional: true }
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const file of filesToCopy) {
|
||||||
|
const srcPath = path.resolve(file.src);
|
||||||
|
const destPath = path.join(config.outputDir, file.dest);
|
||||||
|
|
||||||
|
if (fs.existsSync(srcPath)) {
|
||||||
|
fs.copyFileSync(srcPath, destPath);
|
||||||
|
console.log(` ✓ 复制: ${file.dest}`);
|
||||||
|
} else if (!file.optional) {
|
||||||
|
console.warn(` ⚠️ 文件不存在: ${srcPath}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 复制WASM文件
|
||||||
|
await copyWasmFiles();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 复制WASM文件
|
||||||
|
*/
|
||||||
|
async function copyWasmFiles() {
|
||||||
|
const wasmSrcDir = './bin/wasm';
|
||||||
|
const wasmDestDir = path.join(config.outputDir, 'wasm');
|
||||||
|
|
||||||
|
if (fs.existsSync(wasmSrcDir)) {
|
||||||
|
console.log('📦 复制WASM文件...');
|
||||||
|
|
||||||
|
// 创建目标目录
|
||||||
|
if (!fs.existsSync(wasmDestDir)) {
|
||||||
|
fs.mkdirSync(wasmDestDir, { recursive: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
// 复制所有WASM相关文件
|
||||||
|
const wasmFiles = fs.readdirSync(wasmSrcDir);
|
||||||
|
for (const file of wasmFiles) {
|
||||||
|
// 排除.gitignore文件
|
||||||
|
if (file === '.gitignore') continue;
|
||||||
|
|
||||||
|
const srcPath = path.join(wasmSrcDir, file);
|
||||||
|
const destPath = path.join(wasmDestDir, file);
|
||||||
|
|
||||||
|
if (fs.statSync(srcPath).isFile()) {
|
||||||
|
fs.copyFileSync(srcPath, destPath);
|
||||||
|
console.log(` ✓ 复制WASM: ${file}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.warn(' ⚠️ WASM目录不存在: ' + wasmSrcDir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 运行构建
|
||||||
|
if (require.main === module) {
|
||||||
|
buildSingleFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { buildSingleFile, config };
|
||||||
210
source/scripts/bundle.js
Normal file
210
source/scripts/bundle.js
Normal file
@@ -0,0 +1,210 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
const esbuild = require('esbuild');
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
const { minify } = require('terser');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ECS Framework 打包脚本
|
||||||
|
* 将bin目录中的所有文件合并成一个压缩文件
|
||||||
|
*/
|
||||||
|
|
||||||
|
const config = {
|
||||||
|
// 输入配置
|
||||||
|
entryPoint: './bin/index.js',
|
||||||
|
|
||||||
|
// 输出配置
|
||||||
|
outputDir: './dist',
|
||||||
|
outputFile: 'ecs-framework.min.js',
|
||||||
|
|
||||||
|
// 压缩配置
|
||||||
|
minify: true,
|
||||||
|
sourcemap: true,
|
||||||
|
|
||||||
|
// 包含WASM文件
|
||||||
|
includeWasm: true,
|
||||||
|
|
||||||
|
// 目标环境
|
||||||
|
target: ['es2017'],
|
||||||
|
format: 'esm'
|
||||||
|
};
|
||||||
|
|
||||||
|
async function createBundle() {
|
||||||
|
console.log('🚀 开始打包 ECS Framework...');
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 确保输出目录存在
|
||||||
|
if (!fs.existsSync(config.outputDir)) {
|
||||||
|
fs.mkdirSync(config.outputDir, { recursive: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
// 第一步:使用esbuild打包
|
||||||
|
console.log('📦 使用 esbuild 打包...');
|
||||||
|
|
||||||
|
const result = await esbuild.build({
|
||||||
|
entryPoints: [config.entryPoint],
|
||||||
|
bundle: true,
|
||||||
|
minify: config.minify,
|
||||||
|
sourcemap: config.sourcemap,
|
||||||
|
target: config.target,
|
||||||
|
format: config.format,
|
||||||
|
outfile: path.join(config.outputDir, config.outputFile),
|
||||||
|
platform: 'browser',
|
||||||
|
|
||||||
|
// 外部依赖(如果有的话)
|
||||||
|
external: [],
|
||||||
|
|
||||||
|
// 定义全局变量
|
||||||
|
define: {
|
||||||
|
'process.env.NODE_ENV': '"production"'
|
||||||
|
},
|
||||||
|
|
||||||
|
// 处理WASM文件
|
||||||
|
loader: {
|
||||||
|
'.wasm': 'binary'
|
||||||
|
},
|
||||||
|
|
||||||
|
// 插件配置
|
||||||
|
plugins: [
|
||||||
|
{
|
||||||
|
name: 'wasm-loader',
|
||||||
|
setup(build) {
|
||||||
|
// 处理WASM文件导入
|
||||||
|
build.onLoad({ filter: /\.wasm$/ }, async (args) => {
|
||||||
|
const wasmBuffer = await fs.promises.readFile(args.path);
|
||||||
|
const base64 = wasmBuffer.toString('base64');
|
||||||
|
|
||||||
|
return {
|
||||||
|
contents: `
|
||||||
|
const wasmBase64 = "${base64}";
|
||||||
|
const wasmBinary = Uint8Array.from(atob(wasmBase64), c => c.charCodeAt(0));
|
||||||
|
export default wasmBinary;
|
||||||
|
`,
|
||||||
|
loader: 'js'
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
// 元信息
|
||||||
|
metafile: true,
|
||||||
|
|
||||||
|
// 日志级别
|
||||||
|
logLevel: 'info'
|
||||||
|
});
|
||||||
|
|
||||||
|
// 显示打包结果
|
||||||
|
if (result.metafile) {
|
||||||
|
const analysis = await esbuild.analyzeMetafile(result.metafile);
|
||||||
|
console.log('📊 打包分析:');
|
||||||
|
console.log(analysis);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 第二步:复制WASM文件到dist目录
|
||||||
|
if (config.includeWasm) {
|
||||||
|
console.log('📁 复制 WASM 文件...');
|
||||||
|
await copyWasmFiles();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 第三步:生成压缩包信息
|
||||||
|
await generateBundleInfo();
|
||||||
|
|
||||||
|
console.log('✅ 打包完成!');
|
||||||
|
console.log(`📄 输出文件: ${path.join(config.outputDir, config.outputFile)}`);
|
||||||
|
|
||||||
|
// 显示文件大小
|
||||||
|
const stats = fs.statSync(path.join(config.outputDir, config.outputFile));
|
||||||
|
console.log(`📏 文件大小: ${(stats.size / 1024).toFixed(2)} KB`);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('❌ 打包失败:', error);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 复制WASM文件到dist目录
|
||||||
|
*/
|
||||||
|
async function copyWasmFiles() {
|
||||||
|
const wasmDir = './bin/wasm';
|
||||||
|
const distWasmDir = path.join(config.outputDir, 'wasm');
|
||||||
|
|
||||||
|
if (fs.existsSync(wasmDir)) {
|
||||||
|
if (!fs.existsSync(distWasmDir)) {
|
||||||
|
fs.mkdirSync(distWasmDir, { recursive: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
const wasmFiles = fs.readdirSync(wasmDir);
|
||||||
|
for (const file of wasmFiles) {
|
||||||
|
// 排除 .gitignore 文件
|
||||||
|
if (file === '.gitignore') {
|
||||||
|
console.log(` ⏭️ 跳过: ${file}`);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const srcPath = path.join(wasmDir, file);
|
||||||
|
const destPath = path.join(distWasmDir, file);
|
||||||
|
|
||||||
|
if (fs.statSync(srcPath).isFile()) {
|
||||||
|
fs.copyFileSync(srcPath, destPath);
|
||||||
|
console.log(` ✓ 复制: ${file}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成打包信息文件
|
||||||
|
*/
|
||||||
|
async function generateBundleInfo() {
|
||||||
|
const bundleInfo = {
|
||||||
|
name: '@esengine/ecs-framework',
|
||||||
|
version: require('../package.json').version,
|
||||||
|
buildTime: new Date().toISOString(),
|
||||||
|
files: {
|
||||||
|
main: config.outputFile,
|
||||||
|
sourcemap: config.outputFile + '.map',
|
||||||
|
wasm: 'wasm/'
|
||||||
|
},
|
||||||
|
target: config.target,
|
||||||
|
format: config.format,
|
||||||
|
minified: config.minify,
|
||||||
|
size: {
|
||||||
|
main: fs.statSync(path.join(config.outputDir, config.outputFile)).size,
|
||||||
|
wasm: getWasmSize()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const infoPath = path.join(config.outputDir, 'bundle-info.json');
|
||||||
|
fs.writeFileSync(infoPath, JSON.stringify(bundleInfo, null, 2));
|
||||||
|
console.log(`📋 生成打包信息: ${infoPath}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取WASM文件总大小
|
||||||
|
*/
|
||||||
|
function getWasmSize() {
|
||||||
|
const wasmDir = path.join(config.outputDir, 'wasm');
|
||||||
|
let totalSize = 0;
|
||||||
|
|
||||||
|
if (fs.existsSync(wasmDir)) {
|
||||||
|
const files = fs.readdirSync(wasmDir);
|
||||||
|
for (const file of files) {
|
||||||
|
const filePath = path.join(wasmDir, file);
|
||||||
|
if (fs.statSync(filePath).isFile()) {
|
||||||
|
totalSize += fs.statSync(filePath).size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return totalSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 运行打包
|
||||||
|
if (require.main === module) {
|
||||||
|
createBundle();
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { createBundle, config };
|
||||||
165
source/scripts/compress.js
Normal file
165
source/scripts/compress.js
Normal file
@@ -0,0 +1,165 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
const archiver = require('archiver');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ECS Framework 压缩脚本
|
||||||
|
* 将bin目录压缩成ZIP文件
|
||||||
|
*/
|
||||||
|
|
||||||
|
const config = {
|
||||||
|
sourceDir: './bin',
|
||||||
|
outputDir: './dist',
|
||||||
|
outputFile: 'ecs-framework-bin.zip',
|
||||||
|
compressionLevel: 9, // 最高压缩级别
|
||||||
|
includeSourceMaps: false // 是否包含source map文件
|
||||||
|
};
|
||||||
|
|
||||||
|
async function createCompressedArchive() {
|
||||||
|
console.log('🗜️ 开始压缩 bin 目录...');
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 确保输出目录存在
|
||||||
|
if (!fs.existsSync(config.outputDir)) {
|
||||||
|
fs.mkdirSync(config.outputDir, { recursive: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
const outputPath = path.join(config.outputDir, config.outputFile);
|
||||||
|
const output = fs.createWriteStream(outputPath);
|
||||||
|
const archive = archiver('zip', {
|
||||||
|
zlib: { level: config.compressionLevel }
|
||||||
|
});
|
||||||
|
|
||||||
|
// 监听事件
|
||||||
|
output.on('close', () => {
|
||||||
|
const sizeKB = (archive.pointer() / 1024).toFixed(2);
|
||||||
|
console.log('✅ 压缩完成!');
|
||||||
|
console.log(`📄 输出文件: ${outputPath}`);
|
||||||
|
console.log(`📏 压缩后大小: ${sizeKB} KB`);
|
||||||
|
console.log(`📊 压缩了 ${archive.pointer()} 字节`);
|
||||||
|
|
||||||
|
// 生成压缩信息
|
||||||
|
generateCompressionInfo(outputPath, archive.pointer());
|
||||||
|
});
|
||||||
|
|
||||||
|
output.on('end', () => {
|
||||||
|
console.log('数据已全部写入');
|
||||||
|
});
|
||||||
|
|
||||||
|
archive.on('warning', (err) => {
|
||||||
|
if (err.code === 'ENOENT') {
|
||||||
|
console.warn('⚠️ 警告:', err);
|
||||||
|
} else {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
archive.on('error', (err) => {
|
||||||
|
throw err;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 连接输出流
|
||||||
|
archive.pipe(output);
|
||||||
|
|
||||||
|
// 添加bin目录中的所有文件
|
||||||
|
console.log('📁 添加文件到压缩包...');
|
||||||
|
|
||||||
|
// 递归添加目录
|
||||||
|
archive.directory(config.sourceDir, false, (entry) => {
|
||||||
|
// 过滤文件
|
||||||
|
if (!config.includeSourceMaps && entry.name.endsWith('.map')) {
|
||||||
|
console.log(` ⏭️ 跳过: ${entry.name}`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 排除 .gitignore 文件
|
||||||
|
if (entry.name === '.gitignore' || entry.name.endsWith('/.gitignore')) {
|
||||||
|
console.log(` ⏭️ 跳过: ${entry.name}`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(` ✓ 添加: ${entry.name}`);
|
||||||
|
return entry;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 完成压缩
|
||||||
|
await archive.finalize();
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('❌ 压缩失败:', error);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成压缩信息文件
|
||||||
|
*/
|
||||||
|
function generateCompressionInfo(outputPath, compressedSize) {
|
||||||
|
const originalSize = getDirectorySize(config.sourceDir);
|
||||||
|
const compressionRatio = ((originalSize - compressedSize) / originalSize * 100).toFixed(2);
|
||||||
|
|
||||||
|
const compressionInfo = {
|
||||||
|
name: '@esengine/ecs-framework',
|
||||||
|
version: require('../package.json').version,
|
||||||
|
compressionTime: new Date().toISOString(),
|
||||||
|
files: {
|
||||||
|
archive: config.outputFile
|
||||||
|
},
|
||||||
|
size: {
|
||||||
|
original: originalSize,
|
||||||
|
compressed: compressedSize,
|
||||||
|
ratio: `${compressionRatio}%`
|
||||||
|
},
|
||||||
|
settings: {
|
||||||
|
compressionLevel: config.compressionLevel,
|
||||||
|
includeSourceMaps: config.includeSourceMaps
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const infoPath = path.join(config.outputDir, 'compression-info.json');
|
||||||
|
fs.writeFileSync(infoPath, JSON.stringify(compressionInfo, null, 2));
|
||||||
|
console.log(`📋 生成压缩信息: ${infoPath}`);
|
||||||
|
console.log(`📈 压缩率: ${compressionRatio}%`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取目录总大小
|
||||||
|
*/
|
||||||
|
function getDirectorySize(dirPath) {
|
||||||
|
let totalSize = 0;
|
||||||
|
|
||||||
|
function calculateSize(currentPath) {
|
||||||
|
const stats = fs.statSync(currentPath);
|
||||||
|
|
||||||
|
if (stats.isDirectory()) {
|
||||||
|
const files = fs.readdirSync(currentPath);
|
||||||
|
for (const file of files) {
|
||||||
|
calculateSize(path.join(currentPath, file));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 过滤source map文件
|
||||||
|
if (!config.includeSourceMaps && currentPath.endsWith('.map')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 排除 .gitignore 文件
|
||||||
|
if (currentPath.endsWith('.gitignore')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
totalSize += stats.size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
calculateSize(dirPath);
|
||||||
|
return totalSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 运行压缩
|
||||||
|
if (require.main === module) {
|
||||||
|
createCompressedArchive();
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { createCompressedArchive, config };
|
||||||
@@ -8,10 +8,8 @@ export * from './Emitter';
|
|||||||
export * from './GlobalManager';
|
export * from './GlobalManager';
|
||||||
export * from './PerformanceMonitor';
|
export * from './PerformanceMonitor';
|
||||||
export { Time } from './Time';
|
export { Time } from './Time';
|
||||||
/**
|
|
||||||
* WebAssembly核心模块
|
// WebAssembly核心模块
|
||||||
* 提供高性能的ECS查询和计算功能
|
|
||||||
*/
|
|
||||||
export {
|
export {
|
||||||
WasmEcsCore,
|
WasmEcsCore,
|
||||||
ecsCore,
|
ecsCore,
|
||||||
@@ -20,5 +18,5 @@ export {
|
|||||||
EntityId,
|
EntityId,
|
||||||
ComponentMask,
|
ComponentMask,
|
||||||
QueryResult,
|
QueryResult,
|
||||||
PerformanceStats
|
PerformanceStats as WasmPerformanceStats
|
||||||
} from './WasmCore';
|
} from './WasmCore';
|
||||||
@@ -17,21 +17,6 @@ export { Timer } from './Utils/Timers/Timer';
|
|||||||
// ECS核心组件
|
// ECS核心组件
|
||||||
export * from './ECS';
|
export * from './ECS';
|
||||||
|
|
||||||
// 工具类
|
// 工具类和类型定义
|
||||||
export * from './Utils/Pool';
|
export * from './Utils';
|
||||||
export * from './Utils/PerformanceMonitor';
|
|
||||||
export * from './Utils/Extensions';
|
|
||||||
|
|
||||||
// WebAssembly核心模块
|
|
||||||
export {
|
|
||||||
WasmEcsCore,
|
|
||||||
ecsCore,
|
|
||||||
initializeEcs,
|
|
||||||
Query,
|
|
||||||
EntityId,
|
|
||||||
ComponentMask,
|
|
||||||
QueryResult
|
|
||||||
} from './Utils/WasmCore';
|
|
||||||
|
|
||||||
// 类型定义
|
|
||||||
export * from './Types';
|
export * from './Types';
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "ES2020",
|
"target": "ES2020",
|
||||||
"module": "CommonJS",
|
"module": "ES2020",
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
"lib": ["ES2020", "DOM"],
|
"lib": ["ES2020", "DOM"],
|
||||||
"outDir": "./bin",
|
"outDir": "./bin",
|
||||||
@@ -27,7 +27,10 @@
|
|||||||
"experimentalDecorators": true,
|
"experimentalDecorators": true,
|
||||||
"emitDecoratorMetadata": true,
|
"emitDecoratorMetadata": true,
|
||||||
"importHelpers": false,
|
"importHelpers": false,
|
||||||
"downlevelIteration": true
|
"downlevelIteration": true,
|
||||||
|
"isolatedModules": false,
|
||||||
|
"allowJs": true,
|
||||||
|
"resolveJsonModule": true
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
"src/**/*"
|
"src/**/*"
|
||||||
|
|||||||
Reference in New Issue
Block a user