Minify backend (#17054)

* wip

* Update build.js

* Update build.js

* [minify-backend用] フィジビリティ検証 (#16878)

* fix: minify-backend

* 間違えて入れちゃったのを戻す

* 追従

* fix

---------

Co-authored-by: syuilo <4439005+syuilo@users.noreply.github.com>

* test

* use node 24

* Revert "use node 24"

This reverts commit 7ae2debf23.

* Revert "test"

This reverts commit d919879091.

* Update package.json

* wip

* Update compile_config.js

* Revert "Update compile_config.js"

This reverts commit 0ee286f02b.

* Update config.ts

* wip

* Update .swcrc

* Update ClientServerService.ts

* [ci skip] update CHANGELOG

---------

Co-authored-by: おさむのひと <46447427+samunohito@users.noreply.github.com>
This commit is contained in:
syuilo 2026-01-05 20:56:52 +09:00 committed by GitHub
parent 4f65c1529b
commit 7bcfeba7e5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 722 additions and 187 deletions

View File

@ -6,6 +6,7 @@
Dockerfile Dockerfile
build/ build/
built/ built/
src-js/
db/ db/
.devcontainer/compose.yml .devcontainer/compose.yml
node_modules/ node_modules/

1
.gitignore vendored
View File

@ -46,6 +46,7 @@ docker-compose.yml
built built
built-test built-test
js-built js-built
src-js
/data /data
/.cache-loader /.cache-loader
/db /db

View File

@ -23,7 +23,7 @@
- Enhance: OAuthのクライアント情報取得Client Information Discoveryにおいて、IndieWeb Living Standard 11 July 2024で定義されているJSONドキュメント形式に対応しました - Enhance: OAuthのクライアント情報取得Client Information Discoveryにおいて、IndieWeb Living Standard 11 July 2024で定義されているJSONドキュメント形式に対応しました
- JSONによるClient Information Discoveryを行うには、レスポンスの`Content-Type`ヘッダーが`application/json`である必要があります - JSONによるClient Information Discoveryを行うには、レスポンスの`Content-Type`ヘッダーが`application/json`である必要があります
- 従来の実装12 February 2022版・HTML Microformat形式も引き続きサポートされます - 従来の実装12 February 2022版・HTML Microformat形式も引き続きサポートされます
- Enhance: メモリ使用量を削減
## 2025.12.2 ## 2025.12.2

View File

@ -102,6 +102,7 @@ COPY --chown=misskey:misskey --from=native-builder /misskey/packages/misskey-js/
COPY --chown=misskey:misskey --from=native-builder /misskey/packages/misskey-reversi/built ./packages/misskey-reversi/built COPY --chown=misskey:misskey --from=native-builder /misskey/packages/misskey-reversi/built ./packages/misskey-reversi/built
COPY --chown=misskey:misskey --from=native-builder /misskey/packages/misskey-bubble-game/built ./packages/misskey-bubble-game/built COPY --chown=misskey:misskey --from=native-builder /misskey/packages/misskey-bubble-game/built ./packages/misskey-bubble-game/built
COPY --chown=misskey:misskey --from=native-builder /misskey/packages/backend/built ./packages/backend/built COPY --chown=misskey:misskey --from=native-builder /misskey/packages/backend/built ./packages/backend/built
COPY --chown=misskey:misskey --from=native-builder /misskey/packages/backend/src-js ./packages/backend/src-js
COPY --chown=misskey:misskey --from=native-builder /misskey/packages/i18n/built ./packages/i18n/built COPY --chown=misskey:misskey --from=native-builder /misskey/packages/i18n/built ./packages/i18n/built
COPY --chown=misskey:misskey --from=native-builder /misskey/fluent-emojis /misskey/fluent-emojis COPY --chown=misskey:misskey --from=native-builder /misskey/fluent-emojis /misskey/fluent-emojis
COPY --chown=misskey:misskey . ./ COPY --chown=misskey:misskey . ./

View File

@ -28,7 +28,7 @@
"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 && pnpm compile-config && node ./built/boot/entry.js", "start": "cd packages/backend && pnpm compile-config && node ./built/boot/entry.js",
"start:inspect": "cd packages/backend && pnpm compile-config && node --inspect ./built/boot/entry.js", "start:inspect": "cd packages/backend && pnpm compile-config && node --inspect ./built/boot/entry.js",
"start:test": "ncp ./.github/misskey/test.yml ./.config/test.yml && cd packages/backend && cross-env NODE_ENV=test pnpm compile-config && cross-env NODE_ENV=test node ./built/boot/entry.js", "start:test": "ncp ./.github/misskey/test.yml ./.config/test.yml && cd packages/backend && cross-env NODE_ENV=test pnpm compile-config && cross-env NODE_ENV=test node ./built/boot/entry.js",
"cli": "cd packages/backend && pnpm cli", "cli": "cd packages/backend && pnpm cli",

121
packages/backend/build.js Normal file
View File

@ -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.`);
}

View File

@ -1,6 +1,6 @@
import { DataSource } from 'typeorm'; import { DataSource } from 'typeorm';
import { loadConfig } from './built/config.js'; import { loadConfig } from './src-js/config.js';
import { entities } from './built/postgres.js'; import { entities } from './src-js/postgres.js';
const isConcurrentIndexMigrationEnabled = process.env.MISSKEY_MIGRATION_CREATE_INDEX_CONCURRENTLY === '1'; const isConcurrentIndexMigrationEnabled = process.env.MISSKEY_MIGRATION_CREATE_INDEX_CONCURRENTLY === '1';

View File

@ -12,10 +12,10 @@
"start:test": "cross-env NODE_ENV=test pnpm compile-config && cross-env NODE_ENV=test node ./built/boot/entry.js", "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", "migrate": "pnpm compile-config && pnpm typeorm migration:run -d ormconfig.js",
"revert": "pnpm compile-config && pnpm typeorm migration:revert -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", "check:connect": "pnpm compile-config && node ./scripts/check_connect.js",
"compile-config": "node ./scripts/compile_config.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", "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",
"build:tsc": "tsgo -p tsconfig.json && tsc-alias -p tsconfig.json", "build:tsc": "tsgo -p tsconfig.json && tsc-alias -p tsconfig.json",
@ -219,6 +219,7 @@
"aws-sdk-client-mock": "4.1.0", "aws-sdk-client-mock": "4.1.0",
"cbor": "10.0.11", "cbor": "10.0.11",
"cross-env": "10.1.0", "cross-env": "10.1.0",
"esbuild-plugin-swc": "1.0.1",
"eslint-plugin-import": "2.32.0", "eslint-plugin-import": "2.32.0",
"execa": "9.6.1", "execa": "9.6.1",
"fkill": "10.0.1", "fkill": "10.0.1",

View File

@ -4,8 +4,8 @@
*/ */
import Redis from 'ioredis'; import Redis from 'ioredis';
import { loadConfig } from '../built/config.js'; import { loadConfig } from '../src-js/config.js';
import { createPostgresDataSource } from '../built/postgres.js'; import { createPostgresDataSource } from '../src-js/postgres.js';
const config = loadConfig(); const config = loadConfig();
@ -28,10 +28,8 @@ async function connectToRedis(redisOptions) {
try { try {
await redis.connect(); await redis.connect();
resolve(); resolve();
} catch (e) { } catch (e) {
reject(e); reject(e);
} finally { } finally {
redis.disconnect(false); redis.disconnect(false);
} }
@ -50,7 +48,7 @@ const promises = Array
])) ]))
.map(connectToRedis) .map(connectToRedis)
.concat([ .concat([
connectToPostgres() connectToPostgres(),
]); ]);
await Promise.all(promises); await Promise.all(promises);

View File

@ -3,8 +3,8 @@
* SPDX-License-Identifier: AGPL-3.0-only * SPDX-License-Identifier: AGPL-3.0-only
*/ */
import { writeFileSync, existsSync } from 'node:fs';
import { execa } from 'execa'; import { execa } from 'execa';
import { writeFileSync, existsSync } from "node:fs";
async function main() { async function main() {
if (!process.argv.includes('--no-build')) { if (!process.argv.includes('--no-build')) {
@ -19,10 +19,10 @@ async function main() {
} }
/** @type {import('../src/config.js')} */ /** @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')} */ /** @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 config = loadConfig();
const spec = genOpenapiSpec(config, true); const spec = genOpenapiSpec(config, true);

View File

@ -4,8 +4,6 @@
*/ */
import * as fs from 'node:fs'; import * as fs from 'node:fs';
import { fileURLToPath } from 'node:url';
import { dirname } from 'node:path';
import * as os from 'node:os'; import * as os from 'node:os';
import cluster from 'node:cluster'; import cluster from 'node:cluster';
import chalk from 'chalk'; import chalk from 'chalk';
@ -17,20 +15,15 @@ import { showMachineInfo } from '@/misc/show-machine-info.js';
import { envOption } from '@/env.js'; import { envOption } from '@/env.js';
import { jobQueue, server } from './common.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 logger = new Logger('core', 'cyan');
const bootLogger = logger.createSubLogger('boot', 'magenta'); const bootLogger = logger.createSubLogger('boot', 'magenta');
const themeColor = chalk.hex('#86b300'); const themeColor = chalk.hex('#86b300');
function greet() { function greet(props: { version: string }) {
if (!envOption.quiet) { if (!envOption.quiet) {
//#region Misskey logo //#region Misskey logo
const v = `v${meta.version}`; const v = `v${props.version}`;
console.log(themeColor(' _____ _ _ ')); console.log(themeColor(' _____ _ _ '));
console.log(themeColor(' | |_|___ ___| |_ ___ _ _ ')); console.log(themeColor(' | |_|___ ___| |_ ___ _ _ '));
console.log(themeColor(' | | | | |_ -|_ -| \'_| -_| | |')); console.log(themeColor(' | | | | |_ -|_ -| \'_| -_| | |'));
@ -46,7 +39,7 @@ function greet() {
} }
bootLogger.info('Welcome to Misskey!'); 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 // initialize app
try { try {
greet(); config = loadConfigBoot();
greet({ version: config.version });
showEnvironment(); showEnvironment();
await showMachineInfo(bootLogger); await showMachineInfo(bootLogger);
showNodejsVersion(); showNodejsVersion();
config = loadConfigBoot();
//await connectDb(); //await connectDb();
if (config.pidFile) fs.writeFileSync(config.pidFile, process.pid.toString()); if (config.pidFile) fs.writeFileSync(config.pidFile, process.pid.toString());
} catch (e) { } catch (e) {

View File

@ -219,24 +219,42 @@ export type FulltextSearchProvider = 'sqlLike' | 'sqlPgroonga' | 'meilisearch';
const _filename = fileURLToPath(import.meta.url); const _filename = fileURLToPath(import.meta.url);
const _dirname = dirname(_filename); 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;
}
export const compiledConfigFilePath = fs.existsSync(compiledConfigFilePathForTest) ? compiledConfigFilePathForTest : resolve(_dirname, '../../../built/.config.json'); /** 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(projectBuiltDir, '.config.json');
export function loadConfig(): Config { export function loadConfig(): Config {
if (!fs.existsSync(compiledConfigFilePath)) { if (!fs.existsSync(compiledConfigFilePath)) {
throw new Error('Compiled configuration file not found. Try running \'pnpm compile-config\'.'); 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 frontendManifestExists = fs.existsSync(resolve(projectBuiltDir, '_frontend_vite_/manifest.json'));
const frontendEmbedManifestExists = fs.existsSync(_dirname + '/../../../built/_frontend_embed_vite_/manifest.json'); const frontendEmbedManifestExists = fs.existsSync(resolve(projectBuiltDir, '_frontend_embed_vite_/manifest.json'));
const frontendManifest = frontendManifestExists ? 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 } }; : { 'src/_boot_.ts': { file: null } };
const frontendEmbedManifest = frontendEmbedManifestExists ? 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 } }; : { 'src/boot.ts': { file: null } };
const config = JSON.parse(fs.readFileSync(compiledConfigFilePath, 'utf-8')) as Source; const config = JSON.parse(fs.readFileSync(compiledConfigFilePath, 'utf-8')) as Source;

View File

@ -4,8 +4,9 @@
*/ */
import { randomUUID } from 'node:crypto'; import { randomUUID } from 'node:crypto';
import { dirname } from 'node:path'; import { dirname, resolve } from 'node:path';
import { fileURLToPath } from 'node:url'; import { fileURLToPath } from 'node:url';
import * as fs from 'node:fs';
import { Inject, Injectable } from '@nestjs/common'; import { Inject, Injectable } from '@nestjs/common';
import ms from 'ms'; import ms from 'ms';
import sharp from 'sharp'; import sharp from 'sharp';
@ -69,13 +70,28 @@ import type { FastifyError, FastifyInstance, FastifyPluginOptions, FastifyReply
const _filename = fileURLToPath(import.meta.url); const _filename = fileURLToPath(import.meta.url);
const _dirname = dirname(_filename); const _dirname = dirname(_filename);
const staticAssets = `${_dirname}/../../../assets/`; let rootDir = _dirname;
const clientAssets = `${_dirname}/../../../../frontend/assets/`; // 見つかるまで上に遡る
const assets = `${_dirname}/../../../../../built/_frontend_dist_/`; while (!fs.existsSync(resolve(rootDir, 'packages'))) {
const swAssets = `${_dirname}/../../../../../built/_sw_dist_/`; const parentDir = dirname(rootDir);
const frontendViteOut = `${_dirname}/../../../../../built/_frontend_vite_/`; if (parentDir === rootDir) {
const frontendEmbedViteOut = `${_dirname}/../../../../../built/_frontend_embed_vite_/`; throw new Error('Cannot find root directory');
const tarball = `${_dirname}/../../../../../built/tarball/`; }
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() @Injectable()
export class ClientServerService { export class ClientServerService {
@ -207,6 +223,7 @@ export class ClientServerService {
//#region vite assets //#region vite assets
if (this.config.frontendEmbedManifestExists) { if (this.config.frontendEmbedManifestExists) {
console.log(`[ClientServerService] Using built frontend vite assets. ${frontendViteOut}`);
fastify.register((fastify, options, done) => { fastify.register((fastify, options, done) => {
fastify.register(fastifyStatic, { fastify.register(fastifyStatic, {
root: frontendViteOut, root: frontendViteOut,
@ -226,6 +243,7 @@ export class ClientServerService {
done(); done();
}); });
} else { } else {
console.log('[ClientServerService] Proxying to Vite dev server.');
const urlOriginWithoutPort = configUrl.origin.replace(/:\d+$/, ''); const urlOriginWithoutPort = configUrl.origin.replace(/:\d+$/, '');
const port = (process.env.VITE_PORT ?? '5173'); 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\''); 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'), maxAge: ms('30 days'),
}); });
}); });
@ -312,7 +330,7 @@ export class ClientServerService {
reply.header('Content-Security-Policy', 'default-src \'none\'; style-src \'unsafe-inline\''); 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'), maxAge: ms('30 days'),
}); });
}); });
@ -326,7 +344,7 @@ export class ClientServerService {
} }
const mask = await sharp( const mask = await sharp(
`${_dirname}/../../../node_modules/@discordapp/twemoji/dist/svg/${path.replace('.png', '')}.svg`, `${twemojiDir}/${path.replace('.png', '')}.svg`,
{ density: 1000 }, { density: 1000 },
) )
.resize(488, 488) .resize(488, 488)

View File

@ -34,6 +34,10 @@ services:
source: ../built source: ../built
target: /misskey/packages/backend/built target: /misskey/packages/backend/built
read_only: true read_only: true
- type: bind
source: ../src-js
target: /misskey/packages/backend/src-js
read_only: true
- type: bind - type: bind
source: ../migration source: ../migration
target: /misskey/packages/backend/migration target: /misskey/packages/backend/migration

View File

@ -13,7 +13,7 @@
"experimental": { "experimental": {
"keepImportAssertions": true "keepImportAssertions": true
}, },
"baseUrl": "../built", "baseUrl": "../src-js",
"paths": { "paths": {
"@/*": ["*"] "@/*": ["*"]
}, },

File diff suppressed because it is too large Load Diff