@@ -957,3 +957,101 @@ class FakeWindow extends Realm {
957
957
958
958
上面代码中,` FakeWindow` 模拟了一个假的顶层对象` window ` 。
959
959
960
+ ## ` #! ` 命令
961
+
962
+ Unix 的命令行脚本都支持` #! ` 命令,又称为 Shebang 或 Hashbang。这个命令放在脚本的第一行,用来指定脚本的执行器。
963
+
964
+ 比如 Bash 脚本的第一行。
965
+
966
+ ` ` ` bash
967
+ #! / bin/ s h
968
+ ` ` `
969
+
970
+ Python 脚本的第一行。
971
+
972
+ ` ` ` python
973
+ #! / usr/ bin/ env python
974
+ ` ` `
975
+
976
+ 现在有一个[提案](https://github.com/tc39/proposal-hashbang),为 JavaScript 脚本引入了` #! ` 命令,写在脚本文件或者模块文件的第一行。
977
+
978
+ ` ` ` javascript
979
+ // 写在脚本文件第一行
980
+ #! / usr/ bin/ env node
981
+ ' use strict' ;
982
+ console .log (1 );
983
+
984
+ // 写在模块文件第一行
985
+ #! / usr/ bin/ env node
986
+ export {};
987
+ console .log (1 );
988
+ ` ` `
989
+
990
+ 有了这一行以后,Unix 命令行就可以直接执行脚本。
991
+
992
+ ` ` ` bash
993
+ # 以前执行脚本的方式
994
+ $ node hello .js
995
+
996
+ # hashbang 的方式
997
+ $ hello .js
998
+ ` ` `
999
+
1000
+ 对于 JavaScript 引擎来说,会把` #! ` 理解成注释,忽略掉这一行。
1001
+
1002
+ ## import.meta
1003
+
1004
+ 加载 JavaScript 脚本的时候,有时候需要知道脚本的元信息。Node.js 提供了两个特殊变量` __filename ` 和` __dirname ` ,用来获取脚本的文件名和所在路径。
1005
+
1006
+ ` ` ` javascript
1007
+ const fs = require (' fs' );
1008
+ const path = require (' path' );
1009
+ const bytes = fs .readFileSync (path .resolve (__dirname , ' data.bin' ));
1010
+ ` ` `
1011
+
1012
+ 上面代码中,` __dirname ` 用于加载与脚本同一个目录的数据文件` data .bin ` 。
1013
+
1014
+ 但是,浏览器没有这两个特殊变量。如果需要知道脚本的元信息,就只有手动提供。
1015
+
1016
+ ` ` ` html
1017
+ < script data- option= " value" src= " library.js" >< / script>
1018
+ ` ` `
1019
+
1020
+ 上面这一行 HTML 代码加载 JavaScript 脚本,使用` data- ` 属性放入元信息。如果脚本内部要获知元信息,可以像下面这样写。
1021
+
1022
+ ` ` ` javascript
1023
+ const theOption = document .currentScript .dataset .option ;
1024
+ ` ` `
1025
+
1026
+ 上面代码中,` document .currentScript ` 属性可以拿到当前脚本的 DOM 节点。
1027
+
1028
+ 由于 Node.js 和浏览器做法的不统一,现在有一个[提案](https://github.com/tc39/proposal-import-meta),提出统一使用` import .meta` 属性在脚本内部获取元信息。这个属性返回一个对象,该对象的各种属性就是当前运行的脚本的元信息。具体包含哪些属性,标准没有规定,由各个运行环境自行决定。
1029
+
1030
+ 一般来说,浏览器的` import.meta` 至少会有两个属性。
1031
+
1032
+ - ` import.meta.url` :脚本的 URL。
1033
+ - ` import.meta.scriptElement` :加载脚本的那个` <script>` 的 DOM 节点,用来替代` document.currentScript` 。
1034
+
1035
+ ` ` ` html
1036
+ < script type= " module" src= " path/to/hamster-displayer.js" data- size= " 500" >< / script>
1037
+ ` ` `
1038
+
1039
+ 上面这行代码加载的脚本内部,就可以使用` import .meta` 获取元信息。
1040
+
1041
+ ` ` ` javascript
1042
+ (async () => {
1043
+ const response = await fetch (new URL (" ../hamsters.jpg" , import .meta.url));
1044
+ const blob = await response .blob ();
1045
+
1046
+ const size = import .meta.scriptElement.dataset.size || 300;
1047
+
1048
+ const image = new Image ();
1049
+ image .src = URL .createObjectURL (blob);
1050
+ image .width = image .height = size;
1051
+
1052
+ document .body .appendChild (image);
1053
+ })();
1054
+ ` ` `
1055
+
1056
+ 上面代码中,` import .meta` 用来获取所加载的图片的尺寸。
1057
+
0 commit comments