From cffce0bd7921ee3c434fa8f8fdbf2862473651a3 Mon Sep 17 00:00:00 2001 From: undefined Date: Wed, 24 Jan 2024 04:11:48 +0800 Subject: [PATCH] utils: use split loader into @hydrooj/register --- .github/workflows/build.yml | 2 +- package.json | 10 +-- packages/eslint-config/package.json | 4 +- packages/hydrojudge/bin/hydrojudge.js | 2 +- packages/hydrooj/bin/hydrooj.js | 2 +- packages/hydrooj/package.json | 10 +-- packages/register/index.js | 97 +++++++++++++++++++++++++++ packages/register/package.json | 16 +++++ packages/ui-default/build/index.js | 2 +- packages/ui-default/package.json | 10 +-- packages/utils/lib/locate-pm2.ts | 2 +- packages/utils/lib/register.js | 96 +------------------------- packages/utils/package.json | 8 +-- packages/vjudge/package.json | 2 +- 14 files changed, 141 insertions(+), 122 deletions(-) create mode 100644 packages/register/index.js create mode 100644 packages/register/package.json diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d1311c4d5..1f34de607 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -69,7 +69,7 @@ jobs: fi - name: Publish if: ${{ github.event_name == 'push' }} - run: node -r @hydrooj/utils/lib/register build/publish.ts + run: node -r @hydrooj/register build/publish.ts env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} # - name: Benchmark diff --git a/package.json b/package.json index c0799d205..8ca908b93 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "build:ui:dev:https": "node packages/ui-default/build --gulp && node --trace-deprecation packages/ui-default/build --dev --https", "build:ui:production": "cross-env NODE_OPTIONS=--max_old_space_size=8192 node packages/ui-default/build --gulp && node packages/ui-default/build --production", "build:ui:production:webpack": "cross-env NODE_OPTIONS=--max_old_space_size=8192 node packages/ui-default/build --production", - "test": "node -r @hydrooj/utils/lib/register packages/utils/tests/subtask.spec.ts && node test/entry.js", + "test": "node -r @hydrooj/register packages/utils/tests/subtask.spec.ts && node test/entry.js", "benchmark": "cross-env BENCHMARK=true node test/entry.js", "lint": "eslint packages plugins modules --ext .ts,.tsx,.jsx --fix", "lint:ci": "eslint packages plugins modules --ext .ts,.tsx,.jsx --max-warnings=0", @@ -26,7 +26,7 @@ "debug": "node --trace-warnings --async-stack-traces --trace-deprecation packages/hydrooj/bin/hydrooj --debug --template", "start": "packages/hydrooj/bin/hydrooj", "postinstall": "node build/prepare.js", - "gen-patch": "node -r @hydrooj/utils/lib/register build/gen-patch.ts", + "gen-patch": "node -r @hydrooj/register build/gen-patch.ts", "hydrooj": "./node_modules/.bin/hydrooj" }, "version": "1.0.0", @@ -36,7 +36,7 @@ "@types/autocannon": "^7.12.5", "@types/chai": "^4.3.11", "@types/cross-spawn": "^6.0.6", - "@types/node": "^20.10.6", + "@types/node": "^20.11.5", "@types/semver": "^7.5.6", "autocannon": "^7.14.0", "cac": "^6.7.14", @@ -53,8 +53,8 @@ "inspectpack": "^4.7.1", "mongodb-memory-server": "^9.1.6", "nyc": "^15.1.0", - "ora": "^7.0.1", - "package-json": "^8.1.1", + "ora": "^8.0.1", + "package-json": "^9.0.0", "semver": "^7.5.4", "simple-git": "^3.22.0", "supertest": "^6.3.4", diff --git a/packages/eslint-config/package.json b/packages/eslint-config/package.json index 1b14b1383..cfbb25b1a 100644 --- a/packages/eslint-config/package.json +++ b/packages/eslint-config/package.json @@ -4,8 +4,8 @@ "license": "MIT", "main": "react.yaml", "dependencies": { - "@typescript-eslint/eslint-plugin": "^6.19.0", - "@typescript-eslint/parser": "^6.19.0", + "@typescript-eslint/eslint-plugin": "^6.19.1", + "@typescript-eslint/parser": "^6.19.1", "eslint-config-airbnb": "^19.0.4", "eslint-config-airbnb-typescript": "^17.1.0", "eslint-plugin-github": "^4.10.1", diff --git a/packages/hydrojudge/bin/hydrojudge.js b/packages/hydrojudge/bin/hydrojudge.js index 39a9c04c4..2d8b997e0 100755 --- a/packages/hydrojudge/bin/hydrojudge.js +++ b/packages/hydrojudge/bin/hydrojudge.js @@ -1,7 +1,7 @@ #!/usr/bin/env node const argv = require('cac')().parse(); -require('@hydrooj/utils/lib/register'); +require('@hydrooj/register'); if (argv.args[0] === 'cache') require('../src/cache')(); else require('../src/daemon')(); diff --git a/packages/hydrooj/bin/hydrooj.js b/packages/hydrooj/bin/hydrooj.js index 53d191f26..babea7a45 100755 --- a/packages/hydrooj/bin/hydrooj.js +++ b/packages/hydrooj/bin/hydrooj.js @@ -1,5 +1,5 @@ #!/usr/bin/env node -require('@hydrooj/utils/lib/register'); +require('@hydrooj/register'); const packageBasedir = require('path').resolve(__dirname, '..'); const { homedir } = require('os'); diff --git a/packages/hydrooj/package.json b/packages/hydrooj/package.json index 1674e63b3..0119c5dd9 100644 --- a/packages/hydrooj/package.json +++ b/packages/hydrooj/package.json @@ -12,10 +12,10 @@ }, "preferUnplugged": true, "dependencies": { - "@aws-sdk/client-s3": "3.495.0", - "@aws-sdk/lib-storage": "3.490.0", - "@aws-sdk/s3-presigned-post": "3.490.0", - "@aws-sdk/s3-request-presigner": "3.495.0", + "@aws-sdk/client-s3": "3.496.0", + "@aws-sdk/lib-storage": "3.496.0", + "@aws-sdk/s3-presigned-post": "3.496.0", + "@aws-sdk/s3-request-presigner": "3.496.0", "@graphql-tools/schema": "^10.0.2", "@hydrooj/utils": "workspace:*", "@simplewebauthn/server": "7.4.0", @@ -50,7 +50,7 @@ "saslprep": "^1.0.3", "schemastery": "^3.14.3", "semver": "^7.5.4", - "shorty.js": "^1.0.0", + "shorty.js": "^1.0.1", "superagent": "^8.1.2", "tar": "^6.2.0", "thirty-two": "^1.0.2", diff --git a/packages/register/index.js b/packages/register/index.js new file mode 100644 index 000000000..472c86074 --- /dev/null +++ b/packages/register/index.js @@ -0,0 +1,97 @@ +const map = {}; +require('source-map-support').install({ + handleUncaughtExceptions: false, + environment: 'node', + retrieveSourceMap(file) { + if (map[file]) { + return { + url: file, + map: map[file], + }; + } + return null; + }, +}); +const path = require('path'); +const vm = require('vm'); +const fs = require('fs'); +const esbuild = require('esbuild'); + +process.env.NODE_APP_INSTANCE ||= '0'; +const major = +process.version.split('.')[0].split('v')[1]; +const minor = +process.version.split('.')[1]; + +function transform(filename, tsx = true) { + const code = fs.readFileSync(filename, 'utf-8'); + const result = esbuild.transformSync(code, { + tsconfigRaw: '{"compilerOptions":{"experimentalDecorators":true}}', + sourcefile: filename, + sourcemap: 'both', + format: 'cjs', + loader: tsx ? 'tsx' : 'ts', + target: `node${major}.${minor}`, + jsx: 'transform', + }); + if (result.warnings.length) console.warn(result.warnings); + map[filename] = result.map; + if (process.env.LOADER_DUMP_CODE && filename.endsWith(`/${process.env.LOADER_DUMP_CODE}`)) { + console.log(`-----${filename}-----`); + console.log(result.code.split('/# sourceMappingURL=')[0]); + } + return result.code; +} +const _script = new vm.Script('"Hydro"', { produceCachedData: true }); +const bytecode = (_script.createCachedData && _script.createCachedData.call) + ? _script.createCachedData() + : _script.cachedData; +require.extensions['.js'] = function loader(module, filename) { + if (major < 14) { + return module._compile(transform(filename), filename); + } + try { + const content = fs.readFileSync(filename, 'utf-8'); + return module._compile(content, filename); + } catch (e) { // ESM + return module._compile(transform(filename), filename); + } +}; +require.extensions['.ts'] = function loader(module, filename) { + return module._compile(transform(filename, false), filename); +}; +require.extensions['.tsx'] = require.extensions['.jsx'] = function loader(module, filename) { + return module._compile(transform(filename), filename); +}; +require.extensions['.jsc'] = function loader(module, filename) { + const buf = fs.readFileSync(filename); + bytecode.subarray(12, 16).copy(buf, 12); + if (![12, 13, 14, 15, 16, 17].filter((i) => process.version.startsWith(`v${i}`)).length) { + bytecode.subarray(16, 20).copy(buf, 16); + } + // eslint-disable-next-line no-return-assign + const length = buf.subarray(8, 12).reduce((sum, number, power) => sum += number * (256 ** power), 0); + let dummyCode = ''; + if (length > 1) dummyCode = `"${'\u200b'.repeat(length - 2)}"`; + const script = new vm.Script(dummyCode, { + filename, + lineOffset: 0, + displayErrors: true, + cachedData: buf, + }); + if (script.cachedDataRejected) throw new Error(`cacheDataRejected on ${filename}`); + const compiledWrapper = script.runInThisContext({ + filename, + lineOffset: 0, + columnOffset: 0, + displayErrors: true, + }); + const dirname = path.dirname(filename); + const args = [module.exports, require, module, filename, dirname, process, global]; + return compiledWrapper.apply(module.exports, args); +}; + +const argv = require('cac')().parse(); +if (argv.options.debug) { + console.log('Debug mode enabled'); + process.env.NODE_ENV = 'development'; + process.env.DEV = 'on'; +} else process.env.NODE_ENV ||= 'production'; diff --git a/packages/register/package.json b/packages/register/package.json new file mode 100644 index 000000000..464a61c98 --- /dev/null +++ b/packages/register/package.json @@ -0,0 +1,16 @@ +{ + "name": "@hydrooj/register", + "version": "1.0.0", + "license": "MIT", + "main": "index.js", + "engines": { + "node": ">=16" + }, + "dependencies": { + "esbuild": "0.18.20", + "source-map-support": "^0.5.21" + }, + "devDependencies": { + "@types/source-map-support": "^0.5.10" + } +} diff --git a/packages/ui-default/build/index.js b/packages/ui-default/build/index.js index 403a4b177..69a1aec3e 100644 --- a/packages/ui-default/build/index.js +++ b/packages/ui-default/build/index.js @@ -1,4 +1,4 @@ -require('@hydrooj/utils/lib/register'); +require('@hydrooj/register'); const main = require('./main'); if (!module.parent) main(); diff --git a/packages/ui-default/package.json b/packages/ui-default/package.json index 26137b6b0..a4875d63b 100644 --- a/packages/ui-default/package.json +++ b/packages/ui-default/package.json @@ -34,7 +34,7 @@ "@types/nunjucks": "^3.2.6", "@types/pickadate": "^3.5.35", "@types/qrcode": "^1.5.5", - "@types/react": "^18.2.47", + "@types/react": "^18.2.48", "@types/react-dom": "^18.2.18", "@types/redux-logger": "^3.0.12", "@types/webpack-env": "^1.18.4", @@ -47,9 +47,9 @@ "classnames": "^2.5.1", "clean-webpack-plugin": "^4.0.0", "clipboard": "^2.0.11", - "copy-webpack-plugin": "^11.0.0", + "copy-webpack-plugin": "^12.0.2", "cordis": "2.8.8", - "css-loader": "^6.9.0", + "css-loader": "^6.9.1", "diff": "^5.1.0", "diff-dom": "^5.1.2", "echarts": "^5.4.3", @@ -75,7 +75,7 @@ "monaco-editor-nls": "^3.1.0", "monaco-editor-webpack-plugin": "^7.1.0", "monaco-themes": "^0.4.4", - "monaco-yaml": "^5.1.0", + "monaco-yaml": "^5.1.1", "nanoid": "^5.0.4", "normalize.css": "^8.0.1", "nprogress": "^0.2.0", @@ -103,7 +103,7 @@ "redux-thunk": "^3.1.0", "rupture": "^0.7.1", "schemastery": "^3.14.3", - "shorty.js": "^1.0.0", + "shorty.js": "^1.0.1", "slideout": "^1.0.1", "sticky-kit": "^1.1.3", "style-loader": "^3.3.4", diff --git a/packages/utils/lib/locate-pm2.ts b/packages/utils/lib/locate-pm2.ts index f5ef60a6d..3e2ee58b0 100644 --- a/packages/utils/lib/locate-pm2.ts +++ b/packages/utils/lib/locate-pm2.ts @@ -1,5 +1,5 @@ +import fs from 'fs'; import path from 'path'; -import fs from 'fs-extra'; const PATH = process.env.PATH?.split(':') || []; diff --git a/packages/utils/lib/register.js b/packages/utils/lib/register.js index d672ed25b..4e0ce16da 100644 --- a/packages/utils/lib/register.js +++ b/packages/utils/lib/register.js @@ -1,94 +1,2 @@ -const map = {}; -require('source-map-support').install({ - handleUncaughtExceptions: false, - environment: 'node', - retrieveSourceMap(file) { - if (map[file]) { - return { - url: file, - map: map[file], - }; - } - return null; - }, -}); -const path = require('path'); -const vm = require('vm'); -const fs = require('fs-extra'); -const esbuild = require('esbuild'); - -process.env.NODE_APP_INSTANCE ||= '0'; -const major = +process.version.split('.')[0].split('v')[1]; -const minor = +process.version.split('.')[1]; - -function transform(filename) { - const code = fs.readFileSync(filename, 'utf-8'); - const result = esbuild.transformSync(code, { - tsconfigRaw: '{"compilerOptions":{"experimentalDecorators":true}}', - sourcefile: filename, - sourcemap: 'both', - format: 'cjs', - loader: 'tsx', - target: `node${major}.${minor}`, - jsx: 'transform', - }); - if (result.warnings.length) console.warn(result.warnings); - map[filename] = result.map; - if (process.env.LOADER_DUMP_CODE && filename.endsWith(`/${process.env.LOADER_DUMP_CODE}`)) { - console.log(`-----${filename}-----`); - console.log(result.code.split('/# sourceMappingURL=')[0]); - } - return result.code; -} -const _script = new vm.Script('"Hydro"', { produceCachedData: true }); -const bytecode = (_script.createCachedData && _script.createCachedData.call) - ? _script.createCachedData() - : _script.cachedData; -require.extensions['.js'] = function loader(module, filename) { - if (major < 14) { - return module._compile(transform(filename), filename); - } - try { - const content = fs.readFileSync(filename, 'utf-8'); - return module._compile(content, filename); - } catch (e) { // ESM - return module._compile(transform(filename), filename); - } -}; -require.extensions['.ts'] = require.extensions['.tsx'] = function loader(module, filename) { - return module._compile(transform(filename), filename); -}; -require.extensions['.jsc'] = function loader(module, filename) { - const buf = fs.readFileSync(filename); - bytecode.slice(12, 16).copy(buf, 12); - if (![12, 13, 14, 15, 16, 17].filter((i) => process.version.startsWith(`v${i}`)).length) { - bytecode.slice(16, 20).copy(buf, 16); - } - // eslint-disable-next-line no-return-assign - const length = buf.slice(8, 12).reduce((sum, number, power) => sum += number * (256 ** power), 0); - let dummyCode = ''; - if (length > 1) dummyCode = `"${'\u200b'.repeat(length - 2)}"`; - const script = new vm.Script(dummyCode, { - filename, - lineOffset: 0, - displayErrors: true, - cachedData: buf, - }); - if (script.cachedDataRejected) throw new Error(`cacheDataRejected on ${filename}`); - const compiledWrapper = script.runInThisContext({ - filename, - lineOffset: 0, - columnOffset: 0, - displayErrors: true, - }); - const dirname = path.dirname(filename); - const args = [module.exports, require, module, filename, dirname, process, global]; - return compiledWrapper.apply(module.exports, args); -}; - -const argv = require('cac')().parse(); -if (argv.options.debug) { - console.log('Debug mode enabled'); - process.env.NODE_ENV = 'development'; - process.env.DEV = 'on'; -} else process.env.NODE_ENV ||= 'production'; +console.warn('@hydroooj/utils/lib/register has moved to @hydrooj/register.'); +require('@hydrooj/register'); diff --git a/packages/utils/package.json b/packages/utils/package.json index 4a0fd03bf..741ae5412 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -8,19 +8,17 @@ "license": "AGPL-3.0-or-later", "preferUnplugged": true, "dependencies": { + "@hydrooj/register": "workspace:^", "cac": "^6.7.14", - "esbuild": "0.18.20", "fs-extra": "^11.2.0", "js-yaml": "^4.1.0", "moment-timezone": "^0.5.44", "mongodb": "^5.9.2", "reggol": "^1.6.3", "search-query-parser": "^1.6.0", - "source-map-support": "^0.5.21", - "systeminformation": "^5.21.22" + "systeminformation": "^5.21.24" }, "devDependencies": { - "@types/fs-extra": "^11.0.4", - "@types/source-map-support": "^0.5.10" + "@types/fs-extra": "^11.0.4" } } diff --git a/packages/vjudge/package.json b/packages/vjudge/package.json index bb0605342..2fc55ff79 100644 --- a/packages/vjudge/package.json +++ b/packages/vjudge/package.json @@ -9,7 +9,7 @@ "preferUnplugged": true, "dependencies": { "@hydrooj/utils": "workspace:*", - "jsdom": "^23.2.0", + "jsdom": "^24.0.0", "superagent-charset": "^1.2.0", "superagent-proxy": "^3.0.0" },