You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

小型JavaScript项目导入RxJS遇TypeError错误求助

问题

尝试在小型JavaScript项目的脚本文件中使用import导入RxJS,持续出现以下错误:

Subscriber.js:10 Uncaught (in promise) TypeError: Cannot set properties of undefined (setting 'rxjs')

HTML文件内容:

<!DOCTYPE html>
<html lang="en-US">

  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="./styles/style.css">
    <title>Load RxJs using import</title>
  </head>

  <body>
    <h1>Importing RxJs Lib</h1>
    <div>
      <h1 id="info">'loading ...'</h1>
    </div>
    
    <!-- <script src="https://unpkg.com/rxjs@7.5.7/dist/bundles/rxjs.umd.js"></script> -->
    <script src="./js/script.js"></script>
  </body>
</html>

脚本文件内容:

// const updateUI = text => document.querySelectorAll('#info')[0].innerText = "finished";

const loadRxJsLib = async () => {
  await import('https://unpkg.com/rxjs@7.5.7/dist/bundles/rxjs.umd.js');
}

document.addEventListener('DOMContentLoaded', (event) => {
  loadRxJsLib();
});

document.addEventListener('readystatechange', (event) => {
  if (document.readyState === 'complete') {
    const { range } = rxjs;
    const { filter, map } = rxjs.operators;

    range(1, 200)
      .pipe(
        filter((x) => x % 2 === 1),
        map((x) => x + x)
      )
      .subscribe((x) => console.log(x))
  }
});

原因分析

  • UMD包动态加载特性限制:你选用的是RxJS的UMD格式包,这类包通过script标签引入时会自动挂载到全局window对象,但使用动态import()加载时,不会自动将rxjs暴露到全局作用域,导致后续代码访问rxjs变量时找不到目标。
  • 执行时机不匹配:readystatechange触发complete状态时,loadRxJsLib的异步加载操作大概率还未完成,此时rxjs变量尚未定义,直接访问必然报错。

解决方案

方案一:改用ES模块格式加载(推荐)

RxJS提供了ES模块版本,直接通过动态import导入所需内容,同时需要将脚本标记为模块类型:

  1. 修改HTML中的script标签,添加type="module":
<script type="module" src="./js/script.js"></script>
  1. 更新脚本文件,导入ES模块版本的RxJS并执行逻辑:
const loadRxJsLib = async () => {
  // 导入RxJS核心模块和操作符
  const { range } = await import('https://unpkg.com/rxjs@7.5.7/dist/esm/rxjs.min.js');
  const { filter, map } = await import('https://unpkg.com/rxjs@7.5.7/dist/esm/operators.min.js');

  range(1, 200)
    .pipe(
      filter(x => x % 2 === 1),
      map(x => x + x)
    )
    .subscribe(x => console.log(x));
}

document.addEventListener('DOMContentLoaded', () => loadRxJsLib());

方案二:手动挂载UMD包到全局

如果坚持使用UMD包,需要在动态加载后手动将模块内容挂载到window对象,并确保逻辑在加载完成后执行:

修改脚本文件:

const loadRxJsLib = async () => {
  const rxjsModule = await import('https://unpkg.com/rxjs@7.5.7/dist/bundles/rxjs.umd.js');
  // 将RxJS挂载到全局window对象
  window.rxjs = rxjsModule.default;

  // 加载完成后执行RxJS逻辑
  const { range } = rxjs;
  const { filter, map } = rxjs.operators;

  range(1, 200)
    .pipe(
      filter(x => x % 2 === 1),
      map(x => x + x)
    )
    .subscribe(x => console.log(x));
}

document.addEventListener('DOMContentLoaded', () => loadRxJsLib());

方案三:直接用script标签引入UMD包(最简单)

如果不需要动态加载,直接恢复HTML中的script标签引入,去掉动态import逻辑即可:

  1. 恢复HTML中的注释代码:
<script src="https://unpkg.com/rxjs@7.5.7/dist/bundles/rxjs.umd.js"></script>
<script src="./js/script.js"></script>
  1. 脚本文件简化为:
document.addEventListener('readystatechange', (event) => {
  if (document.readyState === 'complete') {
    const { range } = rxjs;
    const { filter, map } = rxjs.operators;

    range(1, 200)
      .pipe(
        filter(x => x % 2 === 1),
        map(x => x + x)
      )
      .subscribe(x => console.log(x))
  }
});

内容的提问来源于stack exchange,提问作者Alte Schule

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 09:50:24