我有一个超过800行的单一JS文件使用OpenLayers创建web地图。这绝对是太多了!该文件是用普通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和https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export:
后,每个函数一个。Filefunction1.js
:
const function1 = (featurePassedFromFlask) {
do stuff
return someVectorLayers;
}
export { function1 };
Filefunction2.js
:
const function2 = (otherFeaturePassedFromFlask) {
do stuff
return aPoint;
}
export { function2 };
和文件map.js
,剩下的代码加上顶部的这两行:
import { function1 } from './function1.js';
import { function2 } from './function2.js';
"problem"在我的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"one_answers";function2.js"不再意识到对象的存在,它们必须将其作为其中定义的函数的参数来考虑。那么我怎样才能再次打开那个链接,就像所有的东西都被封装在一个文件中一样?
ps:很抱歉,我的措辞可能很糟糕,我不是JS专家(这也可能是为什么我没有成功地找到一些有用的材料)。
我终于想通了。
有两种可能
1。type=application/javascript"HTML
内的导入就像@Kajbo在上面的评论中建议的那样,删除所有的导出/导入语法,并在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>
但是没有
如果它们被加载为"module">这样做的主要缺点是,如果你最终有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();
我有很多其他类似的错误,所以我用适当的声明来清理我的代码,就是这样!它现在与导出/导入ES6逻辑一起工作,因此你可以通过只导入主JS文件来保持HTML的整洁(所有JS逻辑都留在JS文件中;这样干净多了)!