210 lines
6.0 KiB
JavaScript
210 lines
6.0 KiB
JavaScript
|
|
#!/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 };
|