Skip to content

Commit adf8cd1

Browse files
authored
fix: upgrade @excalidraw/excalidraw 0.17.6 → 0.18.0 with compatibility fixes (#146)
- Bump @excalidraw/excalidraw to ^0.18.0 (ESM-only bundle) - Add explicit CSS import for ESM bundle (main.tsx) - Update asset copy script for new dist/prod/fonts layout - Add es2022 target for optimizeDeps esbuild - Inline @excalidraw/excalidraw in vitest to fix roughjs ESM resolution - Update .gitignore to add fonts/ directory - Replace commitToHistory with captureUpdate (NEVER/IMMEDIATELY constants) - Use local CAPTURE_UPDATE_NEVER constant in shared.ts to avoid importing full excalidraw UI bundle in jsdom test environment Change-Id: I75ccfa0544a5460ad7ab5c4d92d9a054006b7507
1 parent 4d17aab commit adf8cd1

10 files changed

Lines changed: 3875 additions & 1225 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ backend/dist/
4747
# Generated Excalidraw assets (copied from node_modules for runtime)
4848
frontend/public/excalidraw-assets/
4949
frontend/public/excalidraw-assets-dev/
50+
frontend/public/fonts/
5051

5152
# E2E Testing
5253
e2e/node_modules/

frontend/package-lock.json

Lines changed: 3834 additions & 1207 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

frontend/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
"dependencies": {
1818
"@dnd-kit/core": "^6.3.1",
1919
"@dnd-kit/utilities": "^3.2.2",
20-
"@excalidraw/excalidraw": "0.17.6",
20+
"@excalidraw/excalidraw": "^0.18.0",
2121
"@types/lodash": "^4.17.20",
2222
"axios": "^1.15.0",
2323
"clsx": "^2.1.1",

frontend/scripts/copy-excalidraw-assets.mjs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ import { fileURLToPath } from "node:url";
55
const __dirname = path.dirname(fileURLToPath(import.meta.url));
66
const frontendRoot = path.resolve(__dirname, "..");
77

8+
// In 0.18.0 the old excalidraw-assets / excalidraw-assets-dev directories were
9+
// replaced by dist/prod and dist/dev. Only the fonts sub-directory needs to be
10+
// copied to the public / dist output so that Excalidraw can load them at runtime
11+
// via window.EXCALIDRAW_ASSET_PATH (which is set to "/" in index.html).
812
const EXCALIDRAW_DIST_DIR = path.join(
913
frontendRoot,
1014
"node_modules",
@@ -13,7 +17,10 @@ const EXCALIDRAW_DIST_DIR = path.join(
1317
"dist"
1418
);
1519

16-
const assetDirs = ["excalidraw-assets", "excalidraw-assets-dev"];
20+
// src relative to EXCALIDRAW_DIST_DIR → dest name inside the target root
21+
const ASSET_COPIES = [
22+
{ src: path.join("prod", "fonts"), dest: "fonts" },
23+
];
1724

1825
const copyDir = async (src, dest) => {
1926
await fs.rm(dest, { recursive: true, force: true });
@@ -36,9 +43,9 @@ const main = async () => {
3643
const targetRoot = path.join(frontendRoot, targetName);
3744
await fs.mkdir(targetRoot, { recursive: true });
3845

39-
for (const dirName of assetDirs) {
40-
const src = path.join(EXCALIDRAW_DIST_DIR, dirName);
41-
const destRoot = path.join(targetRoot, dirName);
46+
for (const { src: srcRel, dest: destName } of ASSET_COPIES) {
47+
const src = path.join(EXCALIDRAW_DIST_DIR, srcRel);
48+
const dest = path.join(targetRoot, destName);
4249

4350
try {
4451
await fs.access(src);
@@ -47,9 +54,9 @@ const main = async () => {
4754
throw err;
4855
}
4956

50-
await copyDir(src, destRoot);
57+
await copyDir(src, dest);
5158

52-
console.log(`[copy-excalidraw-assets] Copied ${dirName} -> ${targetName}`);
59+
console.log(`[copy-excalidraw-assets] Copied ${srcRel} -> ${targetName}/${destName}`);
5360
}
5461
}
5562
};

frontend/src/main.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { StrictMode } from 'react'
22
import { createRoot } from 'react-dom/client'
3+
import '@excalidraw/excalidraw/index.css'
34
import './index.css'
45
import App from './App.tsx'
56

frontend/src/pages/Editor.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { ArrowLeft, Download, Loader2, ChevronUp, ChevronDown, Share2 } from 'lu
44
import clsx from 'clsx';
55
import {
66
Excalidraw,
7+
CaptureUpdateAction,
78
convertToExcalidrawElements,
89
exportToSvg,
910
viewportCoordsToSceneCoords,
@@ -1585,7 +1586,7 @@ export const Editor: React.FC = () => {
15851586
imageElements.map((element: any) => [element.id, true])
15861587
),
15871588
},
1588-
commitToHistory: true,
1589+
captureUpdate: CaptureUpdateAction.IMMEDIATELY,
15891590
});
15901591
} catch (err) {
15911592
console.error("[Editor] Failed to import dropped images", err);

frontend/src/pages/editor/shared.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ describe("editor/shared scene guards", () => {
7070

7171
expect(result.sceneUpdate).toEqual({
7272
collaborators,
73-
commitToHistory: false,
73+
captureUpdate: "NEVER",
7474
});
7575
expect(result.mergedElements).toBeNull();
7676
expect(result.shouldUpdateFiles).toBe(false);
@@ -96,7 +96,7 @@ describe("editor/shared scene guards", () => {
9696
localElements[0],
9797
pendingElements[0],
9898
],
99-
commitToHistory: false,
99+
captureUpdate: "NEVER",
100100
});
101101
expect(result.mergedElements).toEqual([
102102
localElements[0],
@@ -120,7 +120,7 @@ describe("editor/shared scene guards", () => {
120120

121121
expect(result.sceneUpdate).toEqual({
122122
files: incomingFiles,
123-
commitToHistory: false,
123+
captureUpdate: "NEVER",
124124
});
125125
expect(result.mergedElements).toBeNull();
126126
expect(result.nextFiles).toEqual(incomingFiles);
@@ -144,7 +144,7 @@ describe("editor/shared scene guards", () => {
144144
localElements[1],
145145
localElements[0],
146146
],
147-
commitToHistory: false,
147+
captureUpdate: "NEVER",
148148
});
149149
expect(result.mergedElements).toEqual([
150150
localElements[1],

frontend/src/pages/editor/shared.ts

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,26 @@ export interface ElementVersionInfo {
77
contentSig: string;
88
}
99

10+
/**
11+
* Matches CaptureUpdateAction.NEVER from @excalidraw/excalidraw.
12+
* Kept as a local constant so that shared.ts doesn't pull in the full
13+
* excalidraw UI bundle, which breaks jsdom-based unit tests.
14+
*/
15+
const CAPTURE_UPDATE_NEVER = "NEVER" as const;
16+
1017
type RemoteSceneUpdate =
1118
| {
1219
collaborators: Map<string, any>;
13-
commitToHistory: false;
20+
captureUpdate: typeof CAPTURE_UPDATE_NEVER;
1421
}
1522
| {
1623
elements: any[];
1724
files?: Record<string, any>;
18-
commitToHistory: false;
25+
captureUpdate: typeof CAPTURE_UPDATE_NEVER;
1926
}
2027
| {
2128
files: Record<string, any>;
22-
commitToHistory: false;
29+
captureUpdate: typeof CAPTURE_UPDATE_NEVER;
2330
};
2431

2532
type BuildRemoteSceneUpdateInput = {
@@ -53,7 +60,7 @@ export const buildRemoteSceneUpdate = ({
5360
return {
5461
sceneUpdate: {
5562
collaborators,
56-
commitToHistory: false,
63+
captureUpdate: CAPTURE_UPDATE_NEVER,
5764
},
5865
mergedElements: null,
5966
nextFiles: lastSyncedFiles,
@@ -78,7 +85,7 @@ export const buildRemoteSceneUpdate = ({
7885
sceneUpdate: {
7986
elements: mergedElements,
8087
...(shouldUpdateFiles ? { files: nextFiles } : {}),
81-
commitToHistory: false,
88+
captureUpdate: CAPTURE_UPDATE_NEVER,
8289
},
8390
mergedElements,
8491
nextFiles,
@@ -90,7 +97,7 @@ export const buildRemoteSceneUpdate = ({
9097
return {
9198
sceneUpdate: {
9299
files: nextFiles,
93-
commitToHistory: false,
100+
captureUpdate: CAPTURE_UPDATE_NEVER,
94101
},
95102
mergedElements: null,
96103
nextFiles,

frontend/vite.config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ export default defineConfig(({ command }) => {
3636
optimizeDeps: {
3737
esbuildOptions: {
3838
define: processEnvDefines,
39+
target: "es2022",
3940
},
4041
},
4142
server: {

frontend/vitest.config.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ export default defineConfig({
1111
include: ["src/**/*.test.ts", "src/**/*.test.tsx"],
1212
testTimeout: 10000,
1313
css: true,
14+
server: {
15+
deps: {
16+
inline: ["@excalidraw/excalidraw"],
17+
},
18+
},
1419
},
1520
resolve: {
1621
alias: {

0 commit comments

Comments
 (0)