HumanBreak/script/build.ts

187 lines
6.2 KiB
TypeScript
Raw Normal View History

2022-11-13 18:02:05 +08:00
import fss from 'fs';
2023-05-26 21:39:19 +08:00
import fs from 'fs-extra';
2022-11-13 18:02:05 +08:00
import Fontmin from 'fontmin';
2023-04-15 20:21:29 +08:00
import * as babel from '@babel/core';
2023-04-16 17:05:47 +08:00
import * as rollup from 'rollup';
2023-05-02 15:37:38 +08:00
import typescript from '@rollup/plugin-typescript';
import rollupBabel from '@rollup/plugin-babel';
import terser from '@rollup/plugin-terser';
2023-05-13 22:16:51 +08:00
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
2023-05-31 12:09:47 +08:00
import { splitResorce } from './resource.js';
import compressing from 'compressing';
const map = !!Number(process.argv[2]);
const resorce = !!Number(process.argv[3]);
const compress = !!Number(process.argv[4]);
2022-11-13 18:02:05 +08:00
(async function () {
2023-04-29 11:25:18 +08:00
const timestamp = Date.now();
2022-11-13 18:02:05 +08:00
// 1. 去除未使用的文件
const data = (() => {
const data = fss.readFileSync('./public/project/data.js', 'utf-8');
const json = JSON.parse(
data
.split(/(\n|\r\n)/)
.slice(1)
.join('\n')
);
return json;
})() as { main: Record<string, string[]> };
const main = data.main;
try {
const data = [
['./dist/project/floors', '.js', 'floorIds'],
['./dist/project/bgms', '', 'bgms'],
['./dist/project/sounds', '', 'sounds'],
['./dist/project/images', '', 'images'],
['./dist/project/animates', '.animate', 'animates'],
['./dist/project/tilesets', '', 'tilesets'],
['./dist/project/fonts', '.ttf', 'fonts']
];
await Promise.all(
data.map(async v => {
const all = await fs.readdir(`${v[0]}`);
const data = main[v[2]].map(vv => vv + v[1]);
all.forEach(async vv => {
if (!data.includes(vv)) {
await fs.rm(`${v[0]}/${vv}`);
}
});
})
);
2023-05-31 12:09:47 +08:00
if (!map) await fs.remove('./dist/maps/');
2023-04-16 17:05:47 +08:00
// 在线查看什么都看不到,这编辑器难道还需要留着吗?
2023-05-26 21:39:19 +08:00
await fs.remove('./dist/_server');
await fs.remove('./dist/editor.html');
await fs.remove('./dist/server.cjs');
2022-11-13 18:02:05 +08:00
} catch {}
// 2. 压缩字体
try {
// 获取要压缩的文字列表libs & projects下的所有js文件
let texts = ``;
const exclude = `\n \t`;
const libs = await fs.readdir('./public/libs');
const project = await fs.readdir('./public/project');
const floors = await fs.readdir('./public/project/floors');
const assets = await fs.readdir('./dist/assets/');
const all = [
...libs.map(v => `./public/libs/${v}`),
...project.map(v => `./public/project/${v}`),
...floors.map(v => `./public/project/floors/${v}`),
2023-05-31 12:09:47 +08:00
...assets.map(v => `./dist/assets/${v}`)
2022-11-13 18:02:05 +08:00
];
for await (const dir of all) {
const stat = await fs.stat(dir);
if (!stat.isFile()) continue;
2023-04-28 17:09:16 +08:00
if (dir.endsWith('.ttf')) continue;
2022-11-13 18:02:05 +08:00
const file = await fs.readFile(dir, 'utf-8');
for (let i = 0; i < file.length; i++) {
const char = file[i];
if (!texts.includes(char) && !exclude.includes(char))
texts += char;
}
}
// 获取所有字体(直接压缩字体会报错
const fonts = main.fonts;
await Promise.all([
...fonts.map(v =>
(async () => {
const fontmin = new Fontmin();
fontmin
.src<string>(`./public/project/fonts/${v}.ttf`)
.dest('./dist/project/fonts')
.use(
Fontmin.glyph({
text: texts
})
);
await new Promise(res => {
fontmin.run(err => {
if (err) throw err;
res('');
});
});
})()
)
]);
2023-04-29 11:25:18 +08:00
await Promise.all([
...fonts.map(v => {
2023-05-26 21:39:19 +08:00
return fs.rename(
2023-04-29 11:25:18 +08:00
`./dist/project/fonts/${v}.ttf`,
`./dist/project/fonts/${v}-${timestamp}.ttf`
);
})
]);
2022-11-13 18:02:05 +08:00
} catch (e) {
2023-05-31 12:09:47 +08:00
console.log('字体压缩失败');
2022-11-13 18:02:05 +08:00
}
2023-02-27 20:39:59 +08:00
// 3. 压缩js插件
try {
2023-05-26 21:39:19 +08:00
await fs.remove('./dist/project/plugin.min.js');
2023-05-02 15:37:38 +08:00
2023-04-16 17:05:47 +08:00
const build = await rollup.rollup({
2023-05-02 15:37:38 +08:00
input: 'src/plugin/game/index.js',
plugins: [
typescript({
sourceMap: false
}),
rollupBabel({
babelHelpers: 'bundled',
sourceType: 'module'
}),
2023-05-13 22:16:51 +08:00
terser(),
resolve(),
commonjs()
2023-05-02 15:37:38 +08:00
]
2023-02-27 20:39:59 +08:00
});
2023-05-02 15:37:38 +08:00
await build.write({
2023-04-16 17:05:47 +08:00
format: 'iife',
2023-05-02 15:37:38 +08:00
name: 'CorePlugin',
file: './dist/project/plugin.min.js'
2023-04-16 17:05:47 +08:00
});
2023-05-26 21:39:19 +08:00
await fs.remove('./dist/project/plugin/');
2023-04-16 17:05:47 +08:00
} catch (e) {
2023-02-27 20:39:59 +08:00
console.log('压缩插件失败');
}
2023-02-28 18:21:29 +08:00
// 4. 压缩main.js
try {
// 先获取不能压缩的部分
2023-04-29 11:25:18 +08:00
const main = (await fs.readFile('./public/main.js', 'utf-8'))
.replace(
/this.pluginUseCompress\s*=\s*false\;/,
'this.pluginUseCompress = true;'
)
.replace('this.timestamp = 0', `this.timestamp = ${timestamp};`);
2023-04-16 17:30:22 +08:00
2023-02-28 18:21:29 +08:00
const endIndex = main.indexOf('// >>>> body end');
const nonCompress = main.slice(0, endIndex);
const needCompress = main.slice(endIndex + 17);
2023-04-16 17:05:47 +08:00
const compressed = babel.transformSync(needCompress)?.code;
await fs.writeFile('./dist/main.js', nonCompress + compressed, 'utf-8');
2023-02-28 18:21:29 +08:00
} catch {
console.log('main.js压缩失败');
}
2023-04-28 17:09:16 +08:00
// 5. 杂项
try {
2023-05-26 21:39:19 +08:00
await fs.copy('./LICENSE', './dist/LICENSE');
2023-04-28 17:09:16 +08:00
} catch {}
2023-05-31 12:09:47 +08:00
// 6. 资源分离
if (resorce) {
await splitResorce(compress);
}
// 7. 压缩本体
if (compress) {
await fs.ensureDir('./out');
await compressing.zip.compressDir('./dist', './out/dist.zip');
}
2022-11-13 18:02:05 +08:00
})();