拆分单个 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 干净; 这更干净)!
我有一个超过 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 干净; 这更干净)!