From 4decb3d60592dec956a32f86b85309ff2fe3e9c2 Mon Sep 17 00:00:00 2001 From: Haoyu Xu Date: Fri, 20 Jan 2023 17:21:08 -0500 Subject: [PATCH] feat(runner): add parallel building --- libs/append.js | 10 ++--- libs/assets_processor.js | 12 +++--- libs/config.js | 5 +-- libs/env_generator.js | 4 +- libs/initializer.js | 8 ++-- libs/project_json.js | 19 +++++----- libs/vite.js | 39 -------------------- runner.js | 35 +++++------------- vite.js | 80 ++++++++++++++++++++++++++++++++++++++++ 9 files changed, 117 insertions(+), 95 deletions(-) delete mode 100644 libs/vite.js create mode 100644 vite.js diff --git a/libs/append.js b/libs/append.js index 972e389..7abe8e4 100644 --- a/libs/append.js +++ b/libs/append.js @@ -1,18 +1,18 @@ import path from 'path' import { appendSync, readSync } from './file.js' -export function appendReadme() { - const operatorConfig = __config.operators[__operator_name] - const projectJson = JSON.parse(readSync(path.join(__dirname, __config.folder.operator, __operator_name, 'project.json'))) +export function appendReadme(operatorName) { + const operatorConfig = __config.operators[operatorName] + const projectJson = JSON.parse(readSync(path.join(__dirname, __config.folder.operator, operatorName, 'project.json'))) appendSync( `\n| ${operatorConfig.title.split(' - ')[0].split('Arknights: ')[1]} | [Link](https://arknights.halyul.dev/${operatorConfig.link}/) | [Link](https://steamcommunity.com/sharedfiles/filedetails/?id=${projectJson.workshopid}) |`, path.join(__dirname, 'README.md') ) } -export function appendMainConfig() { +export function appendMainConfig(operatorName) { appendSync( - `\n ${__operator_name}: !include config/${__operator_name}.yaml`, + `\n ${operatorName}: !include config/${operatorName}.yaml`, path.join(__dirname, 'config.yaml') ) } \ No newline at end of file diff --git a/libs/assets_processor.js b/libs/assets_processor.js index 474d096..b8d14c5 100644 --- a/libs/assets_processor.js +++ b/libs/assets_processor.js @@ -5,19 +5,21 @@ import AlphaComposite from './alpha_composite.js' export default class AssetsProcessor { #operatorSourceFolder #alphaCompositer + #operatorName - constructor() { + constructor(operatorName) { this.#operatorSourceFolder = path.join(__dirname, __config.folder.operator) this.#alphaCompositer = new AlphaComposite() + this.#operatorName = operatorName } async process(extractedDir) { const BASE64_BINARY_PREFIX = 'data:application/octet-stream;base64,' const BASE64_PNG_PREFIX = 'data:image/png;base64,' const assetsJson = {} - const skelFilename = `${__config.operators[__operator_name].filename}.skel` + const skelFilename = `${__config.operators[this.#operatorName].filename}.skel` const skel = await read(path.join(extractedDir, skelFilename), null) - const atlasFilename = `${__config.operators[__operator_name].filename}.atlas` + const atlasFilename = `${__config.operators[this.#operatorName].filename}.atlas` const atlas = await read(path.join(extractedDir, atlasFilename)) const dimensions = atlas.match(new RegExp(/^size:(.*),(.*)/gm))[0].replace('size: ', '').split(',') const matches = atlas.match(new RegExp(/(.*).png/g)) @@ -28,9 +30,9 @@ export default class AssetsProcessor { assetsJson[`./assets/${skelFilename.replace('#', '%23')}`] = BASE64_BINARY_PREFIX + skel.toString('base64') assetsJson[`./assets/${atlasFilename.replace('#', '%23')}`] = BASE64_BINARY_PREFIX + Buffer.from(atlas).toString('base64') - const fallbackFilename = `${__config.operators[__operator_name].fallback_name}.png` + const fallbackFilename = `${__config.operators[this.#operatorName].fallback_name}.png` const fallbackBuffer = await this.#alphaCompositer.process(fallbackFilename, extractedDir) - await write(fallbackBuffer, path.join(this.#operatorSourceFolder, __operator_name, fallbackFilename)) + await write(fallbackBuffer, path.join(this.#operatorSourceFolder, this.#operatorName, fallbackFilename)) return { dimensions, assetsJson diff --git a/libs/config.js b/libs/config.js index 0a87a75..b14d6d9 100644 --- a/libs/config.js +++ b/libs/config.js @@ -2,8 +2,5 @@ import path from 'path' import { read } from './yaml.js' export default function () { - return { - basedir: __dirname, - ...read(path.join(__dirname, 'config.yaml')) - } + return read(path.join(__dirname, 'config.yaml')) } \ No newline at end of file diff --git a/libs/env_generator.js b/libs/env_generator.js index e25220e..5b2f20a 100644 --- a/libs/env_generator.js +++ b/libs/env_generator.js @@ -2,8 +2,8 @@ export default class EnvGenerator { #assets #operatorConfig - constructor(assets) { - this.#operatorConfig = __config.operators[__operator_name] + constructor(operatorName, assets) { + this.#operatorConfig = __config.operators[operatorName] this.#assets = assets } diff --git a/libs/initializer.js b/libs/initializer.js index f72ff61..0d7597b 100644 --- a/libs/initializer.js +++ b/libs/initializer.js @@ -4,12 +4,12 @@ import { read as readYAML } from './yaml.js' import { mkdir, writeSync } from './file.js' import { appendMainConfig } from './append.js' -export default function init(extractedDir) { +export default function init(operatorName, extractedDir) { mkdir(extractedDir) const date = new Date() const template = readYAML(path.join(__dirname, 'config', '_template.yaml')) - template.link = __operator_name + template.link = operatorName template.date = `${date.getFullYear()}/${(date.getMonth() + 1).toString().padStart(2, '0') }` - writeSync(stringify(template), path.join(__dirname, 'config', `${__operator_name}.yaml`)) - appendMainConfig(__operator_name, __dirname) + writeSync(stringify(template), path.join(__dirname, 'config', `${operatorName}.yaml`)) + appendMainConfig(operatorName) } \ No newline at end of file diff --git a/libs/project_json.js b/libs/project_json.js index d01a4ff..7160108 100644 --- a/libs/project_json.js +++ b/libs/project_json.js @@ -5,15 +5,14 @@ import { read as readYAML } from './yaml.js' export default class ProjectJson { #json - #config #operatorName #operatorSourceFolder #operatorShareFolder #assets - #rootDir #template - constructor(operatorShareFolder, assets) { + constructor(operatorName, operatorShareFolder, assets) { + this.#operatorName = operatorName this.#operatorSourceFolder = path.join(__dirname, __config.folder.operator) this.#operatorShareFolder = operatorShareFolder this.#assets = assets @@ -29,7 +28,7 @@ export default class ProjectJson { #getPath() { // if exists, do not use the template - const defaultPath = path.join(this.#operatorSourceFolder, __operator_name, 'project.json') + const defaultPath = path.join(this.#operatorSourceFolder, this.#operatorName, 'project.json') if (exists(defaultPath)) { return defaultPath } else { @@ -41,7 +40,7 @@ export default class ProjectJson { this.#json = { ...this.#json, description: this.#template.description, - title: __config.operators[__operator_name].title, + title: __config.operators[this.#operatorName].title, general: { ...this.#json.general, localization: this.#template.localization, @@ -54,7 +53,7 @@ export default class ProjectJson { } #processYAML(template) { - const matcher = new Matcher(template.description, '${', '}', __config.operators[__operator_name]) + const matcher = new Matcher(template.description, '${', '}', __config.operators[this.#operatorName]) if (matcher.match() !== null) { template.description = matcher.process() } @@ -74,25 +73,25 @@ export default class ProjectJson { { key: "paddingleft", value: { - value: __config.operators[__operator_name].viewport_left + value: __config.operators[this.#operatorName].viewport_left }, }, { key: "paddingright", value: { - value: __config.operators[__operator_name].viewport_right + value: __config.operators[this.#operatorName].viewport_right }, }, { key: "paddingtop", value: { - value: __config.operators[__operator_name].viewport_top + value: __config.operators[this.#operatorName].viewport_top }, }, { key: "paddingbottom", value: { - value: __config.operators[__operator_name].viewport_bottom + value: __config.operators[this.#operatorName].viewport_bottom }, }, ] diff --git a/libs/vite.js b/libs/vite.js deleted file mode 100644 index 7dbf3f3..0000000 --- a/libs/vite.js +++ /dev/null @@ -1,39 +0,0 @@ -import path from 'path' -import { createServer, build } from 'vite' - -export default class Vite { - - dev() { - ; (async () => { - const server = await createServer(this.#viteConfig) - await server.listen() - - server.printUrls() - })() - } - - async build() { - await build(this.#viteConfig) - } - - get #viteConfig() { - return { - base: "", - publicDir: path.resolve(__dirname, __config.folder.release, __operator_name), - root: path.resolve(__dirname), - resolve: { - alias: { - '@': path.resolve(__dirname, './src'), - '!': path.resolve(__dirname, __config.folder.operator, __operator_name), - '#': path.resolve(__config.basedir, __config.folder.operator, __operator_name, `${__config.operators[__operator_name].filename}.json`), - }, - }, - build: { - outDir: path.resolve(__dirname, __config.folder.release, __operator_name), - emptyOutDir: false, - chunkSizeWarningLimit: 10000, - }, - } - } - -} \ No newline at end of file diff --git a/runner.js b/runner.js index 28be689..bd46e2c 100644 --- a/runner.js +++ b/runner.js @@ -1,14 +1,14 @@ import assert from 'assert' import path from 'path' import { fileURLToPath } from 'url' +import { fork } from 'child_process'; import getConfig from './libs/config.js' import ProjectJson from './libs/project_json.js' import EnvGenerator from './libs/env_generator.js' -import { write, rmdir, copy, writeSync, rm } from './libs/file.js' +import { write, rmdir, copy, writeSync } from './libs/file.js' import AssetsProcessor from './libs/assets_processor.js' import init from './libs/initializer.js' import directory from './libs/directory.js' -import Vite from './libs/vite.js' import { appendReadme } from './libs/append.js' import Background from './libs/background.js' @@ -44,7 +44,6 @@ async function main() { assert(OPERATOR_NAMES.length !== 0, 'Please set the operator name.') for (const OPERATOR_NAME of OPERATOR_NAMES) { - global.__operator_name = OPERATOR_NAME const OPERATOR_SOURCE_FOLDER = path.join(__dirname, __config.folder.operator) const OPERATOR_RELEASE_FOLDER = path.join(__dirname, __config.folder.release, OPERATOR_NAME) const SHOWCASE_PUBLIC_ASSSETS_FOLDER = path.join(OPERATOR_RELEASE_FOLDER, "assets") @@ -58,10 +57,10 @@ async function main() { */ switch (op) { case 'init': - init(EXTRACTED_FOLDER) + init(OPERATOR_NAME, EXTRACTED_FOLDER) process.exit(0) case 'readme': - appendReadme() + appendReadme(OPERATOR_NAME) process.exit(0) default: break @@ -69,14 +68,14 @@ async function main() { rmdir(OPERATOR_RELEASE_FOLDER) - const projectJson = new ProjectJson(OPERATOR_SHARE_FOLDER, { + const projectJson = new ProjectJson(OPERATOR_NAME, OPERATOR_SHARE_FOLDER, { backgrounds }) projectJson.load().then((content) => { write(JSON.stringify(content, null, 2), path.join(OPERATOR_RELEASE_FOLDER, 'project.json')) }) - const assetsProcessor = new AssetsProcessor() + const assetsProcessor = new AssetsProcessor(OPERATOR_NAME) assetsProcessor.process(EXTRACTED_FOLDER).then((content) => { write(JSON.stringify(content.assetsJson, null), path.join(OPERATOR_SOURCE_FOLDER, OPERATOR_NAME, `${__config.operators[OPERATOR_NAME].filename}.json`)) }) @@ -108,27 +107,11 @@ async function main() { copy(path.join(file.source, file.filename), path.join(file.target, file.filename)) }) - const envPath = path.join(__dirname, '.env') - writeSync((new EnvGenerator({ + const envPath = path.join(OPERATOR_SOURCE_FOLDER, OPERATOR_NAME, '.env') + writeSync((new EnvGenerator(OPERATOR_NAME, { backgrounds })).generate(), envPath) - /** - * dev: run dev server - * build: build assets - */ - const vite = new Vite(__config, OPERATOR_NAME, __dirname) - switch (op) { - case 'dev': - vite.dev() - break - case 'build': - case 'build-all': - await vite.build() - rm(envPath) - break - default: - break - } + fork(path.join(__dirname, 'vite.js'), [op, OPERATOR_NAME]) } } diff --git a/vite.js b/vite.js new file mode 100644 index 0000000..74b24dd --- /dev/null +++ b/vite.js @@ -0,0 +1,80 @@ +import path from 'path' +import { fileURLToPath } from 'url' +import { createServer, build, loadEnv } from 'vite' +import getConfig from './libs/config.js' +import { rm } from './libs/file.js' + +global.__dirname = path.dirname(fileURLToPath(import.meta.url)) + +export default class Vite { + #operatorName = process.argv[3] + #config = getConfig() + + dev() { + ; (async () => { + this.#loadEnvFromEnvFile('development') + const server = await createServer(this.#viteConfig) + await server.listen() + + server.printUrls() + })() + } + + build() { + ; (async () => { + this.#loadEnvFromEnvFile('production') + console.log("Building", this.#operatorName, "...") + await build({ + ...this.#viteConfig, + logLevel: 'silent', + }) + })() + + } + + #loadEnvFromEnvFile(mode) { + const envPath = path.join(__dirname, this.#config.folder.operator, this.#operatorName) + process.env = { ...loadEnv(mode, envPath) } + rm(path.join(envPath, '.env')) + } + + get #viteConfig() { + return { + base: "", + publicDir: path.resolve(__dirname, this.#config.folder.release, this.#operatorName), + root: path.resolve(__dirname), + resolve: { + alias: { + '@': path.resolve(__dirname, './src'), + '!': path.resolve(__dirname, this.#config.folder.operator, this.#operatorName), + '#': path.resolve(__dirname, this.#config.folder.operator, this.#operatorName, `${this.#config.operators[this.#operatorName].filename}.json`), + }, + }, + build: { + outDir: path.resolve(__dirname, this.#config.folder.release, this.#operatorName), + emptyOutDir: false, + chunkSizeWarningLimit: 10000, + }, + } + } + +} + +function main() { + const MODE = process.argv[2] + const vite = new Vite() + + switch (MODE) { + case 'dev': + vite.dev() + break + case 'build': + case 'build-all': + vite.build() + break + default: + break + } +} + +main() \ No newline at end of file