拆分单个 JS 文件后导入的函数不再知道它们作为参数的对象

Functions imports after splitting a single JS file are no more aware of the object they take as parameter

我有一个超过 800 行的单个 JS 文件,使用 OpenLayers 创建网络地图。这绝对是太多了!该文件是用 vanilla JavaScript.

编写的

结构简单如下:

const function1 = (featurePassedFromFlask) {
  do stuff
  return someVectorLayers;
}

const function2 = (otherFeaturePassedFromFlask) {
  do stuff
  return aPoint;
}

const map = (vectorLayers, myPoint) => {
  do stuff to build the map, no returned value.
}

vectorLayers = function1(featurePassedFromFlask);
myPoint = function2(otherFeaturePassedFromFlask);

map(vectorLayers, myPoint);

如你所见,我里面有三个主要的功能,所以我决定把它分成三个文件,每个功能一个,阅读后 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import and https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export:

文件function1.js:

const function1 = (featurePassedFromFlask) {
  do stuff
  return someVectorLayers;
}
export { function1 };

文件function2.js:

const function2 = (otherFeaturePassedFromFlask) {
  do stuff
  return aPoint;
}
export { function2 };

和文件 map.js 以及剩余的代码 + 顶部的这两行新行:

import { function1 } from './function1.js';
import { function2 } from './function2.js';

“问题”是在我的 Flask 模板中 map.html (jinja2) 我只将 map.js 文件加载为:

<!-- Pass first result object from Python to JS here --> 
{% if resultsObjectFromRoute1 %}
  <script type="text/javascript">
    var featurePassedFromFlask = {{ resultsObjectFromRoute1|tojson }};
  </script>
{% endif %}

<!-- Pass second result object from Python to JS here --> 
{% if resultsObjectFromRoute2 %}
  <script type="text/javascript">
    var otherFeaturePassedFromFlask = {{ resultsObjectFromRoute2|tojson }};
  </script>
{% endif %}

<script src="{{ url_for('static', filename='js/ol.js') }}" type="application/javascript"></script>
<script src="{{ url_for('static', filename='js/map.js') }}" type="application/javascript"></script>

浏览器首先抱怨:Uncaught SyntaxError: import declarations may only appear at top level of a module 所以我稍微浏览了一下,发现我必须将最后一行更改为:

<script src="{{ url_for('static', filename='js/map.js') }}" type="module"></script>

它不再抱怨,但不是页面无法正常工作:

Uncaught ReferenceError: assignment to undeclared variable geom

我还尝试在 map.html 中导入我的两个函数文件,而不对之前的错误消息进行任何更改:

<script src="{{ url_for('static', filename='js/function1.js') }}" type="module"></script>
<script src="{{ url_for('static', filename='js/function2.js') }}" type="module"></script>
<script src="{{ url_for('static', filename='js/map.js') }}" type="module"></script>

如果函数 1 和 2 不必处理参数,也许它会起作用,所以我知道我破坏了与此相关的东西,因为现在那些文件“function1.js”和“function2.js" 不再 知道 对象的存在,他们必须将其作为其中定义的函数的参数考虑在内。那么我怎么才能再次提出那个 link,就像所有内容都被封装在一个文件中一样ps?

ps:对于可能糟糕到非常糟糕的措辞,我深表歉意,我不是 JS 方面的专家(这也可能是我没有成功找到一些有用的东西的原因 material ).

终于想通了

有两种可能。

1。作为经典的 "type=application/javascript" 在 HTML

中导入

就像@Kajbo 在上面的评论中建议的那样,删除所有 export/import 语法并在 HTML 中一个接一个地加载所有 JS 文件,主要的(map.js ) 在模板中最后加载确实有效:

<script src="{{ url_for('static', filename='js/function1.js') }}" type="application/javascript"></script>
<script src="{{ url_for('static', filename='js/function2.js') }}" type="application/javascript"></script>
<script src="{{ url_for('static', filename='js/map.js') }}" type="application/javascript"></script>

但是如果像我最初那样将它们作为“模块”加载,不会工作。

这种方式的主要缺点是,如果您最终拥有 180 个 JS 文件,那么在您的 HTML 中就意味着 180 个导入。我不是很热情

2。作为现代“type=module”在 HTML

中导入

事实上,我注意到我在 geom 上遇到的错误是由于我的代码中的这一行:

geom = new ol.format.GeoJSON();

如果这种声明变量的惰性方式在使用“type=application/javascript”加载 JS 文件时有效,那么当您将它们加载为“type=module”时它就不起作用了。事实上,模块似乎更棘手,你现在确实 声明你的变量:

let geom = new ol.format.GeoJSON();

我有很多其他类似的错误,所以我用正确的声明清理了我的代码,就是这样!它现在使用 export/import ES6 逻辑,因此您可以通过 导入主 JS 文件(所有 JS 逻辑都保留在 JS 文件中)来保持 HTML 干净; 这更干净)!