summaryrefslogtreecommitdiff
path: root/packages/backend
diff options
context:
space:
mode:
Diffstat (limited to 'packages/backend')
-rw-r--r--packages/backend/build.js121
-rw-r--r--packages/backend/ormconfig.js4
-rw-r--r--packages/backend/package.json5
-rw-r--r--packages/backend/scripts/check_connect.js8
-rw-r--r--packages/backend/scripts/generate_api_json.js6
-rw-r--r--packages/backend/src/boot/master.ts17
-rw-r--r--packages/backend/src/config.ts32
-rw-r--r--packages/backend/src/server/web/ClientServerService.ts40
-rw-r--r--packages/backend/test-federation/compose.tpl.yml4
-rw-r--r--packages/backend/test-server/.swcrc2
10 files changed, 196 insertions, 43 deletions
diff --git a/packages/backend/build.js b/packages/backend/build.js
new file mode 100644
index 0000000000..52ca09b7a8
--- /dev/null
+++ b/packages/backend/build.js
@@ -0,0 +1,121 @@
+import fs from 'node:fs';
+import { fileURLToPath } from 'node:url';
+import { dirname, join } from 'node:path';
+import { build } from 'esbuild';
+import { swcPlugin } from 'esbuild-plugin-swc';
+
+const _filename = fileURLToPath(import.meta.url);
+const _dirname = dirname(_filename);
+const _package = JSON.parse(fs.readFileSync(_dirname + '/package.json', 'utf-8'));
+
+const resolveTsPathsPlugin = {
+ name: 'resolve-ts-paths',
+ setup(build) {
+ build.onResolve({ filter: /^\.{1,2}\/.*\.js$/ }, (args) => {
+ if (args.importer) {
+ const absPath = join(args.resolveDir, args.path);
+ const tsPath = absPath.slice(0, -3) + '.ts';
+ if (fs.existsSync(tsPath)) return { path: tsPath };
+ const tsxPath = absPath.slice(0, -3) + '.tsx';
+ if (fs.existsSync(tsxPath)) return { path: tsxPath };
+ }
+ });
+ },
+};
+
+const externalIpaddrPlugin = {
+ name: 'external-ipaddr',
+ setup(build) {
+ build.onResolve({ filter: /^ipaddr\.js$/ }, (args) => {
+ return { path: args.path, external: true };
+ });
+ },
+};
+
+/** @type {import('esbuild').BuildOptions} */
+const options = {
+ entryPoints: ['./src/boot/entry.ts'],
+ minify: true,
+ keepNames: true,
+ bundle: true,
+ outdir: './built/boot',
+ target: 'node22',
+ platform: 'node',
+ format: 'esm',
+ sourcemap: 'linked',
+ packages: 'external',
+ banner: {
+ js: 'import { createRequire as topLevelCreateRequire } from "module";' +
+ 'import ___url___ from "url";' +
+ 'const require = topLevelCreateRequire(import.meta.url);' +
+ 'const __filename = ___url___.fileURLToPath(import.meta.url);' +
+ 'const __dirname = ___url___.fileURLToPath(new URL(".", import.meta.url));',
+ },
+ plugins: [
+ externalIpaddrPlugin,
+ resolveTsPathsPlugin,
+ swcPlugin({
+ jsc: {
+ parser: {
+ syntax: 'typescript',
+ decorators: true,
+ dynamicImport: true,
+ },
+ transform: {
+ legacyDecorator: true,
+ decoratorMetadata: true,
+ },
+ experimental: {
+ keepImportAssertions: true,
+ },
+ baseUrl: join(_dirname, 'src'),
+ paths: {
+ '@/*': ['*'],
+ },
+ target: 'esnext',
+ keepClassNames: true,
+ },
+ }),
+ externalIpaddrPlugin,
+ ],
+ // external: [
+ // 'slacc-*',
+ // 'class-transformer',
+ // 'class-validator',
+ // '@sentry/*',
+ // '@nestjs/websockets/socket-module',
+ // '@nestjs/microservices/microservices-module',
+ // '@nestjs/microservices',
+ // '@napi-rs/canvas-win32-x64-msvc',
+ // 'mock-aws-s3',
+ // 'aws-sdk',
+ // 'nock',
+ // 'sharp',
+ // 'jsdom',
+ // 're2',
+ // '@napi-rs/canvas',
+ // ],
+};
+
+const args = process.argv.slice(2).map(arg => arg.toLowerCase());
+
+if (!args.includes('--no-clean')) {
+ fs.rmSync('./built', { recursive: true, force: true });
+}
+
+await buildSrc();
+
+async function buildSrc() {
+ console.log(`[${_package.name}] start building...`);
+
+ await build(options)
+ .then(() => {
+ console.log(`[${_package.name}] build succeeded.`);
+ })
+ .catch((err) => {
+ process.stderr.write(err.stderr || err.message || err);
+ process.exit(1);
+ });
+
+ console.log(`[${_package.name}] finish building.`);
+}
diff --git a/packages/backend/ormconfig.js b/packages/backend/ormconfig.js
index dabc0893f4..1a8c146451 100644
--- a/packages/backend/ormconfig.js
+++ b/packages/backend/ormconfig.js
@@ -1,6 +1,6 @@
import { DataSource } from 'typeorm';
-import { loadConfig } from './built/config.js';
-import { entities } from './built/postgres.js';
+import { loadConfig } from './src-js/config.js';
+import { entities } from './src-js/postgres.js';
const isConcurrentIndexMigrationEnabled = process.env.MISSKEY_MIGRATION_CREATE_INDEX_CONCURRENTLY === '1';
diff --git a/packages/backend/package.json b/packages/backend/package.json
index 181ba4d3ef..8bda4bd909 100644
--- a/packages/backend/package.json
+++ b/packages/backend/package.json
@@ -12,10 +12,10 @@
"start:test": "cross-env NODE_ENV=test pnpm compile-config && cross-env NODE_ENV=test node ./built/boot/entry.js",
"migrate": "pnpm compile-config && pnpm typeorm migration:run -d ormconfig.js",
"revert": "pnpm compile-config && pnpm typeorm migration:revert -d ormconfig.js",
- "cli": "pnpm compile-config && node ./built/boot/cli.js",
+ "cli": "pnpm compile-config && node ./src-js/boot/cli.js",
"check:connect": "pnpm compile-config && node ./scripts/check_connect.js",
"compile-config": "node ./scripts/compile_config.js",
- "build": "swc src -d built -D --strip-leading-paths",
+ "build": "swc src -d src-js -D --strip-leading-paths && node ./build.js",
"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",
"build:tsc": "tsgo -p tsconfig.json && tsc-alias -p tsconfig.json",
@@ -219,6 +219,7 @@
"aws-sdk-client-mock": "4.1.0",
"cbor": "10.0.11",
"cross-env": "10.1.0",
+ "esbuild-plugin-swc": "1.0.1",
"eslint-plugin-import": "2.32.0",
"execa": "9.6.1",
"fkill": "10.0.1",
diff --git a/packages/backend/scripts/check_connect.js b/packages/backend/scripts/check_connect.js
index 96c4549ccb..d2f38aedb3 100644
--- a/packages/backend/scripts/check_connect.js
+++ b/packages/backend/scripts/check_connect.js
@@ -4,8 +4,8 @@
*/
import Redis from 'ioredis';
-import { loadConfig } from '../built/config.js';
-import { createPostgresDataSource } from '../built/postgres.js';
+import { loadConfig } from '../src-js/config.js';
+import { createPostgresDataSource } from '../src-js/postgres.js';
const config = loadConfig();
@@ -28,10 +28,8 @@ async function connectToRedis(redisOptions) {
try {
await redis.connect();
resolve();
-
} catch (e) {
reject(e);
-
} finally {
redis.disconnect(false);
}
@@ -50,7 +48,7 @@ const promises = Array
]))
.map(connectToRedis)
.concat([
- connectToPostgres()
+ connectToPostgres(),
]);
await Promise.all(promises);
diff --git a/packages/backend/scripts/generate_api_json.js b/packages/backend/scripts/generate_api_json.js
index 798e243004..237f63a4d3 100644
--- a/packages/backend/scripts/generate_api_json.js
+++ b/packages/backend/scripts/generate_api_json.js
@@ -3,8 +3,8 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
+import { writeFileSync, existsSync } from 'node:fs';
import { execa } from 'execa';
-import { writeFileSync, existsSync } from "node:fs";
async function main() {
if (!process.argv.includes('--no-build')) {
@@ -19,10 +19,10 @@ async function main() {
}
/** @type {import('../src/config.js')} */
- const { loadConfig } = await import('../built/config.js');
+ const { loadConfig } = await import('../src-js/config.js');
/** @type {import('../src/server/api/openapi/gen-spec.js')} */
- const { genOpenapiSpec } = await import('../built/server/api/openapi/gen-spec.js');
+ const { genOpenapiSpec } = await import('../src-js/server/api/openapi/gen-spec.js');
const config = loadConfig();
const spec = genOpenapiSpec(config, true);
diff --git a/packages/backend/src/boot/master.ts b/packages/backend/src/boot/master.ts
index 4776d0d412..f392f2f671 100644
--- a/packages/backend/src/boot/master.ts
+++ b/packages/backend/src/boot/master.ts
@@ -4,8 +4,6 @@
*/
import * as fs from 'node:fs';
-import { fileURLToPath } from 'node:url';
-import { dirname } from 'node:path';
import * as os from 'node:os';
import cluster from 'node:cluster';
import chalk from 'chalk';
@@ -17,20 +15,15 @@ import { showMachineInfo } from '@/misc/show-machine-info.js';
import { envOption } from '@/env.js';
import { jobQueue, server } from './common.js';
-const _filename = fileURLToPath(import.meta.url);
-const _dirname = dirname(_filename);
-
-const meta = JSON.parse(fs.readFileSync(`${_dirname}/../../../../built/meta.json`, 'utf-8'));
-
const logger = new Logger('core', 'cyan');
const bootLogger = logger.createSubLogger('boot', 'magenta');
const themeColor = chalk.hex('#86b300');
-function greet() {
+function greet(props: { version: string }) {
if (!envOption.quiet) {
//#region Misskey logo
- const v = `v${meta.version}`;
+ const v = `v${props.version}`;
console.log(themeColor(' _____ _ _ '));
console.log(themeColor(' | |_|___ ___| |_ ___ _ _ '));
console.log(themeColor(' | | | | |_ -|_ -| \'_| -_| | |'));
@@ -46,7 +39,7 @@ function greet() {
}
bootLogger.info('Welcome to Misskey!');
- bootLogger.info(`Misskey v${meta.version}`, null, true);
+ bootLogger.info(`Misskey v${props.version}`, null, true);
}
/**
@@ -57,11 +50,11 @@ export async function masterMain() {
// initialize app
try {
- greet();
+ config = loadConfigBoot();
+ greet({ version: config.version });
showEnvironment();
await showMachineInfo(bootLogger);
showNodejsVersion();
- config = loadConfigBoot();
//await connectDb();
if (config.pidFile) fs.writeFileSync(config.pidFile, process.pid.toString());
} catch (e) {
diff --git a/packages/backend/src/config.ts b/packages/backend/src/config.ts
index 657d7869fa..069b7c9661 100644
--- a/packages/backend/src/config.ts
+++ b/packages/backend/src/config.ts
@@ -219,24 +219,42 @@ export type FulltextSearchProvider = 'sqlLike' | 'sqlPgroonga' | 'meilisearch';
const _filename = fileURLToPath(import.meta.url);
const _dirname = dirname(_filename);
-const compiledConfigFilePathForTest = resolve(_dirname, '../../../built/._config_.json');
+/** Path of repository root directory */
+let rootDir = _dirname;
+// 見つかるまで上に遡る
+while (!fs.existsSync(resolve(rootDir, 'packages'))) {
+ const parentDir = dirname(rootDir);
+ if (parentDir === rootDir) {
+ throw new Error('Cannot find root directory');
+ }
+ rootDir = parentDir;
+}
+
+/** Path of configuration directory */
+const configDir = resolve(rootDir, '.config');
+/** Path of built directory */
+const projectBuiltDir = resolve(rootDir, 'built');
+
+const compiledConfigFilePathForTest = resolve(projectBuiltDir, '._config_.json');
-export const compiledConfigFilePath = fs.existsSync(compiledConfigFilePathForTest) ? compiledConfigFilePathForTest : resolve(_dirname, '../../../built/.config.json');
+export const compiledConfigFilePath = fs.existsSync(compiledConfigFilePathForTest)
+ ? compiledConfigFilePathForTest
+ : resolve(projectBuiltDir, '.config.json');
export function loadConfig(): Config {
if (!fs.existsSync(compiledConfigFilePath)) {
throw new Error('Compiled configuration file not found. Try running \'pnpm compile-config\'.');
}
- const meta = JSON.parse(fs.readFileSync(`${_dirname}/../../../built/meta.json`, 'utf-8'));
+ const meta = JSON.parse(fs.readFileSync(resolve(projectBuiltDir, 'meta.json'), 'utf-8'));
- const frontendManifestExists = fs.existsSync(_dirname + '/../../../built/_frontend_vite_/manifest.json');
- const frontendEmbedManifestExists = fs.existsSync(_dirname + '/../../../built/_frontend_embed_vite_/manifest.json');
+ const frontendManifestExists = fs.existsSync(resolve(projectBuiltDir, '_frontend_vite_/manifest.json'));
+ const frontendEmbedManifestExists = fs.existsSync(resolve(projectBuiltDir, '_frontend_embed_vite_/manifest.json'));
const frontendManifest = frontendManifestExists ?
- JSON.parse(fs.readFileSync(`${_dirname}/../../../built/_frontend_vite_/manifest.json`, 'utf-8'))
+ JSON.parse(fs.readFileSync(resolve(projectBuiltDir, '_frontend_vite_/manifest.json'), 'utf-8'))
: { 'src/_boot_.ts': { file: null } };
const frontendEmbedManifest = frontendEmbedManifestExists ?
- JSON.parse(fs.readFileSync(`${_dirname}/../../../built/_frontend_embed_vite_/manifest.json`, 'utf-8'))
+ JSON.parse(fs.readFileSync(resolve(projectBuiltDir, '_frontend_embed_vite_/manifest.json'), 'utf-8'))
: { 'src/boot.ts': { file: null } };
const config = JSON.parse(fs.readFileSync(compiledConfigFilePath, 'utf-8')) as Source;
diff --git a/packages/backend/src/server/web/ClientServerService.ts b/packages/backend/src/server/web/ClientServerService.ts
index bcea935409..2494ad038c 100644
--- a/packages/backend/src/server/web/ClientServerService.ts
+++ b/packages/backend/src/server/web/ClientServerService.ts
@@ -4,8 +4,9 @@
*/
import { randomUUID } from 'node:crypto';
-import { dirname } from 'node:path';
+import { dirname, resolve } from 'node:path';
import { fileURLToPath } from 'node:url';
+import * as fs from 'node:fs';
import { Inject, Injectable } from '@nestjs/common';
import ms from 'ms';
import sharp from 'sharp';
@@ -69,13 +70,28 @@ import type { FastifyError, FastifyInstance, FastifyPluginOptions, FastifyReply
const _filename = fileURLToPath(import.meta.url);
const _dirname = dirname(_filename);
-const staticAssets = `${_dirname}/../../../assets/`;
-const clientAssets = `${_dirname}/../../../../frontend/assets/`;
-const assets = `${_dirname}/../../../../../built/_frontend_dist_/`;
-const swAssets = `${_dirname}/../../../../../built/_sw_dist_/`;
-const frontendViteOut = `${_dirname}/../../../../../built/_frontend_vite_/`;
-const frontendEmbedViteOut = `${_dirname}/../../../../../built/_frontend_embed_vite_/`;
-const tarball = `${_dirname}/../../../../../built/tarball/`;
+let rootDir = _dirname;
+// 見つかるまで上に遡る
+while (!fs.existsSync(resolve(rootDir, 'packages'))) {
+ const parentDir = dirname(rootDir);
+ if (parentDir === rootDir) {
+ throw new Error('Cannot find root directory');
+ }
+ rootDir = parentDir;
+}
+
+const backendRootDir = resolve(rootDir, 'packages/backend');
+const frontendRootDir = resolve(rootDir, 'packages/frontend');
+
+const staticAssets = resolve(backendRootDir, 'assets');
+const clientAssets = resolve(frontendRootDir, 'assets');
+const assets = resolve(rootDir, 'built/_frontend_dist_');
+const swAssets = resolve(rootDir, 'built/_sw_dist_');
+const fluentEmojisDir = resolve(rootDir, 'fluent-emojis/dist');
+const twemojiDir = resolve(backendRootDir, 'node_modules/@discordapp/twemoji/dist/svg');
+const frontendViteOut = resolve(rootDir, 'built/_frontend_vite_');
+const frontendEmbedViteOut = resolve(rootDir, 'built/_frontend_embed_vite_');
+const tarball = resolve(rootDir, 'built/tarball');
@Injectable()
export class ClientServerService {
@@ -207,6 +223,7 @@ export class ClientServerService {
//#region vite assets
if (this.config.frontendEmbedManifestExists) {
+ console.log(`[ClientServerService] Using built frontend vite assets. ${frontendViteOut}`);
fastify.register((fastify, options, done) => {
fastify.register(fastifyStatic, {
root: frontendViteOut,
@@ -226,6 +243,7 @@ export class ClientServerService {
done();
});
} else {
+ console.log('[ClientServerService] Proxying to Vite dev server.');
const urlOriginWithoutPort = configUrl.origin.replace(/:\d+$/, '');
const port = (process.env.VITE_PORT ?? '5173');
@@ -297,7 +315,7 @@ export class ClientServerService {
reply.header('Content-Security-Policy', 'default-src \'none\'; style-src \'unsafe-inline\'');
- return await reply.sendFile(path, `${_dirname}/../../../../../fluent-emojis/dist/`, {
+ return reply.sendFile(path, fluentEmojisDir, {
maxAge: ms('30 days'),
});
});
@@ -312,7 +330,7 @@ export class ClientServerService {
reply.header('Content-Security-Policy', 'default-src \'none\'; style-src \'unsafe-inline\'');
- return await reply.sendFile(path, `${_dirname}/../../../node_modules/@discordapp/twemoji/dist/svg/`, {
+ return reply.sendFile(path, twemojiDir, {
maxAge: ms('30 days'),
});
});
@@ -326,7 +344,7 @@ export class ClientServerService {
}
const mask = await sharp(
- `${_dirname}/../../../node_modules/@discordapp/twemoji/dist/svg/${path.replace('.png', '')}.svg`,
+ `${twemojiDir}/${path.replace('.png', '')}.svg`,
{ density: 1000 },
)
.resize(488, 488)
diff --git a/packages/backend/test-federation/compose.tpl.yml b/packages/backend/test-federation/compose.tpl.yml
index 1404345e2a..ac93b24b87 100644
--- a/packages/backend/test-federation/compose.tpl.yml
+++ b/packages/backend/test-federation/compose.tpl.yml
@@ -35,6 +35,10 @@ services:
target: /misskey/packages/backend/built
read_only: true
- type: bind
+ source: ../src-js
+ target: /misskey/packages/backend/src-js
+ read_only: true
+ - type: bind
source: ../migration
target: /misskey/packages/backend/migration
read_only: true
diff --git a/packages/backend/test-server/.swcrc b/packages/backend/test-server/.swcrc
index eeac7eabc6..3859603da3 100644
--- a/packages/backend/test-server/.swcrc
+++ b/packages/backend/test-server/.swcrc
@@ -13,7 +13,7 @@
"experimental": {
"keepImportAssertions": true
},
- "baseUrl": "../built",
+ "baseUrl": "../src-js",
"paths": {
"@/*": ["*"]
},