AFFiNE/blocksuite/playground/vite.config.ts
2025-01-08 04:07:56 +00:00

268 lines
8.7 KiB
TypeScript

import fs from 'node:fs';
import { createRequire } from 'node:module';
import { cpus } from 'node:os';
import path, { resolve } from 'node:path';
import { fileURLToPath } from 'node:url';
import type { GetManualChunk } from 'rollup';
import type { Plugin } from 'vite';
import { defineConfig, loadEnv } from 'vite';
import istanbul from 'vite-plugin-istanbul';
import wasm from 'vite-plugin-wasm';
import { hmrPlugin } from './scripts/hmr-plugin';
const require = createRequire(import.meta.url);
const enableIstanbul = !!process.env.COVERAGE;
const chunkSizeReport = !!process.env.CHUNK_SIZE_REPORT;
const cache = new Map();
export function sourcemapExclude(): Plugin {
return {
name: 'sourcemap-exclude',
transform(code: string, id: string) {
if (id.includes('node_modules') && !id.includes('@blocksuite')) {
return {
code,
// https://github.com/rollup/rollup/blob/master/docs/plugin-development/index.md#source-code-transformations
map: { mappings: '' },
};
}
return undefined;
},
};
}
type GetModuleInfo = Parameters<GetManualChunk>[1]['getModuleInfo'];
function isDepInclude(
id: string,
depPaths: string[],
importChain: string[],
getModuleInfo: GetModuleInfo
): boolean | undefined {
const key = `${id}-${depPaths.join('|')}`;
if (importChain.includes(id)) {
cache.set(key, false);
return false;
}
if (cache.has(key)) {
return cache.get(key);
}
for (const depPath of depPaths) {
if (id.includes(depPath)) {
importChain.forEach(item =>
cache.set(`${item}-${depPaths.join('|')}`, true)
);
return true;
}
}
const moduleInfo = getModuleInfo(id);
if (!moduleInfo || !moduleInfo.importers) {
cache.set(key, false);
return false;
}
const isInclude = moduleInfo.importers.some(importer =>
isDepInclude(importer, depPaths, importChain.concat(id), getModuleInfo)
);
cache.set(key, isInclude);
return isInclude;
}
const chunkGroups = {
framework: [
require.resolve('@blocksuite/block-std'),
require.resolve('@blocksuite/block-std/gfx'),
require.resolve('@blocksuite/global'),
require.resolve('@blocksuite/global/utils'),
require.resolve('@blocksuite/global/env'),
require.resolve('@blocksuite/global/exceptions'),
require.resolve('@blocksuite/global/di'),
require.resolve('@blocksuite/inline'),
require.resolve('@blocksuite/store'),
require.resolve('@blocksuite/sync'),
],
components: [
require.resolve('@blocksuite/affine-components/icons'),
require.resolve('@blocksuite/affine-components/peek'),
require.resolve('@blocksuite/affine-components/portal'),
require.resolve('@blocksuite/affine-components/hover'),
require.resolve('@blocksuite/affine-components/toolbar'),
require.resolve('@blocksuite/affine-components/toast'),
require.resolve('@blocksuite/affine-components/rich-text'),
require.resolve('@blocksuite/affine-components/caption'),
require.resolve('@blocksuite/affine-components/context-menu'),
require.resolve('@blocksuite/affine-components/date-picker'),
require.resolve('@blocksuite/affine-components/drag-indicator'),
],
affine: [
require.resolve('@blocksuite/affine-shared'),
require.resolve('@blocksuite/affine-model'),
require.resolve('@blocksuite/affine-block-list'),
require.resolve('@blocksuite/affine-block-paragraph'),
require.resolve('@blocksuite/affine-block-surface'),
require.resolve('@blocksuite/data-view'),
],
datefns: [path.dirname(require.resolve('date-fns'))],
dompurify: [path.dirname(require.resolve('dompurify'))],
shiki: [path.dirname(require.resolve('@shikijs/core'))],
dotLottie: [path.dirname(require.resolve('@lottiefiles/dotlottie-wc'))],
unified: [
path.dirname(require.resolve('unified')),
path.dirname(require.resolve('rehype-parse')),
path.dirname(require.resolve('rehype-stringify')),
path.dirname(require.resolve('remark-parse')),
path.dirname(require.resolve('remark-stringify')),
path.dirname(require.resolve('mdast-util-gfm-autolink-literal')),
path.dirname(require.resolve('mdast-util-gfm-strikethrough')),
path.dirname(require.resolve('mdast-util-gfm-table')),
path.dirname(require.resolve('mdast-util-gfm-task-list-item')),
path.dirname(require.resolve('micromark-extension-gfm-autolink-literal')),
path.dirname(require.resolve('micromark-extension-gfm-strikethrough')),
path.dirname(require.resolve('micromark-extension-gfm-table')),
path.dirname(require.resolve('micromark-extension-gfm-task-list-item')),
path.dirname(require.resolve('micromark-util-combine-extensions')),
],
blocks: [
require.resolve('@blocksuite/blocks'),
require.resolve('@blocksuite/blocks/schemas'),
],
presets: [require.resolve('@blocksuite/presets')],
common: [
require.resolve('@blocksuite/icons/lit'),
require.resolve('@toeverything/theme'),
require.resolve('@toeverything/y-indexeddb'),
require.resolve('@preact/signals-core'),
require.resolve('@lit/context'),
require.resolve('lit'),
require.resolve('zod'),
require.resolve('minimatch'),
require.resolve('nanoid'),
require.resolve('yjs'),
],
};
const clearSiteDataPlugin = () =>
({
name: 'clear-site-data',
configureServer(server) {
server.middlewares.use((req, res, next) => {
if (req.url === '/Clear-Site-Data') {
res.statusCode = 200;
res.setHeader('Clear-Site-Data', '"*"');
}
next();
});
},
}) as Plugin;
// https://vitejs.dev/config/
export default defineConfig(({ mode }) => {
process.env = { ...process.env, ...loadEnv(mode, __dirname, '') };
return {
envDir: __dirname,
define: {
'import.meta.env.PLAYGROUND_SERVER': JSON.stringify(
process.env.PLAYGROUND_SERVER ?? 'http://localhost:8787'
),
'import.meta.env.PLAYGROUND_WS': JSON.stringify(
process.env.PLAYGROUND_WS ?? 'ws://localhost:8787'
),
},
plugins: [
hmrPlugin,
sourcemapExclude(),
enableIstanbul &&
istanbul({
cwd: fileURLToPath(new URL('../..', import.meta.url)),
include: ['packages/**/src/*'],
exclude: [
'node_modules',
'tests',
fileURLToPath(new URL('.', import.meta.url)),
],
forceBuildInstrument: true,
}),
wasm(),
clearSiteDataPlugin(),
],
esbuild: {
target: 'es2018',
},
resolve: {
extensions: ['.ts', '.js'],
},
build: {
target: 'es2022',
sourcemap: true,
rollupOptions: {
cache: false,
maxParallelFileOps: Math.max(1, cpus().length - 1),
onwarn(warning, defaultHandler) {
if (
warning.code &&
['EVAL', 'SOURCEMAP_ERROR'].includes(warning.code)
) {
return;
}
defaultHandler(warning);
},
input: {
main: resolve(__dirname, 'index.html'),
'starter/': resolve(__dirname, 'starter/index.html'),
'examples/basic/page': resolve(
__dirname,
'examples/basic/page/index.html'
),
'examples/basic/edgeless': resolve(
__dirname,
'examples/basic/edgeless/index.html'
),
'examples/multiple-editors/page-page': resolve(
__dirname,
'examples/multiple-editors/page-page/index.html'
),
'examples/multiple-editors/page-edgeless': resolve(
__dirname,
'examples/multiple-editors/page-edgeless/index.html'
),
'examples/multiple-editors/edgeless-edgeless': resolve(
__dirname,
'examples/multiple-editors/edgeless-edgeless/index.html'
),
'examples/inline': resolve(__dirname, 'examples/inline/index.html'),
},
treeshake: true,
output: {
sourcemapIgnoreList: relativeSourcePath => {
const normalizedPath = path.normalize(relativeSourcePath);
return normalizedPath.includes('node_modules');
},
manualChunks(id, { getModuleInfo }) {
for (const group of Object.keys(chunkGroups)) {
const deps = chunkGroups[group];
if (isDepInclude(id, deps, [], getModuleInfo)) {
if (chunkSizeReport && id.includes('node_modules')) {
console.log(group + ':', id);
console.log(
group + ':',
fs.statSync(id.replace('\x00', '').replace(/\?.*/, ''))
.size / 1024,
'KB'
);
}
return group;
}
return undefined;
}
},
},
},
},
};
});