Openlayers 6.2.1 浅尝心得(二)

上文 说到 Openlayers 6.2.1 开发环境的搭建,并简述了各个插件的功能。今天本文将继续记录关于 Node 环境下 OpenLayers 开发的小小心得。

问题总结

完成了 Openlayers 的环境搭建,接下来的任务就是功能开发。接下来,全文将记录博主在开发过程中所有遇到的跟 Node 相关的问题总结。

一、对关键字 import,export 的理解

importexport 作为 ES6 中新增的两个关键字,主要是用来解决作用域的问题。通常情况下 importexport 是成对使用的。即:假设我在 B.js 中定义了一个名为 str 的变量,如果想在其它 js 文件中也能使用,那么 B.js 文件中就必须使用 export 关键字将 str 导出。同时 A.js 文件也必须使用 import 关键字将 str 进行导入方可使用。

二、具体代码及相关问题

首先我们要在同一目录下创建以下三个文件:

A.js

import str from "./B";
import {bbb} from "./B";
// str = null;
document.write(str+bbb);

B.js

let str = "blablabla~";
let bbb = "NB";
export default str;
export {bbb}

index.html

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="A.js"></script>
</head>
<body>

</body>
</html>

启动项目 (这里博主用的 IDE 工具可在界面底部 Terminal 面板内直接敲命令)

npm start

项目启动后,如未修改过项目端口,则直接访问 http://localhost:1234 即可看到页面上的显示结果:

blablabla~NB

如果你已经看到了界面上显示的上述内容,说明你的项目 parcel 插件是没有问题的。
那么现在我们来分析一下代码:

1. 根据文件关系,我们先来看 B.js 文件,在这个文件中通过 let 关键字定义了变量 strbbb ,并通过 export defaultexport {} 两种方式进行了变量导出操作。这里值得注意的是,用 export default 进行变量导出时,在一个 js 文件中只能出现一次也可以不出现。而 export {} 方式的导出可以将多个要导出的变量放入大括号内,并用逗号分开即可。

2.A.js 文件中,前两行是对 B.js 中导出的变量的导入。第一行是对 export default 导出变量的导入方式,第二行是对 export {} 导出变量的导入方式,如果需要导入多个,只需在大括号内填入其他需要导入的变量名,并用逗号分开即可。这部分需要注意的是,不可将 export defaultexport {} 导出的变量合并到 import {} from 中一起导入。

3.index.html 中,我们可以看到,这里只对 A.js 进行了引用,并未对 B.js 进行引用,然而代码却运行正常。这是因为我们所搭建的项目环境能够对入口文件(index.html)与其他文件间的引用关系进行自动查找导入,不用我们进行手动的显式导入。

4. 现在我们再回过头来看 A.js 文件,第三行处有一句被我注释掉的代码。现在把它的注释去掉,让其运行。运行结果如下:

A.f5b0a0fa.js:116 Uncaught Error: "str" is read-only.
at A.js:3
at Object.parcelRequire.A.js../B (A.js:3)
at newRequire (A.f5b0a0fa.js:47)
at A.f5b0a0fa.js:81
at A.f5b0a0fa.js:120

这里可以看到由于我们在 A.js 文件中对 B.js 文件中的变量 str 进行了修改,导致了本次错误。错误原因为是:在 A.js 文件中 B.js 文件是只读的,换句话说,在 A.js 中我们是没有权限修改变量 str 所指向的内存地址的。

5. 接下来我们分别对 A.jsindex.html 文件做一下内容的调整,修改后的代码如下:

A.js:

function onLoadTest() {
    document.write("哎呦,不错呦~!");
}

index.html:

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="A.js"></script>
</head>
<body onload="onLoadTest()">

</body>
</html>

修改完代码,我们在 Terminal 面板执行一下 npm start 命令,把项目启动一下,然而结果却让人“呵呵”。我们非但没有看到页面上 哎呦,不错呦~! 的称赞,浏览器还(口吐芬芳)给报了个错。

Uncaught ReferenceError: onLoadTest is not defined
at onload ((index):8)

onLoadTest 未定义?怎么会?明明就在 A.js 文件中定义过了啊?而且 html 中还引用了函数所在的文件呢~!(有人可能会说是因为没有用 export 进行变量导出,在这里我想说,我当时也这么想过,并进行了导出操作,运行结果可想而知——依然报错)换种打开方式试试,把 index.html 文件直接拖进打开的浏览器中,你看到了什么?屏幕上赫然写着: 哎呦,不错呦~!。看到这里是不是更懵了?下面我来解释一下为什么会这样,并说一下这种问题改怎么处理。

会出现这样的问题是因为,在面向对象的模块化开发的模式下,我们在某个 js 文件中定义的函数或变量的作用域仅为当前文件,出了他们所在的文件,我们就无法直接调用了,所以就会报错。看到这里如果你又想到,那我就在 A.js 文件中把函数导出,在 index.html 中用 <script> import {XXX} from "XXX";</script> 把函数导入不就可以了吗?很开心我们再一次想到了一起,但遗憾的告诉你,这种导入方式是被浏览器禁止的,因此也行不通。那我们该怎么办?把 js 函数写到 html 里吗?如果真这么做的话,还真可以。可现实告诉我们这样的项目是不切实际的,因为一旦我们在 html 中嵌套了其他 js 文件中的函数,我们就又得导入,然后浏览器还是不允许这样的方式。死循环了~!

咋办?办法有一个,就是将动态或静态写在 html 节点中的被调用的函数设置成全局变量即可。也就是把需要被调用的函数放到全局作用域中,以使其在项目中任何一个文件中都可以被自由的调用。这里就又引出了浏览器和 Node 中的全局变量的问题。

浏览器中,最高层级的全局变量是 windows,它包含了所有定义在所有 js 文件中的变量。而在 Node 中,最高层级的全局变量是 globa,他们之间是有区别的,但这并不影响我们的使用,故而也就自然不是我们关注的重点。(别问有啥区别,问就是不会~!)既然全局变量有了,那我们要做的就是给这个变量增加一个属性的事了。修正后的代码如下:

A.js

global.onLoadTest = function () {
    document.write("哎呦,不错呦~!");
};

好了,再运行一下 npm start 试试。是不是很开心:哎呦,不错呦~!

三、总结:

Node 环境下的前端项目开发跟以往全靠在 html 文件中引入 js 文件的方式有许多不同点,这会让我们有些不习惯,但这并不重要,拥抱新技术才是我们程序猿成长、快乐的根本不是吗?

猜你喜欢

转载自blog.csdn.net/Supreme_Sir/article/details/105143329