JSON export/import
편집기 문서는 저장되고 다시 열려야 합니다. 가장 단순한 시작점은 JSON export/import입니다.
중요한 것은 무엇을 저장하고 무엇을 저장하지 않을지 정하는 것입니다.
저장할 것은 문서 의미다
JSON에는 scene graph, node properties, styles, assets reference, page metadata 같은 값이 들어갑니다.
{
"version": 1,
"rootIds": ["frame-1"],
"nodes": {
"frame-1": { "type": "frame", "children": ["rect-1"] },
"rect-1": { "type": "rect", "size": [200, 120] }
}
}
GPU buffer나 WebGL texture는 저장하지 않습니다. 다시 열 때 renderer가 새로 만들 수 있어야 합니다.
function exportDocument(document) {
return JSON.stringify({
version: document.version,
rootIds: document.rootIds,
nodes: Object.fromEntries(document.nodesById)
});
}
function importDocument(json) {
const raw = JSON.parse(json);
validateDocumentShape(raw);
return {
version: raw.version,
rootIds: raw.rootIds,
nodesById: new Map(Object.entries(raw.nodes).map(([id, node]) => {
return [id, normalizeNode({ id, ...node })];
}))
};
}
version이 필요하다
문서 포맷은 바뀝니다. 처음부터 version을 넣어두면 migration을 만들 수 있습니다.
version 1 -> version 2
강의 초반에는 migration을 깊게 다루지 않더라도 version field는 습관으로 넣어둡니다.
import는 validate를 해야 한다
외부 JSON은 믿으면 안 됩니다. node id가 중복되거나 parent가 없거나 type이 이상할 수 있습니다.
parse
validate shape
normalize defaults
load into editor state
이 과정이 있어야 저장 파일이 깨졌을 때도 에디터가 조용히 망가지지 않습니다.
function normalizeNode(node) {
return {
visible: true,
locked: false,
children: [],
localMatrix: identity3(),
...node
};
}
오늘의 핵심
JSON export/import는 scene model의 경계를 확인하는 테스트입니다.
저장 가능한 것 = 문서 상태
다시 만들 수 있는 것 = renderer cache
이 기준이 명확하면 renderer와 editor core의 분리가 더 단단해집니다.