Closed
1 of 2 issues completed
Description
Describe the bug
BlockNote with Shiki is causing a significant bundle size issue. Unnecessary language files (like emacs-lisp.mjs) are being included in the client bundle, increasing the bundle size by approximately 788KB (192KB gzipped).
This is occurring in a Turborepo monorepo environment with pnpm as the package manager, where our web workspace uses Next.js 14.
To Reproduce
- Create a Next.js 14 project (in our case, within a Turborepo monorepo)
- Install BlockNote:
npm install @blocknote/core @blocknote/react @blocknote/mantine
- Create a basic BlockNote editor with code block support
- Run
next build
and analyze the bundle - Notice large chunks containing Shiki language files that aren't being used
BlockNote version:
"@blocknote/core": "^0.23.6",
"@blocknote/mantine": "^0.23.6",
"@blocknote/react": "^0.23.6",
Code setup:
// BlockNote.tsx
import { BlockNoteSchema, customizeCodeBlock, defaultBlockSpecs } from '@blocknote/core';
import { BlockNoteView, useCreateBlockNote } from '@blocknote/react';
const customCodeBlock = customizeCodeBlock({
defaultLanguage: 'typescript',
supportedLanguages: [
{ id: 'javascript', match: ['javascript', 'js'], name: 'JavaScript' },
{ id: 'typescript', match: ['typescript', 'ts'], name: 'TypeScript' },
{ id: 'html', match: ['html'], name: 'HTML' },
{ id: 'css', match: ['css'], name: 'CSS' },
{ id: 'json', match: ['json'], name: 'JSON' },
{ id: 'markdown', match: ['markdown', 'md'], name: 'Markdown' },
],
});
const schema = BlockNoteSchema.create({
blockSpecs: {
...defaultBlockSpecs,
codeBlock: customCodeBlock,
},
});
export const BlockNote = ({ initialContent }) => {
const editor = useCreateBlockNote({
initialContent,
schema,
});
return (
<BlockNoteView
editor={editor}
editable={false}
formattingToolbar={false}
/>
);
};
I've tried using webpack externals to exclude unnecessary language files:
// next.config.js
config.externals = [
...(config.externals || []),
function(context, request, callback) {
if (/node_modules[\/\\]@shikijs[\/\\]langs[\/\\]dist[\/\\](?!javascript|typescript|html|css|json|markdown).+\.mjs$/.test(request)) {
console.log('Excluded Shiki language file:', request);
return callback(null, 'commonjs {}');
}
callback();
}
];
But the bundle still includes all Shiki language files:
parsed: static/chunks/b9c69e33.fdaaa1746205dfd1.js (785.91 KB)
gziped: static/chunks/b9c69e33.fdaaa1746205dfd1.js (192.3 KB)
Misc
- Node version: 22.11
- Package manager: pnpm
- Browser: Chrome
- Environment: Turborepo monorepo with Next.js 14 in web workspace
- I'm a sponsor and would appreciate if you could look into this sooner than later 💖
Questions
- Is there a way to completely remove or replace Shiki in BlockNote's codeBlock?
- Is it possible to isolate just the code block rendering to a server component? This would keep Shiki on the server side and prevent it from being included in the client bundle.