CDN으로 Web SDK 가져오기

먼저 전체 예제를 실행한 뒤 자신의 페이지에 복사하세요. 편집 가능한 시트와 수식 계산에 필요한 의존성, 스타일, 언어 팩, Facade 등록이 포함되어 있습니다.

편집 가능한 시트 체험

  1. 예제 열기 또는 아래 HTML을 내려받아 index.html로 저장하세요.
  2. 인터넷에 연결된 최신 브라우저에서 여세요. 빌드 도구나 서버가 필요하지 않습니다. 예제 UI와 표의 내용은 한국어입니다.
  3. 노트 합계는 36입니다. 수량을 3에서 4로 바꾸면 48이 됩니다. 셀 편집과 실행 취소도 체험할 수 있습니다.
HTML 다운로드

전체 HTML 예제

이 예제는 React 18.3.1 UMD를 사용합니다. 전역 React 객체에는 Univer UMD 번들이 요구하는 jsx와 jsxs가 없으므로 아래 두 줄에서 공개 React.createElement API로 연결합니다. 패키지 관리자로 통합하면 빌드 도구가 react/jsx-runtime을 해석하므로 이 UMD 브리지를 복사할 필요가 없습니다.

리소스를 의존성 순서에 따라 jsDelivr에서 로드합니다. 요청이 실패하면 unpkg에서 같은 버전을 다시 시도한 뒤 계속 진행합니다. 두 공급자 모두 실패하면 시작을 중단하고 로드하지 못한 리소스를 페이지에 표시합니다.

HTML
<!doctype html><html lang="ko-KR">  <head>    <meta charset="UTF-8" />    <meta name="viewport" content="width=device-width, initial-scale=1.0" />    <title>Univer Sheets CDN 예제</title>    <style>      html,      body,      #root,      #app {        padding: 0;        margin: 0;        height: 100%;      }    </style>  </head>  <body>    <div id="app"><p role="status" style="padding: 24px; font-family: system-ui">Univer 로딩 중…</p></div>    <script>      const cdnBases = ['https://cdn.jsdelivr.net/npm/', 'https://unpkg.com/']      const app = document.getElementById('app')      async function loadResource(path, tag = 'script') {        for (const base of cdnBases) {          const element = document.createElement(tag)          const url = base + path          element.crossOrigin = 'anonymous'          if (tag === 'link') {            element.rel = 'stylesheet'            element.href = url          } else {            element.src = url          }          try {            await new Promise((resolve, reject) => {              element.onload = () => resolve()              element.onerror = () => reject(new Error(url))              document.head.appendChild(element)            })            return          } catch {            element.remove()          }        }        throw new Error(`Could not load ${path} from ${cdnBases.join(' or ')}`)      }      const styles = [        '@univerjs/design@1.3.0/lib/index.css',        '@univerjs/ui@1.3.0/lib/index.css',        '@univerjs/docs-ui@1.3.0/lib/index.css',        '@univerjs/sheets-ui@1.3.0/lib/index.css',        '@univerjs/sheets-formula-ui@1.3.0/lib/index.css',        '@univerjs/sheets-numfmt-ui@1.3.0/lib/index.css',      ]      const reactScripts = [        'react@18.3.1/umd/react.production.min.js',        'react-dom@18.3.1/umd/react-dom.production.min.js',      ]      const sdkScripts = [        'rxjs@7.8.2/dist/bundles/rxjs.umd.min.js',        '@wendellhu/redi@1.1.3/dist/umd/index.js',        '@wendellhu/redi@1.1.3/dist/umd/react-bindings/index.js',        '@univerjs/themes@1.3.0/lib/umd/index.js',        '@univerjs/protocol@1.3.0/lib/umd/index.js',        '@univerjs/core@1.3.0/lib/umd/index.js',        '@univerjs/network@1.3.0/lib/umd/index.js',        '@univerjs/rpc@1.3.0/lib/umd/index.js',        '@univerjs/design@1.3.0/lib/umd/index.js',        '@univerjs/engine-render@1.3.0/lib/umd/index.js',        '@univerjs/engine-formula@1.3.0/lib/umd/index.js',        '@univerjs/drawing@1.3.0/lib/umd/index.js',        '@univerjs/telemetry@1.3.0/lib/umd/index.js',        '@univerjs/ui@1.3.0/lib/umd/index.js',        '@univerjs/docs@1.3.0/lib/umd/index.js',        '@univerjs/docs-ui@1.3.0/lib/umd/index.js',        '@univerjs/sheets@1.3.0/lib/umd/index.js',        '@univerjs/sheets-ui@1.3.0/lib/umd/index.js',        '@univerjs/sheets-formula@1.3.0/lib/umd/index.js',        '@univerjs/sheets-formula-ui@1.3.0/lib/umd/index.js',        '@univerjs/sheets-numfmt@1.3.0/lib/umd/index.js',        '@univerjs/sheets-numfmt-ui@1.3.0/lib/umd/index.js',        '@univerjs/core@1.3.0/lib/umd/facade.js',        '@univerjs/engine-formula@1.3.0/lib/umd/facade.js',        '@univerjs/ui@1.3.0/lib/umd/facade.js',        '@univerjs/docs@1.3.0/lib/umd/facade.js',        '@univerjs/docs-ui@1.3.0/lib/umd/facade.js',        '@univerjs/sheets@1.3.0/lib/umd/facade.js',        '@univerjs/sheets-ui@1.3.0/lib/umd/facade.js',        '@univerjs/sheets-formula@1.3.0/lib/umd/facade.js',        '@univerjs/sheets-numfmt@1.3.0/lib/umd/facade.js',        '@univerjs/design@1.3.0/lib/umd/locale/ko-KR.js',        '@univerjs/ui@1.3.0/lib/umd/locale/ko-KR.js',        '@univerjs/sheets@1.3.0/lib/umd/locale/ko-KR.js',        '@univerjs/sheets-ui@1.3.0/lib/umd/locale/ko-KR.js',        '@univerjs/docs-ui@1.3.0/lib/umd/locale/ko-KR.js',        '@univerjs/sheets-formula-ui@1.3.0/lib/umd/locale/ko-KR.js',        '@univerjs/sheets-numfmt-ui@1.3.0/lib/umd/locale/ko-KR.js',      ]      // Fetch ahead in parallel; main() still executes scripts in dependency order.      for (const [as, paths] of [        ['style', styles],        ['script', [...reactScripts, ...sdkScripts]],      ]) {        for (const path of paths) {          const preload = document.createElement('link')          preload.rel = 'preload'          preload.as = as          preload.crossOrigin = 'anonymous'          preload.href = cdnBases[0] + path          preload.onerror = () => {            preload.onerror = null            preload.href = cdnBases[1] + path          }          document.head.appendChild(preload)        }      }      async function main() {        for (const path of styles) await loadResource(path, 'link')        for (const path of reactScripts) await loadResource(path)        // Bridge the React 18 UMD global to the JSX runtime expected by Univer UMD bundles.        React.jsx = (type, props, key) => React.createElement(type, key === undefined ? props : { ...props, key })        React.jsxs = React.jsx        for (const path of sdkScripts) await loadResource(path)        app.textContent = ''        const { Univer, LocaleType, mergeLocales, UniverInstanceType } = UniverCore        const { FUniver } = UniverCoreFacade        const { UniverRenderEnginePlugin } = UniverEngineRender        const { UniverFormulaEnginePlugin } = UniverEngineFormula        const { UniverUIPlugin } = UniverUi        const { UniverSheetsPlugin } = UniverSheets        const { UniverSheetsUIPlugin } = UniverSheetsUi        const { UniverDocsPlugin } = UniverDocs        const { UniverDocsUIPlugin } = UniverDocsUi        const { UniverSheetsFormulaPlugin } = UniverSheetsFormula        const { UniverSheetsFormulaUIPlugin } = UniverSheetsFormulaUi        const { UniverSheetsNumfmtPlugin } = UniverSheetsNumfmt        const { UniverSheetsNumfmtUIPlugin } = UniverSheetsNumfmtUi        const univer = new Univer({          locale: LocaleType.KO_KR,          locales: {            [LocaleType.KO_KR]: mergeLocales(              UniverDesignKoKR,              UniverUiKoKR,              UniverSheetsKoKR,              UniverSheetsUiKoKR,              UniverDocsUiKoKR,              UniverSheetsFormulaUiKoKR,              UniverSheetsNumfmtUiKoKR,            ),          },        })        univer.registerPlugin(UniverRenderEnginePlugin)        univer.registerPlugin(UniverFormulaEnginePlugin)        univer.registerPlugin(UniverUIPlugin, {          container: 'app',        })        univer.registerPlugin(UniverDocsPlugin)        univer.registerPlugin(UniverDocsUIPlugin)        univer.registerPlugin(UniverSheetsPlugin)        univer.registerPlugin(UniverSheetsUIPlugin)        univer.registerPlugin(UniverSheetsFormulaPlugin)        univer.registerPlugin(UniverSheetsFormulaUIPlugin)        univer.registerPlugin(UniverSheetsNumfmtPlugin)        univer.registerPlugin(UniverSheetsNumfmtUIPlugin)        univer.createUnit(UniverInstanceType.UNIVER_SHEET, {})        const univerAPI = FUniver.newAPI(univer)        window.univerAPI = univerAPI        univerAPI          .getActiveWorkbook()          .getActiveSheet()          .getRange('A1:D3')          .setValues([            ['품목', '수량', '단가', '합계'],            ['노트', 3, 12, '=B2*C2'],            ['펜', 5, 2, '=B3*C3'],          ])      }      main().catch((error) => {        console.error(error)        app.setAttribute('role', 'alert')        app.style.cssText =          'padding: 24px; box-sizing: border-box; white-space: pre-wrap; overflow-wrap: anywhere; font: 14px/1.5 system-ui'        app.textContent =          '예제 로딩에 실패했습니다. 네트워크를 확인한 뒤 페이지를 새로 고치세요.' + '\n' + error.message      })    </script>  </body></html>

네임스페이스 규칙

UMD 스크립트는 모듈 내보내기를 전역 객체로 제공합니다. 초기화 코드에서 다음 이름으로 플러그인과 Facade API에 접근하세요.

패키지 또는 진입점전역 이름
@univerjs/coreUniverCore
@univerjs/docs-uiUniverDocsUi
@univerjs/core/facadeUniverCoreFacade
@univerjs/docs-ui/locale/ko-KRUniverDocsUiKoKR

버전 일치

예제는 Univer 1.3.0, React와 ReactDOM 18.3.1, RxJS 7.8.2로 고정되어 있습니다. 업그레이드할 때 Facade, CSS, 언어 파일을 포함한 모든 Univer URL을 함께 바꾸세요. 기존 앱 번들에 포함된 라이브러리를 중복으로 로드하지 마세요.

문제 해결

증상확인할 사항
ITelemetryService@univerjs/telemetry에 의존하는 @univerjs/sheets-ui보다 먼저 로드하고 전체 의존성 목록을 유지하세요.
FDocument@univerjs/docs-ui/facade보다 먼저 @univerjs/docs/facade를 로드하세요. Sheets도 Docs 텍스트 엔진을 사용합니다.
[redi], t is not a function전체 예제로 시작하고 각 의존성을 동일한 버전으로 한 번만 로드하세요. 브라우저 Network에서 실패한 요청을 확인하세요.
빈 에디터컨테이너 높이를 지정하세요. 네트워크나 CSP가 CDN을 차단하면 직접 호스팅한 의존성이나 패키지 관리자를 사용하세요.

기존 React 또는 Vue 앱에는 의존성을 관리하는 패키지 관리자 통합을 권장합니다. 긴 스크립트 목록을 직접 관리할 필요가 없습니다.

이 가이드는 어떠셨나요?

© 2026 DreamNum Co., Ltd.