diff --git a/CHANGELOG.md b/CHANGELOG.md
index 27b6113f0f..d77bfd8212 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,7 @@
- 新しい設定項目"fulltextSearch.provider"が追加されました. sqlLike, sqlPgroonga, meilisearchのいずれかを設定出来ます.
- すでにMeilisearchをお使いの場合、 **"fulltextSearch.provider"を"meilisearch"に設定する必要** があります.
- 詳細は #14730 および `.config/example.yml` または `.config/docker_example.yml`の'Fulltext search configuration'をご参照願います.
+- 【開発者向け】従来の開発モードでHMRが機能しない問題が修正されたため、バックエンド・フロントエンド分離型の開発モードが削除されました。開発環境においてconfigの変更が必要となる可能性があります。
### General
- Feat: カスタム絵文字管理画面をリニューアル #10996
@@ -46,6 +47,7 @@
(Cherry-picked from https://github.com/yojo-art/cherrypick/pull/153)
- Fix: 非ログイン時のサーバー概要画面のメニューボタンが押せないことがあるのを修正
(Cherry-picked from https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/656)
+- Fix: URLにはじめから`#pswp`が含まれている場合に画像ビューワーがブラウザの戻るボタンで閉じられない問題を修正
### Server
- Enhance: pg_bigmが利用できるよう、ノートの検索をILIKE演算子でなくLIKE演算子でLOWER()をかけたテキストに対して行うように
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 54bdb09139..ca4cc53e0d 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -197,25 +197,10 @@ pnpm dev
command.
- Server-side source files and automatically builds them if they are modified. Automatically start the server process(es).
-- Vite HMR (just the `vite` command) is available. The behavior may be different from production.
- Service Worker is watched by esbuild.
-- The front end can be viewed by accessing `http://localhost:5173`.
-- The backend listens on the port configured with `port` in .config/default.yml.
-If you have not changed it from the default, it will be "http://localhost:3000".
-If "port" in .config/default.yml is set to something other than 3000, you need to change the proxy settings in packages/frontend/vite.config.local-dev.ts.
-
-### `MK_DEV_PREFER=backend pnpm dev`
-pnpm dev has another mode with `MK_DEV_PREFER=backend`.
-
-```
-MK_DEV_PREFER=backend pnpm dev
-```
-
-- This mode is closer to the production environment than the default mode.
-- Vite runs behind the backend (the backend will proxy Vite at /vite).
+- Vite HMR (just the `vite` command) is available. The behavior may be different from production.
+- Vite runs behind the backend (the backend will proxy Vite at /vite and /embed_vite except for websocket used for HMR).
- You can see Misskey by accessing `http://localhost:3000` (Replace `3000` with the port configured with `port` in .config/default.yml).
-- To change the port of Vite, specify with `VITE_PORT` environment variable.
-- HMR may not work in some environments such as Windows.
## Testing
You can run non-backend tests by executing following commands:
@@ -497,6 +482,11 @@ describe('test', () => {
コード上でMisskeyのドメイン固有の概念には`Mi`をprefixすることで、他のドメインの同様の概念と区別できるほか、名前の衝突を防ぐ。
ただし、文脈上Misskeyのものを指すことが明らかであり、名前の衝突の恐れがない場合は、一時的なローカル変数に限って`Mi`を省略してもよい。
+### Misskey.jsの型生成
+```bash
+pnpm build-misskey-js-with-types
+```
+
### How to resolve conflictions occurred at pnpm-lock.yaml?
Just execute `pnpm` to fix it.
diff --git a/locales/de-DE.yml b/locales/de-DE.yml
index d110fba34b..43b63c2423 100644
--- a/locales/de-DE.yml
+++ b/locales/de-DE.yml
@@ -684,7 +684,7 @@ smtpSecureInfo: "Schalte dies aus, falls du STARTTLS verwendest."
testEmail: "Emailversand testen"
wordMute: "Wortstummschaltung"
wordMuteDescription: "Minimiert Notizen, die das angegebene Wort oder den angegebenen Ausdruck enthalten. Minimierte Notizen können angezeigt werden, indem du auf sie klickst."
-hardWordMute: "Harte Wort-Stummschaltung"
+hardWordMute: "Harte Wortstummschaltung"
showMutedWord: "Stummgeschaltete Wörter anzeigen"
hardWordMuteDescription: "Blendet Notizen aus, die das angegebene Wort oder die angegebene Phrase enthalten. Im Gegensatz zur Wortstummschaltung wird die Notiz vollständig ausgeblendet."
regexpError: "Fehler in einem regulären Ausdruck"
diff --git a/locales/ru-RU.yml b/locales/ru-RU.yml
index 64747e0b91..589155ee4b 100644
--- a/locales/ru-RU.yml
+++ b/locales/ru-RU.yml
@@ -1063,7 +1063,7 @@ hiddenTags: "Скрытые хештеги"
notesSearchNotAvailable: "Поиск заметок недоступен"
license: "Лицензия"
unfavoriteConfirm: "Удалить избранное?"
-myClips: "Мои клипы"
+myClips: "Мои подборки"
drivecleaner: "Очиститель дисков"
retryAllQueuesNow: "Повторить все очереди сейчас"
retryAllQueuesConfirmTitle: "Хотите попробовать ещё раз?"
diff --git a/packages/backend/src/server/web/ClientServerService.ts b/packages/backend/src/server/web/ClientServerService.ts
index 1a75096c4e..d450c3fb01 100644
--- a/packages/backend/src/server/web/ClientServerService.ts
+++ b/packages/backend/src/server/web/ClientServerService.ts
@@ -317,16 +317,19 @@ export class ClientServerService {
done();
});
} else {
+ const configUrl = new URL(this.config.url);
+ const urlOriginWithoutPort = configUrl.origin.replace(/:\d+$/, '');
+
const port = (process.env.VITE_PORT ?? '5173');
fastify.register(fastifyProxy, {
- upstream: 'http://localhost:' + port,
+ upstream: urlOriginWithoutPort + ':' + port,
prefix: '/vite',
rewritePrefix: '/vite',
});
const embedPort = (process.env.EMBED_VITE_PORT ?? '5174');
fastify.register(fastifyProxy, {
- upstream: 'http://localhost:' + embedPort,
+ upstream: urlOriginWithoutPort + ':' + embedPort,
prefix: '/embed_vite',
rewritePrefix: '/embed_vite',
});
diff --git a/packages/frontend-embed/package.json b/packages/frontend-embed/package.json
index 2ece7b793d..26c22abb4e 100644
--- a/packages/frontend-embed/package.json
+++ b/packages/frontend-embed/package.json
@@ -4,7 +4,6 @@
"type": "module",
"scripts": {
"watch": "vite",
- "dev": "vite --config vite.config.local-dev.ts --debug hmr",
"build": "vite build",
"typecheck": "vue-tsc --noEmit",
"eslint": "eslint --quiet \"src/**/*.{ts,vue}\"",
diff --git a/packages/frontend-embed/src/index.html b/packages/frontend-embed/src/index.html
deleted file mode 100644
index 47b0b0e84e..0000000000
--- a/packages/frontend-embed/src/index.html
+++ /dev/null
@@ -1,36 +0,0 @@
-
-
-
-
-
-
-
-
- [DEV] Loading...
-
-
-
-
-
-
-
-
-
-
-
diff --git a/packages/frontend-embed/vite.config.local-dev.ts b/packages/frontend-embed/vite.config.local-dev.ts
deleted file mode 100644
index bf2f478887..0000000000
--- a/packages/frontend-embed/vite.config.local-dev.ts
+++ /dev/null
@@ -1,96 +0,0 @@
-import dns from 'dns';
-import { readFile } from 'node:fs/promises';
-import type { IncomingMessage } from 'node:http';
-import { defineConfig } from 'vite';
-import type { UserConfig } from 'vite';
-import * as yaml from 'js-yaml';
-import locales from '../../locales/index.js';
-import { getConfig } from './vite.config.js';
-
-dns.setDefaultResultOrder('ipv4first');
-
-const defaultConfig = getConfig();
-
-const { port } = yaml.load(await readFile('../../.config/default.yml', 'utf-8'));
-
-const httpUrl = `http://localhost:${port}/`;
-const websocketUrl = `ws://localhost:${port}/`;
-
-// activitypubリクエストはProxyを通し、それ以外はViteの開発サーバーを返す
-function varyHandler(req: IncomingMessage) {
- if (req.headers.accept?.includes('application/activity+json')) {
- return null;
- }
- return '/index.html';
-}
-
-const devConfig: UserConfig = {
- // 基本の設定は vite.config.js から引き継ぐ
- ...defaultConfig,
- root: 'src',
- publicDir: '../assets',
- base: '/embed',
- server: {
- host: 'localhost',
- port: 5174,
- proxy: {
- '/api': {
- changeOrigin: true,
- target: httpUrl,
- },
- '/assets': httpUrl,
- '/static-assets': httpUrl,
- '/client-assets': httpUrl,
- '/files': httpUrl,
- '/twemoji': httpUrl,
- '/fluent-emoji': httpUrl,
- '/sw.js': httpUrl,
- '/streaming': {
- target: websocketUrl,
- ws: true,
- },
- '/favicon.ico': httpUrl,
- '/robots.txt': httpUrl,
- '/embed.js': httpUrl,
- '/identicon': {
- target: httpUrl,
- rewrite(path) {
- return path.replace('@localhost:5173', '');
- },
- },
- '/url': httpUrl,
- '/proxy': httpUrl,
- '/_info_card_': httpUrl,
- '/bios': httpUrl,
- '/cli': httpUrl,
- '/inbox': httpUrl,
- '/emoji/': httpUrl,
- '/notes': {
- target: httpUrl,
- bypass: varyHandler,
- },
- '/users': {
- target: httpUrl,
- bypass: varyHandler,
- },
- '/.well-known': {
- target: httpUrl,
- },
- },
- },
- build: {
- ...defaultConfig.build,
- rollupOptions: {
- ...defaultConfig.build?.rollupOptions,
- input: 'index.html',
- },
- },
-
- define: {
- ...defaultConfig.define,
- _LANGS_FULL_: JSON.stringify(Object.entries(locales)),
- },
-};
-
-export default defineConfig(({ command, mode }) => devConfig);
-
diff --git a/packages/frontend-embed/vite.config.ts b/packages/frontend-embed/vite.config.ts
index 151d316190..3d628c800e 100644
--- a/packages/frontend-embed/vite.config.ts
+++ b/packages/frontend-embed/vite.config.ts
@@ -1,12 +1,17 @@
import path from 'path';
import pluginVue from '@vitejs/plugin-vue';
import { type UserConfig, defineConfig } from 'vite';
+import * as yaml from 'js-yaml';
+import { promises as fsp } from 'fs';
import locales from '../../locales/index.js';
import meta from '../../package.json';
import packageInfo from './package.json' with { type: 'json' };
import pluginJson5 from './vite.json5.js';
+const url = process.env.NODE_ENV === 'development' ? yaml.load(await fsp.readFile('../../.config/default.yml', 'utf-8')).url : null;
+const host = url ? (new URL(url)).hostname : undefined;
+
const extensions = ['.ts', '.tsx', '.js', '.jsx', '.mjs', '.json', '.json5', '.svg', '.sass', '.scss', '.css', '.vue'];
/**
@@ -62,6 +67,7 @@ export function getConfig(): UserConfig {
base: '/embed_vite/',
server: {
+ host,
port: 5174,
hmr: {
// バックエンド経由での起動時、Viteは5174経由でアセットを参照していると思い込んでいるが実際は3000から配信される
diff --git a/packages/frontend/package.json b/packages/frontend/package.json
index d4ae4943de..67a2c59feb 100644
--- a/packages/frontend/package.json
+++ b/packages/frontend/package.json
@@ -4,7 +4,6 @@
"type": "module",
"scripts": {
"watch": "vite",
- "dev": "vite --config vite.config.local-dev.ts --debug hmr",
"build": "vite build",
"storybook-dev": "nodemon --verbose --watch src --ext \"mdx,ts,vue\" --ignore \"*.stories.ts\" --exec \"pnpm build-storybook-pre && pnpm exec storybook dev -p 6006 --ci\"",
"build-storybook-pre": "(tsc -p .storybook || echo done.) && node .storybook/generate.js && node .storybook/preload-locale.js && node .storybook/preload-theme.js",
diff --git a/packages/frontend/src/_dev_boot_.ts b/packages/frontend/src/_dev_boot_.ts
deleted file mode 100644
index f312765dcf..0000000000
--- a/packages/frontend/src/_dev_boot_.ts
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * SPDX-FileCopyrightText: syuilo and misskey-project
- * SPDX-License-Identifier: AGPL-3.0-only
- */
-
-await main();
-
-import('@/_boot_.js');
-
-/**
- * backend/src/server/web/boot.jsで差し込まれている起動処理のうち、最低限必要なものを模倣するための処理
- */
-async function main() {
- const forceError = localStorage.getItem('forceError');
- if (forceError != null) {
- renderError('FORCED_ERROR', 'This error is forced by having forceError in local storage.');
- }
-
- //#region Detect language & fetch translations
-
- // dev-modeの場合は常に取り直す
- const supportedLangs = _LANGS_.map(it => it[0]);
- let lang: string | null | undefined = localStorage.getItem('lang');
- if (lang == null || !supportedLangs.includes(lang)) {
- if (supportedLangs.includes(navigator.language)) {
- lang = navigator.language;
- } else {
- lang = supportedLangs.find(x => x.split('-')[0] === navigator.language);
-
- // Fallback
- if (lang == null) lang = 'en-US';
- }
- }
-
- // TODO:今のままだと言語ファイル変更後はpnpm devをリスタートする必要があるので、chokidarを使ったり等で対応できるようにする
- const locale = _LANGS_FULL_.find(it => it[0] === lang);
- localStorage.setItem('lang', lang);
- localStorage.setItem('locale', JSON.stringify(locale[1]));
- localStorage.setItem('localeVersion', _VERSION_);
- //#endregion
-
- //#region Theme
- const theme = localStorage.getItem('theme');
- if (theme) {
- for (const [k, v] of Object.entries(JSON.parse(theme))) {
- document.documentElement.style.setProperty(`--MI_THEME-${k}`, v.toString());
-
- // HTMLの theme-color 適用
- if (k === 'htmlThemeColor') {
- for (const tag of document.head.children) {
- if (tag.tagName === 'META' && tag.getAttribute('name') === 'theme-color') {
- tag.setAttribute('content', v);
- break;
- }
- }
- }
- }
- }
- const colorScheme = localStorage.getItem('colorScheme');
- if (colorScheme) {
- document.documentElement.style.setProperty('color-scheme', colorScheme);
- }
- //#endregion
-
- const fontSize = localStorage.getItem('fontSize');
- if (fontSize) {
- document.documentElement.classList.add('f-' + fontSize);
- }
-
- const useSystemFont = localStorage.getItem('useSystemFont');
- if (useSystemFont) {
- document.documentElement.classList.add('useSystemFont');
- }
-
- const wallpaper = localStorage.getItem('wallpaper');
- if (wallpaper) {
- document.documentElement.style.backgroundImage = `url(${wallpaper})`;
- }
-
- const customCss = localStorage.getItem('customCss');
- if (customCss && customCss.length > 0) {
- const style = document.createElement('style');
- style.innerHTML = customCss;
- document.head.appendChild(style);
- }
-}
-
-function renderError(code: string, details?: string) {
- console.log(code, details);
-}
diff --git a/packages/frontend/src/boot/common.ts b/packages/frontend/src/boot/common.ts
index bfe5c4f5f7..ae6b1aee26 100644
--- a/packages/frontend/src/boot/common.ts
+++ b/packages/frontend/src/boot/common.ts
@@ -98,6 +98,11 @@ export async function common(createVue: () => App) {
// タッチデバイスでCSSの:hoverを機能させる
document.addEventListener('touchend', () => {}, { passive: true });
+ // URLに#pswpを含む場合は取り除く
+ if (location.hash === '#pswp') {
+ history.replaceState(null, '', location.href.replace('#pswp', ''));
+ }
+
// 一斉リロード
reloadChannel.addEventListener('message', path => {
if (path !== null) location.href = path;
diff --git a/packages/frontend/src/index.html b/packages/frontend/src/index.html
deleted file mode 100644
index 84ba9dfabc..0000000000
--- a/packages/frontend/src/index.html
+++ /dev/null
@@ -1,37 +0,0 @@
-
-
-
-
-
-
-
-
- [DEV] Loading...
-
-
-
-
-
-
-
-
-
-
-
diff --git a/packages/frontend/src/pages/welcome.entrance.a.vue b/packages/frontend/src/pages/welcome.entrance.a.vue
index 68938f0bbf..34c5c3ce6c 100644
--- a/packages/frontend/src/pages/welcome.entrance.a.vue
+++ b/packages/frontend/src/pages/welcome.entrance.a.vue
@@ -53,6 +53,7 @@ function getInstanceIcon(instance: Misskey.entities.FederationInstance): string
if (!instance.iconUrl) {
return '';
}
+
return getProxiedImageUrl(instance.iconUrl, 'preview');
}
diff --git a/packages/frontend/vite.config.local-dev.ts b/packages/frontend/vite.config.local-dev.ts
deleted file mode 100644
index 922fb45995..0000000000
--- a/packages/frontend/vite.config.local-dev.ts
+++ /dev/null
@@ -1,101 +0,0 @@
-import dns from 'dns';
-import { readFile } from 'node:fs/promises';
-import type { IncomingMessage } from 'node:http';
-import { defineConfig } from 'vite';
-import type { UserConfig } from 'vite';
-import * as yaml from 'js-yaml';
-import locales from '../../locales/index.js';
-import { getConfig } from './vite.config.js';
-
-dns.setDefaultResultOrder('ipv4first');
-
-const defaultConfig = getConfig();
-
-const { port } = yaml.load(await readFile('../../.config/default.yml', 'utf-8'));
-
-const httpUrl = `http://localhost:${port}/`;
-const websocketUrl = `ws://localhost:${port}/`;
-const embedUrl = `http://localhost:5174/`;
-
-// activitypubリクエストはProxyを通し、それ以外はViteの開発サーバーを返す
-function varyHandler(req: IncomingMessage) {
- if (req.headers.accept?.includes('application/activity+json')) {
- return null;
- }
- return '/index.html';
-}
-
-const devConfig: UserConfig = {
- // 基本の設定は vite.config.js から引き継ぐ
- ...defaultConfig,
- root: 'src',
- publicDir: '../assets',
- base: './',
- server: {
- host: 'localhost',
- port: 5173,
- proxy: {
- '/api': {
- changeOrigin: true,
- target: httpUrl,
- },
- '/assets': httpUrl,
- '/static-assets': httpUrl,
- '/client-assets': httpUrl,
- '/files': httpUrl,
- '/twemoji': httpUrl,
- '/fluent-emoji': httpUrl,
- '/sw.js': httpUrl,
- '/streaming': {
- target: websocketUrl,
- ws: true,
- },
- '/favicon.ico': httpUrl,
- '/robots.txt': httpUrl,
- '/embed.js': httpUrl,
- '/embed': {
- target: embedUrl,
- ws: true,
- },
- '/identicon': {
- target: httpUrl,
- rewrite(path) {
- return path.replace('@localhost:5173', '');
- },
- },
- '/url': httpUrl,
- '/proxy': httpUrl,
- '/_info_card_': httpUrl,
- '/bios': httpUrl,
- '/cli': httpUrl,
- '/inbox': httpUrl,
- '/emoji/': httpUrl,
- '/notes': {
- target: httpUrl,
- bypass: varyHandler,
- },
- '/users': {
- target: httpUrl,
- bypass: varyHandler,
- },
- '/.well-known': {
- target: httpUrl,
- },
- },
- },
- build: {
- ...defaultConfig.build,
- rollupOptions: {
- ...defaultConfig.build?.rollupOptions,
- input: 'index.html',
- },
- },
-
- define: {
- ...defaultConfig.define,
- _LANGS_FULL_: JSON.stringify(Object.entries(locales)),
- },
-};
-
-export default defineConfig(({ command, mode }) => devConfig);
-
diff --git a/packages/frontend/vite.config.ts b/packages/frontend/vite.config.ts
index 3c4b19a571..d1b7c410dc 100644
--- a/packages/frontend/vite.config.ts
+++ b/packages/frontend/vite.config.ts
@@ -2,6 +2,8 @@ import path from 'path';
import pluginReplace from '@rollup/plugin-replace';
import pluginVue from '@vitejs/plugin-vue';
import { type UserConfig, defineConfig } from 'vite';
+import * as yaml from 'js-yaml';
+import { promises as fsp } from 'fs';
import locales from '../../locales/index.js';
import meta from '../../package.json';
@@ -9,6 +11,9 @@ import packageInfo from './package.json' with { type: 'json' };
import pluginUnwindCssModuleClassName from './lib/rollup-plugin-unwind-css-module-class-name.js';
import pluginJson5 from './vite.json5.js';
+const url = process.env.NODE_ENV === 'development' ? yaml.load(await fsp.readFile('../../.config/default.yml', 'utf-8')).url : null;
+const host = url ? (new URL(url)).hostname : undefined;
+
const extensions = ['.ts', '.tsx', '.js', '.jsx', '.mjs', '.json', '.json5', '.svg', '.sass', '.scss', '.css', '.vue'];
/**
@@ -64,6 +69,7 @@ export function getConfig(): UserConfig {
base: '/vite/',
server: {
+ host,
port: 5173,
hmr: {
// バックエンド経由での起動時、Viteは5173経由でアセットを参照していると思い込んでいるが実際は3000から配信される
diff --git a/scripts/dev.mjs b/scripts/dev.mjs
index 424b29c7cc..d9ed993086 100644
--- a/scripts/dev.mjs
+++ b/scripts/dev.mjs
@@ -77,13 +77,13 @@ execa('pnpm', ['--filter', 'frontend-shared', 'watch'], {
stderr: process.stderr,
});
-execa('pnpm', ['--filter', 'frontend', process.env.MK_DEV_PREFER === 'backend' ? 'watch' : 'dev'], {
+execa('pnpm', ['--filter', 'frontend', 'watch'], {
cwd: _dirname + '/../',
stdout: process.stdout,
stderr: process.stderr,
});
-execa('pnpm', ['--filter', 'frontend-embed', process.env.MK_DEV_PREFER === 'backend' ? 'watch' : 'dev'], {
+execa('pnpm', ['--filter', 'frontend-embed', 'watch'], {
cwd: _dirname + '/../',
stdout: process.stdout,
stderr: process.stderr,