ES 模块导入——总能做到吗?尝试导入 socket.io-client 的失败示例

ES module imports - can it always be done? A failed example trying to import socket.io-client

我正在尝试使用“无构建”过程,所以我在 html 文件中使用普通模块 script(遵循 Preact 文档):

<script type="module">
  import {
    html,
    render,
  } from 'https://unpkg.com/htm/preact/index.mjs?module';
 
  function App(props) {
    return html`<h1>Hello ${props.name}!</h1>`;
  }

  render(html`<${App} name="world" />`, document.getElementById('root'));
</script>

如果我绕过模块系统并依赖 window 全局,我可以让客户端 socket.io 工作(注意:我正在为 html来自已传递到 socket.io 的服务器并自动安装了 /socket.io/socket.io.js 的 http 服务器的文件):

<script src="/socket.io/socket.io.js"></script>

<!-- in previous module script: -->
  const socket = window.io();

  socket.on('connect', () => {
    console.log('socket id>>', socket.id);
  });

我想从 ES 模块导入 socket.io 客户端。我知道我可以将 window 的使用封装在我自己的 JS 文件中,然后将其导入到我的 html 的模块脚本中,但我正在尝试这样做,但它不起作用:

  import io from '/socket.io.js'; // after copying socket.io.js to my public dir
  import { io } from 'https://cdnjs.cloudflare.com/ajax/libs/engine.io-client/3.5.0/engine.io.js'; // I have tried several variations of urls and what is imported

判断依据:

Uncaught SyntaxError: The requested module '/socket.io.js' does not provide an export named 'default'

并且通过“polyfill”编辑(如果这是正确的术语)commonjs 全局变量,例如 probably-webpack 包中的 module,即 socket.io.js - 很可能只是没有支持对于这个库的 ES 模块。

我可能会一遍又一遍地面对这个问题,所以我决定返回构建步骤。

我的问题是 - 有没有办法解决这个“不支持开箱即用的 ES 模块导入的第 3 方库”?也许通过我的一些工作,我可以解决这个问题并尝试完成一个小项目,而无需开发中的构建步骤。

Is there a way around this "3rd party libraries not supporting ES module imports out of the box"?

不幸的是没有,至少不总是。浏览器不可能原生 import 不是 ES 模块的东西。但是,如果您可以访问原始源代码,并且源代码本身是作为 ES 模块编写的(然后 transpiled/bundled),您有时可以自己构建 ES 模块。

在 socket.io 的情况下,their repo 在 TypeScript 中托管源代码,它使用 import/export。不幸的是,他们的代码还使用了 require() 和其他 npm 包,这最终意味着它不能简单地转换为 ES 模块。