From 04941936bc46b483716943229f8e61e5e2cae16d Mon Sep 17 00:00:00 2001 From: undefined Date: Tue, 5 May 2020 11:10:14 +0800 Subject: [PATCH] =?UTF-8?q?=E6=89=93=E5=8C=85=E6=A8=A1=E5=9D=97=E4=B8=BA?= =?UTF-8?q?=E5=8D=95=E4=B8=AA=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build/buildModule.js | 30 +++++++++++++++++ build/buildTemplate.js | 15 --------- build/index.js | 21 ++++++++++-- build/locales.js | 14 -------- build/template.js | 4 +++ hydro/loader.js | 76 +++++++++++++++++++----------------------- 6 files changed, 88 insertions(+), 72 deletions(-) delete mode 100644 build/buildTemplate.js delete mode 100644 build/locales.js diff --git a/build/buildModule.js b/build/buildModule.js index b1b0c2da9..f5679bfd8 100644 --- a/build/buildModule.js +++ b/build/buildModule.js @@ -2,6 +2,7 @@ /* eslint-disable import/no-extraneous-dependencies */ /* eslint-disable no-await-in-loop */ const fs = require('fs'); +const zlib = require('zlib'); const webpack = require('webpack'); const yaml = require('js-yaml'); const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin'); @@ -54,6 +55,35 @@ const build = async (type) => { resolve(); }); }); + for (const i of modules) { + if (!i.startsWith('.')) { + const current = {}; + if (exist(`module/${i}/locale`)) { + const locales = fs.readdirSync(root(`module/${i}/locale`)); + const lang = {}; + for (const j of locales) { + const content = fs.readFileSync(root(`module/${i}/locale/${j}`)).toString(); + lang[j.split('.')[0]] = yaml.safeLoad(content); + } + current.locale = lang; + } + if (exist(`module/${i}/template.build.js`)) { + const builder = require(root(`module/${i}/template.build.js`)); + const [templates, exclude] = await builder.prebuild(); + current.template = template(templates, exclude); + } else if (exist(`module/${i}/template`)) { + current.template = template(`module/${i}/template`); + } + if (exist(`module/${i}/model.js`)) { + current.model = fs.readFileSync(root(`.build/module/${i}/model.js`)).toString(); + } + if (exist(`module/${i}/handler.js`)) { + current.handler = fs.readFileSync(root(`.build/module/${i}/handler.js`)).toString(); + } + const data = zlib.gzipSync(Buffer.from(yaml.safeDump(current)), { level: 3 }); + fs.writeFileSync(root(`.build/module/${i}.hydro-module`), data); + } + } for (const i of modules) { if (!i.startsWith('.')) { if (exist(`module/${i}/locale`)) { diff --git a/build/buildTemplate.js b/build/buildTemplate.js deleted file mode 100644 index fc5c55e11..000000000 --- a/build/buildTemplate.js +++ /dev/null @@ -1,15 +0,0 @@ -const fs = require('fs'); -const yaml = require('js-yaml'); -const root = require('./root'); -const template = require('./template'); - -const build = async () => { - const exclude = [ - 'partials/training_default.json', - 'partials/problem_default.md', - 'bsod.html', - ]; - fs.writeFileSync(root('.build/template.yaml'), yaml.safeDump(template('templates', exclude))); -}; - -module.exports = build; diff --git a/build/index.js b/build/index.js index 60d97369d..d9b266e59 100644 --- a/build/index.js +++ b/build/index.js @@ -1,13 +1,30 @@ const fs = require('fs'); +const zlib = require('zlib'); +const yaml = require('js-yaml'); const root = require('./root'); +const template = require('./template'); const ignoreFailure = require('./ignoreFailure'); async function build(type) { if (!['development', 'production'].includes(type)) throw new Error(`Unknown type: ${type}`); ignoreFailure(fs.mkdirSync, root('.build')); - await require('./locales')(type); + const langs = fs.readdirSync(root('locales')); + const lang = {}; + for (const i of langs) { + const content = fs.readFileSync(root(`locales/${i}`)).toString(); + lang[i.split('.')[0]] = yaml.safeLoad(content); + } + const exclude = [ + 'partials/training_default.json', + 'partials/problem_default.md', + 'bsod.html', + ]; + const builtin = {}; + builtin.locale = lang; + builtin.template = template('templates', exclude); + const data = zlib.gzipSync(Buffer.from(yaml.safeDump(builtin)), { level: 3 }); + fs.writeFileSync(root('.build/module/builtin.hydro-module'), data); await require('./buildModule')(type); - await require('./buildTemplate')(type); await require('./webpack')(type); } diff --git a/build/locales.js b/build/locales.js deleted file mode 100644 index 8ccde9acf..000000000 --- a/build/locales.js +++ /dev/null @@ -1,14 +0,0 @@ -const yaml = require('js-yaml'); -const fs = require('fs'); -const root = require('./root'); - -const build = async () => { - const langs = fs.readdirSync(root('locales')); - const lang = {}; - for (const i of langs) { - const content = fs.readFileSync(root(`locales/${i}`)).toString(); - lang[i.split('.')[0]] = yaml.safeLoad(content); - } - fs.writeFileSync(root('.build/locales.json'), JSON.stringify(lang)); -}; -module.exports = build; diff --git a/build/template.js b/build/template.js index 086170e45..fe4dfcd87 100644 --- a/build/template.js +++ b/build/template.js @@ -38,6 +38,10 @@ const build = (dirOrObject, exclude = []) => { .replace(/> {{/gmi, '>{{') .replace(/{{ /gmi, '{{') .replace(/ }}/gmi, '}}') + .replace(/%} {%/gmi, '>{%') + .replace(/= /gmi, '=') + .replace(/ =/gmi, '=') .trim(); } } diff --git a/hydro/loader.js b/hydro/loader.js index 0eed0b4f1..3182d3a2c 100644 --- a/hydro/loader.js +++ b/hydro/loader.js @@ -1,73 +1,66 @@ /* eslint-disable import/no-dynamic-require */ +/* eslint-disable no-await-in-loop */ +/* eslint-disable no-eval */ const fs = require('fs'); +const zlib = require('zlib'); const path = require('path'); const yaml = require('js-yaml'); function root(name) { return path.resolve(process.cwd(), name); } -const installed = fs.readdirSync(root('.build/module')); -function exist(name) { - try { - fs.statSync(root(name)); - } catch (e) { - return false; + +const installed = []; + +async function preload() { + const files = fs.readdirSync(root('.build/module')); + for (const file of files) { + if (file.endsWith('.hydro-module')) { + const f = fs.readFileSync(root(`.build/module/${file}`)); + installed.push({ ...yaml.safeLoad(zlib.gunzipSync(f)), id: file.split('.')[0] }); + } } - return true; } -const superRequire = (name) => { - let m; - try { - m = require(root(name)); - } catch (e) { - m = __non_webpack_require__(root(name)); // eslint-disable-line no-undef - } - return m; -}; async function handler() { for (const i of installed) { - if (exist(`.build/module/${i}/handler.js`)) { - superRequire(`.build/module/${i}/handler.js`); - console.log(`Handler init: ${i}`); + if (i.handler) { + console.time(`Handler init: ${i.id}`); + const module = {}; // eslint-disable-line no-unused-vars + const exports = {}; // eslint-disable-line no-unused-vars + eval(i.handler); + console.timeEnd(`Handler init: ${i.id}`); } } } async function locale() { - if (exist('.build/locale.json')) { - global.Hydro.lib.i18n(superRequire('.build/locale.json')); - console.log('Locale init: builtin'); - } for (const i of installed) { - if (exist(`.build/module/${i}/locale.json`)) { - global.Hydro.lib.i18n(superRequire(`.build/module/${i}/locale.json`)); - console.log(`Locale init: ${i}`); + if (i.locale) { + global.Hydro.lib.i18n(i.locale); + console.log(`Locale init: ${i.id}`); } } } async function template() { - if (exist('.build/template.yaml')) { - const file = fs.readFileSync(root('.build/template.yaml')).toString(); - Object.assign(global.Hydro.template, yaml.safeLoad(file)); - console.log('Template init: builtin'); - } for (const i of installed) { - if (exist(`.build/module/${i}/template.yaml`)) { - const file = fs.readFileSync(root(`.build/module/${i}/template.yaml`)).toString(); - Object.assign(global.Hydro.template, yaml.safeLoad(file)); - console.log(`Template init: ${i}`); + if (i.template) { + Object.assign(global.Hydro.template, i.template); + console.log(`Template init: ${i.id}`); } } } async function model() { for (const i of installed) { - if (exist(`.build/module/${i}/model.js`)) { - const m = superRequire(`.build/module/${i}/model.js`); - if (m.index) await m.index(); // eslint-disable-line no-await-in-loop - console.log(`Model init: ${i}`); + if (i.model) { + console.time(`Model init: ${i.id}`); + const module = {}; + const exports = {}; // eslint-disable-line no-unused-vars + eval(i.handler); + if ((module.exports || {}).index) await module.exports.index(); + console.timeEnd(`Model init: ${i.id}`); } } } @@ -81,6 +74,7 @@ async function load() { template: {}, ui: {}, }; + await preload(); await template(); require('./lib/i18n'); require('./utils'); @@ -114,7 +108,7 @@ async function load() { ]; for (const i of builtinModel) { const m = require(`./model/${i}`); - if (m.index) await m.index(); // eslint-disable-line no-await-in-loop + if (m.index) await m.index(); } const builtinHandler = [ 'home', 'problem', 'record', 'judge', 'user', @@ -124,7 +118,7 @@ async function load() { await model(); await handler(); for (const i in global.Hydro.handler) { - await global.Hydro.handler[i].apply(); // eslint-disable-line no-await-in-loop + await global.Hydro.handler[i].apply(); } const notfound = require('./handler/notfound'); await notfound.apply();