Remove js-yaml from runtime dependencies, use pre-compiled JSON instead
Co-authored-by: syuilo <4439005+syuilo@users.noreply.github.com>
This commit is contained in:
parent
5e6fe5bef6
commit
69c8d8e102
|
|
@ -27,9 +27,9 @@
|
||||||
"build": "pnpm build-pre && pnpm -r build && pnpm build-assets",
|
"build": "pnpm build-pre && pnpm -r build && pnpm build-assets",
|
||||||
"build-storybook": "pnpm --filter frontend build-storybook",
|
"build-storybook": "pnpm --filter frontend build-storybook",
|
||||||
"build-misskey-js-with-types": "pnpm build-pre && pnpm --filter backend... --filter=!misskey-js build && pnpm --filter backend generate-api-json --no-build && ncp packages/backend/built/api.json packages/misskey-js/generator/api.json && pnpm --filter misskey-js update-autogen-code && pnpm --filter misskey-js build && pnpm --filter misskey-js api",
|
"build-misskey-js-with-types": "pnpm build-pre && pnpm --filter backend... --filter=!misskey-js build && pnpm --filter backend generate-api-json --no-build && ncp packages/backend/built/api.json packages/misskey-js/generator/api.json && pnpm --filter misskey-js update-autogen-code && pnpm --filter misskey-js build && pnpm --filter misskey-js api",
|
||||||
"start": "pnpm check:connect && cd packages/backend && node ./built/boot/entry.js",
|
"start": "pnpm check:connect && cd packages/backend && pnpm start",
|
||||||
"start:inspect": "cd packages/backend && node --inspect ./built/boot/entry.js",
|
"start:inspect": "cd packages/backend && pnpm start:inspect",
|
||||||
"start:test": "ncp ./.github/misskey/test.yml ./.config/test.yml && cd packages/backend && cross-env NODE_ENV=test node ./built/boot/entry.js",
|
"start:test": "ncp ./.github/misskey/test.yml ./.config/test.yml && cd packages/backend && pnpm start:test",
|
||||||
"cli": "cd packages/backend && pnpm cli",
|
"cli": "cd packages/backend && pnpm cli",
|
||||||
"init": "pnpm migrate",
|
"init": "pnpm migrate",
|
||||||
"migrate": "cd packages/backend && pnpm migrate",
|
"migrate": "cd packages/backend && pnpm migrate",
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,7 @@
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { path as configYamlPath } from '../../built/config.js';
|
import { path as configJsonPath } from '../../built/config.js';
|
||||||
import * as yaml from 'js-yaml';
|
|
||||||
import fs from "node:fs";
|
import fs from "node:fs";
|
||||||
|
|
||||||
export function isConcurrentIndexMigrationEnabled() {
|
export function isConcurrentIndexMigrationEnabled() {
|
||||||
|
|
@ -14,7 +13,7 @@ export function isConcurrentIndexMigrationEnabled() {
|
||||||
let loadedConfigCache = undefined;
|
let loadedConfigCache = undefined;
|
||||||
|
|
||||||
function loadConfigInternal() {
|
function loadConfigInternal() {
|
||||||
const config = yaml.load(fs.readFileSync(configYamlPath, 'utf-8'));
|
const config = JSON.parse(fs.readFileSync(configJsonPath, 'utf-8'));
|
||||||
|
|
||||||
return {
|
return {
|
||||||
disallowExternalApRedirect: Boolean(config.disallowExternalApRedirect ?? false),
|
disallowExternalApRedirect: Boolean(config.disallowExternalApRedirect ?? false),
|
||||||
|
|
|
||||||
|
|
@ -7,13 +7,14 @@
|
||||||
"node": "^22.15.0 || ^24.10.0"
|
"node": "^22.15.0 || ^24.10.0"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node ./built/boot/entry.js",
|
"compile-config": "node ./scripts/compile_config.js",
|
||||||
"start:inspect": "node --inspect ./built/boot/entry.js",
|
"start": "pnpm compile-config && node ./built/boot/entry.js",
|
||||||
"start:test": "cross-env NODE_ENV=test node ./built/boot/entry.js",
|
"start:inspect": "pnpm compile-config && node --inspect ./built/boot/entry.js",
|
||||||
"migrate": "pnpm typeorm migration:run -d ormconfig.js",
|
"start:test": "cross-env NODE_ENV=test pnpm compile-config && cross-env NODE_ENV=test node ./built/boot/entry.js",
|
||||||
"revert": "pnpm typeorm migration:revert -d ormconfig.js",
|
"migrate": "pnpm compile-config && pnpm typeorm migration:run -d ormconfig.js",
|
||||||
"cli": "node ./built/boot/cli.js",
|
"revert": "pnpm compile-config && pnpm typeorm migration:revert -d ormconfig.js",
|
||||||
"check:connect": "node ./scripts/check_connect.js",
|
"cli": "pnpm compile-config && node ./built/boot/cli.js",
|
||||||
|
"check:connect": "pnpm compile-config && node ./scripts/check_connect.js",
|
||||||
"build": "swc src -d built -D --strip-leading-paths",
|
"build": "swc src -d built -D --strip-leading-paths",
|
||||||
"build:test": "swc test-server -d built-test -D --config-file test-server/.swcrc --strip-leading-paths",
|
"build:test": "swc test-server -d built-test -D --config-file test-server/.swcrc --strip-leading-paths",
|
||||||
"watch:swc": "swc src -d built -D -w --strip-leading-paths",
|
"watch:swc": "swc src -d built -D -w --strip-leading-paths",
|
||||||
|
|
@ -24,11 +25,11 @@
|
||||||
"typecheck": "tsc --noEmit && tsc -p test --noEmit && tsc -p test-federation --noEmit",
|
"typecheck": "tsc --noEmit && tsc -p test --noEmit && tsc -p test-federation --noEmit",
|
||||||
"eslint": "eslint --quiet \"{src,test-federation}/**/*.ts\"",
|
"eslint": "eslint --quiet \"{src,test-federation}/**/*.ts\"",
|
||||||
"lint": "pnpm typecheck && pnpm eslint",
|
"lint": "pnpm typecheck && pnpm eslint",
|
||||||
"jest": "cross-env NODE_ENV=test node ./jest.js --forceExit --config jest.config.unit.cjs",
|
"jest": "cross-env NODE_ENV=test pnpm compile-config && cross-env NODE_ENV=test node ./jest.js --forceExit --config jest.config.unit.cjs",
|
||||||
"jest:e2e": "cross-env NODE_ENV=test node ./jest.js --forceExit --config jest.config.e2e.cjs",
|
"jest:e2e": "cross-env NODE_ENV=test pnpm compile-config && cross-env NODE_ENV=test node ./jest.js --forceExit --config jest.config.e2e.cjs",
|
||||||
"jest:fed": "node ./jest.js --forceExit --config jest.config.fed.cjs",
|
"jest:fed": "pnpm compile-config && node ./jest.js --forceExit --config jest.config.fed.cjs",
|
||||||
"jest-and-coverage": "cross-env NODE_ENV=test node ./jest.js --coverage --forceExit --config jest.config.unit.cjs",
|
"jest-and-coverage": "cross-env NODE_ENV=test pnpm compile-config && cross-env NODE_ENV=test node ./jest.js --coverage --forceExit --config jest.config.unit.cjs",
|
||||||
"jest-and-coverage:e2e": "cross-env NODE_ENV=test node ./jest.js --coverage --forceExit --config jest.config.e2e.cjs",
|
"jest-and-coverage:e2e": "cross-env NODE_ENV=test pnpm compile-config && cross-env NODE_ENV=test node ./jest.js --coverage --forceExit --config jest.config.e2e.cjs",
|
||||||
"jest-clear": "cross-env NODE_ENV=test node ./jest.js --clearCache",
|
"jest-clear": "cross-env NODE_ENV=test node ./jest.js --clearCache",
|
||||||
"test": "pnpm jest",
|
"test": "pnpm jest",
|
||||||
"test:e2e": "pnpm build && pnpm build:test && pnpm jest:e2e",
|
"test:e2e": "pnpm build && pnpm build:test && pnpm jest:e2e",
|
||||||
|
|
@ -127,7 +128,6 @@
|
||||||
"ip-cidr": "4.0.2",
|
"ip-cidr": "4.0.2",
|
||||||
"ipaddr.js": "2.2.0",
|
"ipaddr.js": "2.2.0",
|
||||||
"is-svg": "6.1.0",
|
"is-svg": "6.1.0",
|
||||||
"js-yaml": "4.1.1",
|
|
||||||
"json5": "2.2.3",
|
"json5": "2.2.3",
|
||||||
"jsonld": "9.0.0",
|
"jsonld": "9.0.0",
|
||||||
"jsrsasign": "11.1.0",
|
"jsrsasign": "11.1.0",
|
||||||
|
|
@ -233,6 +233,7 @@
|
||||||
"jest": "29.7.0",
|
"jest": "29.7.0",
|
||||||
"jest-mock": "29.7.0",
|
"jest-mock": "29.7.0",
|
||||||
"jest-util": "29.7.0",
|
"jest-util": "29.7.0",
|
||||||
|
"js-yaml": "4.1.1",
|
||||||
"nodemon": "3.1.11",
|
"nodemon": "3.1.11",
|
||||||
"pid-port": "2.0.0",
|
"pid-port": "2.0.0",
|
||||||
"simple-oauth2": "5.1.0",
|
"simple-oauth2": "5.1.0",
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
import * as fs from 'node:fs';
|
||||||
|
import { fileURLToPath } from 'node:url';
|
||||||
|
import { dirname, resolve } from 'node:path';
|
||||||
|
import * as yaml from 'js-yaml';
|
||||||
|
|
||||||
|
const _filename = fileURLToPath(import.meta.url);
|
||||||
|
const _dirname = dirname(_filename);
|
||||||
|
|
||||||
|
const dir = `${_dirname}/../../../.config`;
|
||||||
|
|
||||||
|
const configYmlPath = process.env.MISSKEY_CONFIG_YML
|
||||||
|
? resolve(dir, process.env.MISSKEY_CONFIG_YML)
|
||||||
|
: process.env.NODE_ENV === 'test'
|
||||||
|
? resolve(dir, 'test.yml')
|
||||||
|
: resolve(dir, 'default.yml');
|
||||||
|
|
||||||
|
// Change extension from .yml to .json
|
||||||
|
const configJsonPath = configYmlPath.replace(/\.yml$/, '.json');
|
||||||
|
|
||||||
|
if (!fs.existsSync(configYmlPath)) {
|
||||||
|
console.error(`Configuration file not found: ${configYmlPath}`);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const yamlContent = fs.readFileSync(configYmlPath, 'utf-8');
|
||||||
|
const config = yaml.load(yamlContent);
|
||||||
|
fs.writeFileSync(configJsonPath, JSON.stringify(config, null, '\t'), 'utf-8');
|
||||||
|
|
||||||
|
console.log(`Compiled config: ${configYmlPath} -> ${configJsonPath}`);
|
||||||
|
|
@ -6,7 +6,6 @@
|
||||||
import * as fs from 'node:fs';
|
import * as fs from 'node:fs';
|
||||||
import { fileURLToPath } from 'node:url';
|
import { fileURLToPath } from 'node:url';
|
||||||
import { dirname, resolve } from 'node:path';
|
import { dirname, resolve } from 'node:path';
|
||||||
import * as yaml from 'js-yaml';
|
|
||||||
import { type FastifyServerOptions } from 'fastify';
|
import { type FastifyServerOptions } from 'fastify';
|
||||||
import type * as Sentry from '@sentry/node';
|
import type * as Sentry from '@sentry/node';
|
||||||
import type * as SentryVue from '@sentry/vue';
|
import type * as SentryVue from '@sentry/vue';
|
||||||
|
|
@ -223,14 +222,19 @@ const _dirname = dirname(_filename);
|
||||||
const dir = `${_dirname}/../../../.config`;
|
const dir = `${_dirname}/../../../.config`;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Path of configuration file
|
* Path of configuration file (YAML)
|
||||||
*/
|
*/
|
||||||
export const path = process.env.MISSKEY_CONFIG_YML
|
const configYmlPath = process.env.MISSKEY_CONFIG_YML
|
||||||
? resolve(dir, process.env.MISSKEY_CONFIG_YML)
|
? resolve(dir, process.env.MISSKEY_CONFIG_YML)
|
||||||
: process.env.NODE_ENV === 'test'
|
: process.env.NODE_ENV === 'test'
|
||||||
? resolve(dir, 'test.yml')
|
? resolve(dir, 'test.yml')
|
||||||
: resolve(dir, 'default.yml');
|
: resolve(dir, 'default.yml');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Path of configuration file (JSON, pre-compiled from YAML)
|
||||||
|
*/
|
||||||
|
export const path = configYmlPath.replace(/\.yml$/, '.json');
|
||||||
|
|
||||||
export function loadConfig(): Config {
|
export function loadConfig(): Config {
|
||||||
const meta = JSON.parse(fs.readFileSync(`${_dirname}/../../../built/meta.json`, 'utf-8'));
|
const meta = JSON.parse(fs.readFileSync(`${_dirname}/../../../built/meta.json`, 'utf-8'));
|
||||||
|
|
||||||
|
|
@ -243,7 +247,7 @@ export function loadConfig(): Config {
|
||||||
JSON.parse(fs.readFileSync(`${_dirname}/../../../built/_frontend_embed_vite_/manifest.json`, 'utf-8'))
|
JSON.parse(fs.readFileSync(`${_dirname}/../../../built/_frontend_embed_vite_/manifest.json`, 'utf-8'))
|
||||||
: { 'src/boot.ts': { file: null } };
|
: { 'src/boot.ts': { file: null } };
|
||||||
|
|
||||||
const config = yaml.load(fs.readFileSync(path, 'utf-8')) as Source;
|
const config = JSON.parse(fs.readFileSync(path, 'utf-8')) as Source;
|
||||||
|
|
||||||
const url = tryCreateUrl(config.url ?? process.env.MISSKEY_URL ?? '');
|
const url = tryCreateUrl(config.url ?? process.env.MISSKEY_URL ?? '');
|
||||||
const version = meta.version;
|
const version = meta.version;
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import * as esbuild from 'esbuild';
|
||||||
import { build } from 'esbuild';
|
import { build } from 'esbuild';
|
||||||
import { execa } from 'execa';
|
import { execa } from 'execa';
|
||||||
import { globSync } from 'glob';
|
import { globSync } from 'glob';
|
||||||
|
import * as yaml from 'js-yaml';
|
||||||
import { generateLocaleInterface } from './scripts/generateLocaleInterface.js';
|
import { generateLocaleInterface } from './scripts/generateLocaleInterface.js';
|
||||||
import type { BuildOptions, BuildResult, Plugin, PluginBuild } from 'esbuild';
|
import type { BuildOptions, BuildResult, Plugin, PluginBuild } from 'esbuild';
|
||||||
|
|
||||||
|
|
@ -49,7 +50,18 @@ if (args.includes('--watch')) {
|
||||||
await buildSrc();
|
await buildSrc();
|
||||||
}
|
}
|
||||||
|
|
||||||
function copyLocales(): void {
|
/**
|
||||||
|
* 何故か文字列にバックスペース文字が混入することがあり、YAMLが壊れるので取り除く
|
||||||
|
*/
|
||||||
|
function clean(text: string) {
|
||||||
|
return text.replace(new RegExp(String.fromCodePoint(0x08), 'g'), '');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert locale YAML files to JSON during build
|
||||||
|
* This allows runtime to avoid loading js-yaml
|
||||||
|
*/
|
||||||
|
function compileLocales(): void {
|
||||||
const srcDir = _localesDir;
|
const srcDir = _localesDir;
|
||||||
const destDir = resolve(_dirname, 'built/locales');
|
const destDir = resolve(_dirname, 'built/locales');
|
||||||
|
|
||||||
|
|
@ -57,9 +69,12 @@ function copyLocales(): void {
|
||||||
|
|
||||||
const files = fs.readdirSync(srcDir).filter(f => f.endsWith('.yml'));
|
const files = fs.readdirSync(srcDir).filter(f => f.endsWith('.yml'));
|
||||||
for (const file of files) {
|
for (const file of files) {
|
||||||
fs.copyFileSync(resolve(srcDir, file), resolve(destDir, file));
|
const yamlContent = clean(fs.readFileSync(resolve(srcDir, file), 'utf-8'));
|
||||||
|
const jsonContent = yaml.load(yamlContent);
|
||||||
|
const jsonFile = file.replace(/\.yml$/, '.json');
|
||||||
|
fs.writeFileSync(resolve(destDir, jsonFile), JSON.stringify(jsonContent), 'utf-8');
|
||||||
}
|
}
|
||||||
console.log(`[${_package.name}] locales copied (${files.length} files).`);
|
console.log(`[${_package.name}] locales compiled to JSON (${files.length} files).`);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -87,7 +102,7 @@ async function buildSrc(): Promise<void> {
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
copyLocales();
|
compileLocales();
|
||||||
await writeFrontendLocalesJson();
|
await writeFrontendLocalesJson();
|
||||||
|
|
||||||
if (process.env.NODE_ENV === 'production') {
|
if (process.env.NODE_ENV === 'production') {
|
||||||
|
|
@ -123,7 +138,7 @@ async function watchSrc(): Promise<void> {
|
||||||
localesWatcher.on('all', async (event, path) => {
|
localesWatcher.on('all', async (event, path) => {
|
||||||
if (!path.endsWith('.yml')) return;
|
if (!path.endsWith('.yml')) return;
|
||||||
console.log(`[${_package.name}] locales changed: ${event} ${path}`);
|
console.log(`[${_package.name}] locales changed: ${event} ${path}`);
|
||||||
copyLocales();
|
compileLocales();
|
||||||
await writeFrontendLocalesJson();
|
await writeFrontendLocalesJson();
|
||||||
await generateLocaleInterface(_localesDir);
|
await generateLocaleInterface(_localesDir);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -32,11 +32,9 @@
|
||||||
"esbuild": "0.27.0",
|
"esbuild": "0.27.0",
|
||||||
"execa": "9.6.0",
|
"execa": "9.6.0",
|
||||||
"glob": "11.1.0",
|
"glob": "11.1.0",
|
||||||
|
"js-yaml": "4.1.1",
|
||||||
"nodemon": "3.1.11",
|
"nodemon": "3.1.11",
|
||||||
"tsx": "4.20.6",
|
"tsx": "4.20.6",
|
||||||
"typescript": "5.9.3"
|
"typescript": "5.9.3"
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"js-yaml": "4.1.1"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import * as fs from 'node:fs';
|
import * as fs from 'node:fs';
|
||||||
import * as yaml from 'js-yaml';
|
|
||||||
import type { Locale } from './autogen/locale.js';
|
import type { Locale } from './autogen/locale.js';
|
||||||
import type { ILocale, ParameterizedString } from './types.js';
|
import type { ILocale, ParameterizedString } from './types.js';
|
||||||
|
|
||||||
|
|
@ -71,13 +70,6 @@ function merge<T extends ILocale>(...args: (T | ILocale | undefined)[]): T {
|
||||||
}), {} as ILocale) as T;
|
}), {} as ILocale) as T;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 何故か文字列にバックスペース文字が混入することがあり、YAMLが壊れるので取り除く
|
|
||||||
*/
|
|
||||||
function clean (text: string) {
|
|
||||||
return text.replace(new RegExp(String.fromCodePoint(0x08), 'g'), '');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 空文字列が入ることがあり、フォールバックが動作しなくなるのでプロパティごと消す
|
* 空文字列が入ることがあり、フォールバックが動作しなくなるのでプロパティごと消す
|
||||||
*/
|
*/
|
||||||
|
|
@ -98,7 +90,7 @@ function build(): Record<Language, Locale> {
|
||||||
// https://github.com/misskey-dev/misskey/pull/14057#issuecomment-2192833785
|
// https://github.com/misskey-dev/misskey/pull/14057#issuecomment-2192833785
|
||||||
const metaUrl = import.meta.url;
|
const metaUrl = import.meta.url;
|
||||||
const locales = languages.reduce<Locales>((a, lang) => {
|
const locales = languages.reduce<Locales>((a, lang) => {
|
||||||
a[lang] = (yaml.load(clean(fs.readFileSync(new URL(`./locales/${lang}.yml`, metaUrl), 'utf-8'))) ?? {}) as ILocale;
|
a[lang] = (JSON.parse(fs.readFileSync(new URL(`./locales/${lang}.json`, metaUrl), 'utf-8')) ?? {}) as ILocale;
|
||||||
return a;
|
return a;
|
||||||
}, {} as Locales);
|
}, {} as Locales);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue