# 通过 CDN 使用 Web SDK

- Human documentation: [https://docs.univer.ai/zh-CN/guides/docs/getting-started/installation/cdn](https://docs.univer.ai/zh-CN/guides/docs/getting-started/installation/cdn)

- Agent Markdown: [https://docs.univer.ai/zh-CN/guides/docs/getting-started/installation/cdn.md](https://docs.univer.ai/zh-CN/guides/docs/getting-started/installation/cdn.md)

- Requested language: `zh-CN`

- Content language: `zh-CN`

- Documentation version: `1.0.0-rc.0`

- Source: [docs/getting-started/installation/cdn.zh-CN.mdx](https://github.com/dream-num/documentation/blob/dev/content/guides/docs/getting-started/installation/cdn.zh-CN.mdx)

---

如果你不使用包管理工具，也可以通过 `<script>` 标签引入 Univer。

## 命名空间规范

Univer 的全局构建（UMD）会在全局对象上暴露一个命名空间，它们的命名规范如下：

```plain
@univerjs/core -> UniverCore
@univerjs/docs-ui -> UniverDocsUi
@univerjs-pro/docs-print -> UniverProDocsPrint
@univerjs/docs-ui/locale/zh-CN -> UniverDocsUiZhCN
@univerjs/core/facade -> UniverCoreFacade
```

## 插件模式

### 使用全局构建版本

Univer 为插件提供 UMD 包。通过 CDN `<script>` 标签使用时，你需要手动引入每个插件的 UMD 包以及它们的前置依赖包。这个过程比较繁琐，建议仅在完全理解插件机制（如插件之间的依赖关系，以及插件样式文件的引入顺序）之后再使用。

#### 示例

```html
<head>
  <script src="https://unpkg.com/react@18.3.1/umd/react.production.min.js"></script>
  <script src="https://unpkg.com/react-dom@18.3.1/umd/react-dom.production.min.js"></script>
  <script>
    /**
     * Starting from Univer 0.6.0, with the support for React 19[^1], UMD users may need additional adaptation.
     * It is recommended to migrate to module script[^2] and a more modern build system.
     *
     * [^1]: [support for React 19] https://github.com/dream-num/univer/pull/4247
     * [^2]: [Module Script] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules#applying_the_module_to_your_html
     */

    /**
     * Fix `Uncaught TypeError: client.createRoot is not a function`
     * If using UMD React < 18, you might need the following code.
     */
    ;(function (global) {
      'use strict'
      if (!global.ReactDOM) {
        throw new Error('ReactDOM must be loaded before ReactCreateRoot.')
      }
      const ReactDOM = global.ReactDOM
      if (!ReactDOM.createRoot) {
        ReactDOM.createRoot = function (container) {
          return {
            render: (element) => {
              ReactDOM.render(element, container)
            },
          }
        }
      }
    })(this)

    /**
     * Fix `Uncaught TypeError: jsxRuntime.jsx is not a function`
     * If using UMD React, you might need the following code.
     * Reference: https://unpkg.com/react@18.3.1/cjs/react-jsx-runtime.production.min.js
     */
    ;(function (global) {
      'use strict'
      if (!global.React) {
        throw new Error('React must be loaded before ReactJSXRuntime.')
      }
      const React = global.React
      if (!React.jsx || !React.jsxs) {
        const REACT_ELEMENT_TYPE = Symbol.for('react.element')
        const hasOwnProperty = Object.prototype.hasOwnProperty
        const RESERVED_PROPS = {
          key: true,
          ref: true,
          __self: true,
          __source: true,
        }
        const ReactCurrentOwner = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner
        function createReactElement(type, config, maybeKey) {
          const props = {}
          let key = null
          let ref = null
          if (maybeKey !== undefined) {
            key = `${maybeKey}`
          }
          if (config.key !== undefined) {
            key = `${config.key}`
          }
          if (config.ref !== undefined) {
            ref = config.ref
          }
          for (var propName in config) {
            if (hasOwnProperty.call(config, propName) && !RESERVED_PROPS.hasOwnProperty(propName)) {
              props[propName] = config[propName]
            }
          }
          if (type && type.defaultProps) {
            const defaultProps = type.defaultProps
            for (var propName in defaultProps) {
              if (props[propName] === undefined) {
                props[propName] = defaultProps[propName]
              }
            }
          }
          return {
            $$typeof: REACT_ELEMENT_TYPE,
            type,
            key,
            ref,
            props,
            _owner: ReactCurrentOwner.current,
          }
        }
        React.jsx = createReactElement
        React.jsxs = createReactElement
      }
    })(this)
  </script>
  <script src="https://unpkg.com/rxjs@7.8.1/dist/bundles/rxjs.umd.min.js"></script>
  <script src="https://unpkg.com/echarts@5.6.0/dist/echarts.min.js"></script>
  <script src="https://unpkg.com/@wendellhu/redi@1.1.2/dist/umd/index.js"></script>
  <script src="https://unpkg.com/@wendellhu/redi@1.1.2/dist/umd/react-bindings/index.js"></script>

  <script src="https://unpkg.com/@univerjs/themes/lib/umd/index.js"></script>
  <script src="https://unpkg.com/@univerjs/protocol/lib/umd/index.js"></script>
  <script src="https://unpkg.com/@univerjs/core/lib/umd/index.js"></script>
  <script src="https://unpkg.com/@univerjs/rpc/lib/umd/index.js"></script>
  <script src="https://unpkg.com/@univerjs/design/lib/umd/index.js"></script>
  <script src="https://unpkg.com/@univerjs/engine-render/lib/umd/index.js"></script>
  <script src="https://unpkg.com/@univerjs/engine-formula/lib/umd/index.js"></script>
  <script src="https://unpkg.com/@univerjs/drawing/lib/umd/index.js"></script>

  <script src="https://unpkg.com/@univerjs/ui/lib/umd/index.js"></script>
  <script src="https://unpkg.com/@univerjs/docs/lib/umd/index.js"></script>
  <script src="https://unpkg.com/@univerjs/docs-ui/lib/umd/index.js"></script>

  <script src="https://unpkg.com/@univerjs/core/lib/umd/facade.js"></script>
  <script src="https://unpkg.com/@univerjs/engine-formula/lib/umd/facade.js"></script>
  <script src="https://unpkg.com/@univerjs/ui/lib/umd/facade.js"></script>
  <script src="https://unpkg.com/@univerjs/docs-ui/lib/umd/facade.js"></script>

  <script src="https://unpkg.com/@univerjs/design/lib/umd/locale/zh-CN.js"></script>
  <script src="https://unpkg.com/@univerjs/ui/lib/umd/locale/zh-CN.js"></script>
  <script src="https://unpkg.com/@univerjs/docs-ui/lib/umd/locale/zh-CN.js"></script>

  <link rel="stylesheet" href="https://unpkg.com/@univerjs/design/lib/index.css" />
  <link rel="stylesheet" href="https://unpkg.com/@univerjs/ui/lib/index.css" />
  <link rel="stylesheet" href="https://unpkg.com/@univerjs/docs-ui/lib/index.css" />

  <style>
    html,
    body,
    #root,
    #app {
      padding: 0;
      margin: 0;
      height: 100%;
    }
  </style>
</head>
<body>
  <div id="app"></div>

  <script>
    const { Univer, LocaleType, mergeLocales } = UniverCore
    const { FUniver } = UniverCoreFacade
    const { UniverRenderEnginePlugin } = UniverEngineRender
    const { UniverFormulaEnginePlugin } = UniverEngineFormula
    const { UniverUIPlugin } = UniverUi
    const { UniverDocsPlugin } = UniverDocs
    const { UniverDocsUIPlugin } = UniverDocsUi

    const univer = new Univer({
      locale: LocaleType.ZH_CN,
      locales: {
        [LocaleType.ZH_CN]: mergeLocales(UniverDesignZhCN, UniverUiZhCN, UniverDocsUiZhCN),
      },
    })

    univer.registerPlugin(UniverRenderEnginePlugin)
    univer.registerPlugin(UniverFormulaEnginePlugin)

    univer.registerPlugin(UniverUIPlugin, {
      container: 'app',
    })

    univer.registerPlugin(UniverDocsPlugin)
    univer.registerPlugin(UniverDocsUIPlugin)

    const univerAPI = FUniver.newAPI(univer)

    univerAPI.createDocument({})
  </script>
</body>
```

## 指定版本

unpkg 和 jsDeliver 都支持指定特定版本的资源。以 unpkg 为例，如果你想使用 `x.y.z` 版本的 Univer，仅需在 URL 中加上 `@<version>` 来指定版本即可：

```diff
- https://unpkg.com/@univerjs/core/lib/umd/index.js
+ https://unpkg.com/@univerjs/core@x.y.z/lib/umd/index.js
```
