0

我有一个简单的 javascript 模块,其中包含我的浏览器端 javascript 和节点服务器 ES6 模块通用的类。代码都是同源的,所以没有加载错误,但是从 ES6 模块导出的实体在浏览器脚本中都不可用。忽略重用并仅考虑浏览器端,这是可行的:
latlong.js非模块

function LatLon(lat,lon) {
      this.lat = lat;
      this.lon = lon;
  }

测试.html

<body>
  <script  src="latlong.js"></script>
  <script>
    let test = new LatLon(1,2)
  </script>
</body>

但这不使用模块,因此不能与节点服务器代码共享,所以我希望以下工作但它失败

了 latlong.js模块,该模块可以在服务器端节点 js 代码中正常导入并且可以工作

export class LatLon {
    constructor(lat, lon) {
      this.lat = lat;
      this.lon = lon;
    }
  }

带有模块导入的test.html

<body>
  <script type="module" src="latlong.js"></script>
  <script>
    let test = new LatLon(1,2)  <=Uncaught ReferenceError: LatLon is not defined
  </script>
</body>

关于如何从模块导出类/原型或声明原型类还有许多其他变体,但对我来说都导致相同的错误。

这是在本地网络服务器中运行的,我已经验证了在两种情况下返回的用于加载 latlong.js 的标头具有内容类型application/javascript。由于这是一个 ampps Web 服务器,我可以将 js 和 mjs 请求的 mime 类型更改为 text/javascript 以更符合要求,但这对报告的错误没有影响。

在 HTML 文档中包含模块很常见,那么我做错了什么?

4

2 回答 2

0

import如果您不在想要使用它们的地方使用它们,模块将无法工作。您还必须将导入声明scriptmodule一个。

这将起作用:

<script type="module">
  import {LatLon} from 'latlong.js';
  let test = new LatLon(1,2)
</script>
于 2021-06-13T17:17:43.803 回答
0

我成功地将导入行添加到需要内容的每个块中,但我不喜欢它。也许一些专家可以解释为什么这“更好”?

<script type="module">
  import {LatLon} from 'latlong.js'; //import where first used (not in <HEAD>)
  let test = new LatLon(1,2)
</script>

...稍后在页面上...

<script type="module">
  import {LatLon} from 'latlong.js';  //required to import module again
  let test2 = new LatLon(1,2)
</script>

这意味着您在整个 html 页面中导入/包含相同的模块,而不是像通常的惯例那样在文件顶部一次。我不确定是否期望文件顶部的所有包含都是最佳实践,但我已经习惯了这种模式,并且从不期望通过代码查找新的依赖项。我的目标是获得良好的编码实践,并在客户端和服务器之间共享一些全局结构和枚举。尽管共享是与消除代码中重复定义的好处一起实现的,但重新导入的这种需要似乎是一种权衡。
我知道有些人会说“只需将所有脚本放在一个块中”,对我来说,我发现大多数时候都是这种情况。但是该标准出于某种原因允许多个块,并且当您需要它时它就在那里。

于 2021-06-28T19:41:18.697 回答