1
0
mirror of https://github.com/misskey-dev/misskey.git synced 2026-07-25 09:45:04 +02:00
Files
misskey/packages/frontend/vite.config.ts
syuilo 15c187ffa2 enhance(frontend): misskey-native lightbox (#17687)
* wip

* wip

* Update MkImageGallery.item.vue

* wip

* Update MkImageGallery.item.vue

* Update MkImageGallery.item.vue

* wip

* wip

* wip

* wip

* wip

* Update MkImageGallery.vue

* Update MkImageGallery.vue

* wip

* wip

* Update MkMediaList.vue

* Update MkImageGallery.item.vue

* fix

* wip

* Update MkImageGallery.item.vue

* wip

* wip

* Update MkImageGallery.item.vue

* refactor

* Update MkImageGallery.item.vue

* Update MkImageGallery.vue

* Delete animation.ts

* wip

* wip

* Update MkImageGallery.item.vue

* Update MkImageGallery.item.vue

* wip

* wip

* Update MkImageGallery.vue

* Update MkImageGallery.vue

* Update MkImageGallery.item.vue

* fix

* Update MkImageGallery.item.vue

* add note

* lint

* Update MkMediaList.vue

* refactor

* Update MkImageGallery.item.vue

* wip

* Update MkImageGallery.item.vue

* fix

* Update MkImageGallery.item.vue

* wip

* Update MkImageGallery.item.vue

* wip

* wip

* Update MkImageGallery.item.vue

* Update MkImageGallery.item.vue

* Update MkImageGallery.item.vue

* Update MkImageGallery.item.vue

* Update MkVideoContol.vue

* wip

* Update MkMediaVideo.vue

* Update MkMediaVideo.vue

* wip

* Update MkImageGallery.vue

* Update MkVideoContol.vue

* Update MkVideoContol.vue

* Improve image viewer (#17696)

* wip

* fix

* fix

* 🎨

* fix

* fix: Video要素をpropsで渡すのをやめる

* 🎨

* fix

* wip

* fix

* fix: 画面外にドラッグできるのを修正

* fix lint

* fix

* fix

* fix

* refactor

* add comment

* fix: 画像を新しいタブで開くが機能しなくなっていた問題を修正

* fix

* clean up

* attempt to fix

* fix

* enhance: ブラウザの戻るボタンで閉じる

* Revert "fix: 画面外にドラッグできるのを修正"

This reverts commit ea2ddc2620.

* Reapply "fix: 画面外にドラッグできるのを修正"

This reverts commit 87171980a7.

* fix

* fix: 存在しない要素がsourceElementのときに閉じると画像が飛んでいく問題を修正

* fix: clampに余白を追加

* fix duplicated condition

* fix

* fix typo

* fix(frontend/imagegallery): ボタンの当たり判定がまだ小さいのを修正 (#17697)

* wip

* fix

* fix

* 🎨

* fix

* fix: Video要素をpropsで渡すのをやめる

* 🎨

* fix

* wip

* fix

* fix: 画面外にドラッグできるのを修正

* fix lint

* fix

* fix

* fix

* refactor

* add comment

* fix: 画像を新しいタブで開くが機能しなくなっていた問題を修正

* fix

* clean up

* attempt to fix

* fix

* enhance: ブラウザの戻るボタンで閉じる

* Revert "fix: 画面外にドラッグできるのを修正"

This reverts commit ea2ddc2620.

* Reapply "fix: 画面外にドラッグできるのを修正"

This reverts commit 87171980a7.

* fix

* fix: 存在しない要素がsourceElementのときに閉じると画像が飛んでいく問題を修正

* fix: clampに余白を追加

* fix duplicated condition

* fix

* fix typo

* fix

* Update Changelog

* indent

* fix

* fix

* refactor: rename componet

* fix

* fix

* fix

---------

Co-authored-by: かっこかり <67428053+kakkokari-gtyih@users.noreply.github.com>
2026-07-12 11:58:44 +09:00

266 lines
8.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import path from 'path';
import pluginVue from '@vitejs/plugin-vue';
import pluginGlsl from 'vite-plugin-glsl';
import { replacePlugin } from 'rolldown/plugins';
import { visualizer } from 'rollup-plugin-visualizer';
import type { PluginOption, UserConfig } from 'vite';
import { defineConfig } from 'vite';
import { load as loadYaml } from 'js-yaml';
import { promises as fsp } from 'fs';
import locales from 'i18n';
import meta from '../../package.json';
import packageInfo from './package.json' with { type: 'json' };
import pluginUnwindCssModuleClassName from './lib/rollup-plugin-unwind-css-module-class-name.js';
import pluginJson5 from './lib/vite-plugin-json5.js';
import type { Options as SearchIndexOptions } from './lib/vite-plugin-create-search-index.js';
import pluginCreateSearchIndex from './lib/vite-plugin-create-search-index.js';
import pluginWatchLocales from './lib/vite-plugin-watch-locales.js';
import { pluginRemoveUnrefI18n } from '../frontend-builder/rollup-plugin-remove-unref-i18n.js';
import { Features } from 'lightningcss';
const url = process.env.NODE_ENV === 'development' ? (loadYaml(await fsp.readFile('../../.config/default.yml', 'utf-8')) as any).url : null;
const host = url ? (new URL(url)).hostname : undefined;
const extensions = ['.ts', '.tsx', '.js', '.jsx', '.mjs', '.json', '.json5', '.svg', '.sass', '.scss', '.css', '.vue'];
function getBundleVisualizerPlugin(): PluginOption[] {
if (process.env.FRONTEND_BUNDLE_VISUALIZER !== 'true') return [];
const visualizerOptions = {
title: 'Misskey frontend bundle visualizer',
gzipSize: true,
brotliSize: true,
projectRoot: path.resolve(__dirname, '../..'),
};
const plugins = [
visualizer({
...visualizerOptions,
filename: process.env.FRONTEND_BUNDLE_VISUALIZER_FILE,
template: 'raw-data',
}) as PluginOption,
];
if (process.env.FRONTEND_BUNDLE_VISUALIZER_HTML_FILE != null) {
plugins.push(visualizer({
...visualizerOptions,
filename: process.env.FRONTEND_BUNDLE_VISUALIZER_HTML_FILE,
template: 'treemap',
}) as PluginOption);
}
return plugins;
}
/**
* 検索インデックスの生成設定
*/
export const searchIndexes = [{
targetFilePaths: ['src/pages/settings/*.vue'],
mainVirtualModule: 'search-index:settings',
modulesToHmrOnUpdate: ['src/pages/settings/index.vue'],
verbose: process.env.FRONTEND_SEARCH_INDEX_VERBOSE === 'true',
}, {
targetFilePaths: ['src/pages/admin/*.vue'],
mainVirtualModule: 'search-index:admin',
modulesToHmrOnUpdate: ['src/pages/admin/index.vue'],
verbose: process.env.FRONTEND_SEARCH_INDEX_VERBOSE === 'true',
}] satisfies SearchIndexOptions[];
/**
* Misskeyのフロントエンドにバンドルせず、CDNなどから別途読み込むリソースを記述する。
* CDNを使わずにバンドルしたい場合、以下の配列から該当要素を削除orコメントアウトすればOK
*/
const externalPackages = [
// shikiコードブロックのシンタックスハイライトで使用中はテーマ・言語の定義の容量が大きいため、それらはCDNから読み込む
{
name: 'shiki',
match: /^shiki\/(?<subPkg>(langs|themes))$/,
path(id: string, pattern: RegExp): string {
const match = pattern.exec(id)?.groups;
return match
? `https://esm.sh/shiki@${packageInfo.dependencies.shiki}/${match['subPkg']}`
: id;
},
},
];
export const hash = (str: string, seed = 0): number => {
let h1 = 0xdeadbeef ^ seed,
h2 = 0x41c6ce57 ^ seed;
for (let i = 0, ch; i < str.length; i++) {
ch = str.charCodeAt(i);
h1 = Math.imul(h1 ^ ch, 2654435761);
h2 = Math.imul(h2 ^ ch, 1597334677);
}
h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507) ^ Math.imul(h2 ^ (h2 >>> 13), 3266489909);
h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507) ^ Math.imul(h1 ^ (h1 >>> 13), 3266489909);
return 4294967296 * (2097151 & h2) + (h1 >>> 0);
};
export const BASE62_DIGITS = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
export function toBase62(n: number): string {
if (n === 0) {
return '0';
}
let result = '';
while (n > 0) {
result = BASE62_DIGITS[n % BASE62_DIGITS.length] + result;
n = Math.floor(n / BASE62_DIGITS.length);
}
return result;
}
export function getConfig(): UserConfig {
const localesHash = toBase62(hash(JSON.stringify(locales)));
return {
base: '/vite/',
// The console is shared with backend, so clearing the console will also clear the backend log.
clearScreen: false,
server: {
// The backend allows access from any addresses, so vite also allows access from any addresses.
host: '0.0.0.0',
allowedHosts: host ? [host] : undefined,
port: 5173,
strictPort: true,
hmr: {
// バックエンド経由での起動時、Viteは5173経由でアセットを参照していると思い込んでいるが実際は3000から配信される
// そのため、バックエンドのWSサーバーにHMRのWSリクエストが吸収されてしまい、正しくHMRが機能しない
// クライアント側のWSポートをViteサーバーのポートに強制させることで、正しくHMRが機能するようになる
clientPort: 5173,
},
headers: { // なんか効かない
'X-Frame-Options': 'DENY',
},
},
plugins: [
pluginWatchLocales(),
...searchIndexes.map(options => pluginCreateSearchIndex(options)),
pluginVue(),
pluginRemoveUnrefI18n(),
pluginUnwindCssModuleClassName(),
pluginJson5(),
pluginGlsl({ minify: true }),
...process.env.NODE_ENV === 'production'
? [
replacePlugin({
'isChromatic()': JSON.stringify(false),
}, {
preventAssignment: true,
}),
]
: [],
...getBundleVisualizerPlugin(),
],
resolve: {
extensions,
alias: {
'@/': __dirname + '/src/',
'@@/': __dirname + '/../frontend-shared/',
'/client-assets/': __dirname + '/assets/',
'/static-assets/': __dirname + '/../backend/assets/',
'/fluent-emoji/': '@misskey-dev/emoji-assets/fluent-emoji/',
},
},
css: {
lightningcss: {
exclude: Features.LightDark,
},
modules: {
generateScopedName(name, filename, _css): string {
const id = (path.relative(__dirname, filename.split('?')[0]) + '-' + name).replace(/[\\\/\.\?&=]/g, '-').replace(/(src-|vue-)/g, '');
if (process.env.NODE_ENV === 'production') {
return 'x' + toBase62(hash(id)).substring(0, 4);
} else {
return id;
}
},
},
},
define: {
_VERSION_: JSON.stringify(meta.version),
_LANGS_: JSON.stringify(Object.entries(locales).map(([k, v]) => [k, v._lang_])),
_ENV_: JSON.stringify(process.env.NODE_ENV),
_DEV_: process.env.NODE_ENV !== 'production',
_PERF_PREFIX_: JSON.stringify('Misskey:'),
__VUE_OPTIONS_API__: false,
__VUE_PROD_DEVTOOLS__: false,
},
build: {
target: [
'chrome130',
'firefox132',
'safari18.2',
],
manifest: 'manifest.json',
rolldownOptions: {
experimental: {
nativeMagicString: true,
},
input: {
i18n: './src/i18n.ts',
entry: './src/_boot_.ts',
},
external: externalPackages.map(p => p.match),
preserveEntrySignatures: 'allow-extension',
output: {
codeSplitting: {
groups: [{
name: 'vue',
test: /node_modules[\\/]vue/,
}, {
// split i18n related module to distinct module
name: 'i18n',
includeDependenciesRecursively: false,
test: /i18n\.ts|locale\.ts/,
}],
},
entryFileNames: `scripts/${localesHash}-[hash:8].js`,
chunkFileNames: `scripts/${localesHash}-[hash:8].js`,
assetFileNames: `assets/${localesHash}-[hash:8][extname]`,
paths(id) {
for (const p of externalPackages) {
if (p.match.test(id)) {
return p.path(id, p.match);
}
}
return id;
},
},
},
cssCodeSplit: true,
outDir: __dirname + '/../../built/_frontend_vite_',
assetsDir: '.',
emptyOutDir: false,
sourcemap: process.env.NODE_ENV === 'development',
reportCompressedSize: false,
// https://vitejs.dev/guide/dep-pre-bundling.html#monorepos-and-linked-dependencies
commonjsOptions: {
include: [/misskey-js/, /misskey-reversi/, /misskey-bubble-game/, /node_modules/],
},
},
worker: {
format: 'es',
},
};
}
const config = defineConfig(({ command, mode }) => getConfig());
export default config;