简体   繁体   English

浏览器将如何处理 ES6 导入/导出语法

[英]How will browsers handle ES6 import/export syntax

I've been thinking around this question lot of days and i have decided to ask the experts.我一直在思考这个问题很多天,我决定问问专家。

How browsers will handle the new import/export syntax ?浏览器将如何处理新的导入/导出语法? I mean: will the modules be loaded asynchronously ?我的意思是:模块会被异步加载吗? Referencing only my main or entry file and browsers will lazy load the requiere modules.仅引用我的主文件或入口文件和浏览器将延迟加载所需模块。

Maybe am i missing or misunderstanding something about this new architecture ?也许我错过或误解了这个新架构?

Thank you very much!非常感谢!

Regards.问候。

This is standardized now and supported by all major modern browsers.这是现在标准化的,并且被所有主要的现代浏览器支持。

will the modules be loaded asynchronously?模块会被异步加载吗?

Yes, with two options available;是的,有两种选择; details below.详情如下。

Referencing only my main or entry file and browsers will lazy load the requiere modules.仅引用我的主文件或入口文件和浏览器将延迟加载所需模块。

Not so much "lazy," but yes.没有那么多“懒惰”,但是是的。

Enabling it启用它

Details in the spec here and here (and possibly elsewhere).此处此处(可能还有其他地方)的规范中的详细信息。

To get this behavior, you specify that your script is a module by using type="module" :要获得这种行为,可以指定自己的脚本是通过使用模块type="module"

<script src="main.js" type="module"></script>

or for inline scripts或内联脚本

<script type="module">
// ...module code here
</script>

That means that the script is parsed and handled per the Module definition in the JavaScript specification instead of per the Script definition, which means it can have imports (and exports).这意味着脚本是根据 JavaScript 规范中的模块定义而不是脚本定义来解析和处理的,这意味着它可以具有导入(和导出)。

Imports are resolved relative to the script 's URL (for modules loaded via a separate resource such as the main.js above, just like CSS) or relative to the document (for inline modules like the one above).导入是相对于脚本的 URL 解析的(对于通过单独的资源加载的模块,例如上面的main.js ,就像 CSS)或相对于文档(对于像上面那样的内联模块)。

So for instance, if I have this in my document at http://example.com/index.html :例如,如果我在http://example.com/index.html文档中有这个:

<script src="./handy/stuff/nifty.js" type="module"></script>

...and nifty.js contains ...和nifty.js包含

import Thingy from "./thingy.js";

...then the browser looks for http://example.com/handy/stuff/thingy.js , not http://example.com/thingy.js . ...然后浏览器会查找http://example.com/handy/stuff/thingy.js ,而不是http://example.com/thingy.js Again, just like CSS imports.同样,就像 CSS 导入一样。

Note that the ./ on that module specifier is required, just from "thingy.js" won't work.请注意,该模块说明符上的./是必需的,仅from "thingy.js"将不起作用。 That's because bare specifiers are disallowed because they'll probably end up having a special meaning.那是因为不允许使用裸说明符,因为它们可能最终具有特殊含义。 (For instance, in Node.js, that's how you specify built-in modules, and modules installed in node_modules .) A module specifier must be a full URL, or a relative URL starting with / , ./ , or ../ . (例如,在 Node.js 中,这就是您指定内置模块和安装在node_modules模块的node_modules 。)模块说明符必须是完整的 URL,或以/./../开头的相对 URL。

Async异步

I said above that modules are loaded asynchronously, and there are two options available.我上面说过模块是异步加载的,有两个选项可用。 This graphic from the spec says it best (see the spec for the latest copy of it):规范中的这张图说得最好(请参阅规范以获取其最新副本):

在此处输入图片说明

As you can see, for type="module" scripts, if you don't put any special flag attributes on the script tag, all of the module's dependencies will be resolved and then the script will be run once parsing of the HTML is complete.如您所见,对于type="module"脚本,如果您没有在script标签上放置任何特殊的标志属性,则会解析模块的所有依赖项,然后在 HTML 解析完成后运行脚本. If you include the async attribute, it may run sooner, before the HTML parsing is complete (for instance, if all the scripts are in cache).如果包含async属性,它可能会在 HTML 解析完成之前运行得更快(例如,如果所有脚本都在缓存中)。 ( defer is not valid for modules.) defer对模块无效。)

According to this post in Mozilla's website, it's up to the implementation:根据 Mozilla 网站上的这篇文章,这取决于实施:

Because the system doesn't specify how loading works, and because you can figure out all the dependencies ahead of time by looking at the import declarations in the source code, an implementation of ES6 is free to do all the work at compile time and bundle all your modules into a single file to ship them over the network!因为系统没有指定加载是如何工作的,而且因为你可以通过查看源代码中的导入声明提前找出所有的依赖关系,所以 ES6 的实现可以在编译时和捆绑包中自由地完成所有工作您的所有模块都集成到一个文件中,以便通过网络发送它们!

This may change in the future, as it is still not fully standardized, but you can be sure that you will not need to add a script tag for every module.这在未来可能会改变,因为它仍然没有完全标准化,但您可以确定不需要为每个模块添加脚本标记。 Some module loaders today bundle all the files for you, but that's may not be the case when the future will be live, as it will not have an advantage in performance in HTTP2.今天的一些模块加载器为您打包了所有文件,但未来可能不会出现这种情况,因为它在 HTTP2 中不会有性能优势。

You can read the ES6 specification of import here .你可以在这里阅读 ES6 的import规范。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM