WASM Office 라이브러리 — 빠른 시작
office-oxide-wasm 패키지는 office_oxide를 WebAssembly로 컴파일한 것입니다. 네이티브 의존성 없음, 단일 Rust 코어 바이너리, 세 가지 서브패스 진입점으로 JavaScript가 도는 어디서나 동작합니다 — 브라우저, Node.js, 그리고 Vite·Webpack·Rollup 같은 번들러.
Node.js에서 WASM 오버헤드 없이 쓰고 싶다면 네이티브
office-oxide패키지를 사용하세요.
설치
npm install office-oxide-wasm
postinstall 단계 없음. Node 18+, WebAssembly를 지원하는 모던 브라우저, ES 모듈 / CommonJS 로더가 있는 모든 환경에서 동작합니다.
서브패스 익스포트
| 임포트 경로 | 대상 | 형식 |
|---|---|---|
office-oxide-wasm (기본) |
번들러 친화적 ESM (Vite, Webpack, Rollup) | ESM |
office-oxide-wasm/node |
Node.js | CommonJS |
office-oxide-wasm/web |
<script type="module"> 또는 import을 사용하는 브라우저 |
ESM, init() 필요 |
런타임에 맞는 변형을 고르세요.
문서 읽기
번들러 (ESM)
import { WasmDocument } from 'office-oxide-wasm';
const res = await fetch('/report.docx');
const data = new Uint8Array(await res.arrayBuffer());
const doc = new WasmDocument(data, 'docx');
try {
console.log(doc.plainText());
} finally {
doc.free();
}
Node.js (CJS)
const { readFileSync } = require('node:fs');
const { WasmDocument } = require('office-oxide-wasm/node');
const data = readFileSync('report.docx');
const doc = new WasmDocument(data, 'docx');
try {
console.log(doc.plainText());
} finally {
doc.free();
}
브라우저 (번들러 없이)
<script type="module">
import init, { WasmDocument } from 'https://cdn.jsdelivr.net/npm/office-oxide-wasm/web/office_oxide.js';
await init();
const res = await fetch('/report.docx');
const data = new Uint8Array(await res.arrayBuffer());
const doc = new WasmDocument(data, 'docx');
try {
document.body.textContent = doc.plainText();
} finally {
doc.free();
}
</script>
브라우저 한정:
WasmDocument를 생성하기 전에 반드시await init()해야 합니다. Node와 번들러 진입점은 초기화를 내부에서 처리합니다.
핵심 API
WasmDocument가 유일한 핸들입니다 — WASM 빌드에는 Document / EditableDocument 분리가 없습니다(편집 기능은 네이티브 바인딩에 있음).
import { WasmDocument } from 'office-oxide-wasm';
const doc = new WasmDocument(bytes, 'xlsx');
try {
console.log(doc.formatName()); // "xlsx"
console.log(doc.plainText());
console.log(doc.toMarkdown());
console.log(doc.toHtml());
const ir = doc.toIr(); // 파싱된 객체
} finally {
doc.free(); // 필수 — WASM 메모리는 GC가 관리하지 않음
}
모든 메서드는 camelCase: plainText, toMarkdown, toHtml, toIr, formatName. bytes는 Uint8Array여야 합니다. format은 'docx' | 'xlsx' | 'pptx' | 'doc' | 'xls' | 'ppt' 중 하나.
레거시 바이너리 형식(doc, xls, ppt)도 WASM에서 파싱됩니다.
편집 (WASM에서는 미지원)
EditableDocument — 텍스트 치환과 셀 쓰기 — 는 WASM 빌드에서 노출되지 않습니다. 편집이 필요하면:
- 네이티브 Node 바인딩 (
office-oxide) - Python 바인딩
- .NET 바인딩
- Rust 크레이트
읽기 전용 텍스트 / Markdown / HTML / IR 워크플로에서는 WASM이 완전한 기능을 제공합니다.
형식 무관 IR
const doc = new WasmDocument(bytes, 'docx');
const ir = doc.toIr();
doc.free();
for (const section of ir.sections) {
console.log(section.title);
for (const el of section.elements) {
// el.kind: "Heading" | "Paragraph" | "Table" | "List" | "Image" | ...
}
}
IR 스키마는 Rust의 DocumentIR과 정확히 일치하므로, 서버 측과 클라이언트 측 파이프라인이 동일한 프로세서를 공유할 수 있습니다.
바이트 입력, 바이트 출력
WASM 빌드는 바이트 입력 전용 — 파일 I/O 표면은 없습니다.
// <input type="file">에서
const file = inputEl.files[0];
const data = new Uint8Array(await file.arrayBuffer());
const doc = new WasmDocument(data, file.name.split('.').pop().toLowerCase());
// fetch에서
const res = await fetch(url);
const data = new Uint8Array(await res.arrayBuffer());
// Node에서
const data = new Uint8Array(require('node:fs').readFileSync('file.docx'));
번들러
// Vite — 보통 설정 없음
import { WasmDocument } from 'office-oxide-wasm';
// Webpack 5 — module.rules에 추가:
// { test: /\.wasm$/, type: 'asset/resource' }
TypeScript
타입 정의(office_oxide.d.ts)는 각 서브패스 익스포트의 JS glue와 함께 배포됩니다. 루트에서 임포트하면 번들러 타입이 자동으로 적용됩니다. import type { WasmDocument } from 'office-oxide-wasm/node'도 동작합니다.
메모리 관리
const doc = new WasmDocument(bytes, 'docx');
try {
// ... 작업
} finally {
doc.free();
}
free()를 잊으면 인스턴스가 파괴될 때까지 WASM 메모리가 계속 누수됩니다.
오류
실패는 설명적인 메시지가 붙은 일반 Error 인스턴스로 발생합니다. WASM 빌드는 JsValue::from_str을 사용하므로 오류 코드는 숫자로 노출되지 않습니다 — 메시지 문자열을 확인하세요.
문제 해결
| 증상 | 해결 |
|---|---|
ReferenceError: WebAssembly is not defined |
대상 환경이 WASM을 지원하지 않습니다. 네이티브 office-oxide를 사용하세요. |
브라우저: TypeError: ... before init() |
office-oxide-wasm/web 사용 시 await init()을 잊었습니다. |
번들러가 .wasm에 불평 |
WASM 자산 규칙을 추가하거나 번들러 타깃을 esnext로 바꾸세요. |
unsupported format: pdf |
6가지 형식만 받습니다: docx, xlsx, pptx, doc, xls, ppt. |
| 핫 루프에서 메모리가 무한 증가 | 반복 사이에 doc.free()를 호출하지 않았습니다. |
더 보기
- 네이티브 Node 바인딩 — 더 빠르고, 편집 지원
- 성능 벤치마크
- npm 패키지