簡體   English   中英

如何在 Javascript 中檢查腳本是否作為 ES6 模塊運行(以便它可以“導出”)?

[英]How do I check if a script is running as a ES6 module (so that it can `export`), in Javascript?

我想制作一個 Javascript 文件

  • export s 它的內容(例如一個類),如果它可以export (例如它已經加載了<script type="module">
  • 否則,將其內容分配給全局變量,例如windowglobal

例如,讓我們假設這樣一個文件print.js

案例A

可以像這樣使用它:

<script type="module">
    import print_things from "./print.js";
    print_things("Javascript innovation");
</script>

案例B

或者,

<script src="./print.js"></script>
<script>
    print_things("Hmmmmmmm.");
</script>

目前,使用export會使腳本在案例 B中拋出錯誤: Uncaught SyntaxError: Unexpected token export 因此,它必須知道export在其運行的環境中是否可用,以支持這兩種用例。 我該怎么做呢?

查看UMD (通用模塊定義)。 這個例子

(function (root, factory) {
    if (typeof define === 'function' && define.amd) {
        // AMD. Register as an anonymous module.
        define(['exports', 'b'], function (exports, b) {
            factory((root.commonJsStrictGlobal = exports), b);
        });
    } else if (typeof exports === 'object' && typeof exports.nodeName !== 'string') {
        // CommonJS
        factory(exports, require('b'));
    } else {
        // Browser globals
        factory((root.commonJsStrictGlobal = {}), root.b);
    }
}(typeof self !== 'undefined' ? self : this, function (exports, b) {
    // Use b in some fashion.

    // attach properties to the exports object to define
    // the exported module properties.
    exports.action = function () {};
}));

理解type=module的瀏覽器應該忽略帶有nomodule屬性的腳本。 這意味着您可以為支持模塊的瀏覽器提供模塊樹,同時為其他瀏覽器提供回退。

<script type="module" src="module.js"></script>
<script nomodule src="fallback.js"></script>

注意:你可能不應該在現實世界中使用它,但它完全有效的,並且完全符合你的要求。)
這是您的print.js的實現:

function print_things(msg) {
   console.log(msg)
}
if(0)typeof await/2//2; export default print_things

 <script type=module> // (renamed to avoid name collision) import print_things2 from "https://12Me21.github.io/external/print.js" print_things2("Javascript innovation") </script> <script src="https://12Me21.github.io/external/print.js"></script> <script> print_things("Hmmmmmmm.") </script>
此語法將從非模塊腳本中“隱藏”導出語句,因為await/2//2; ... await/2//2; ...根據上下文進行不同的解析:

  • 模塊異步函數中:
    await (運算符) /2/ (正則表達式) / (除) 2 (數字)
  • 在普通腳本中:
    await (variable) / (divide) 2 (number) //2 ... ( comment )

當它被解析為注釋時,該行的其余部分將被忽略。 因此, export語句僅對模塊腳本可見。

這是規范的相關部分: 15.8 Async Function Definitions > Syntax > AwaitExpression > Note 1

兼容性

作為一個非模塊腳本,它應該可以在任何瀏覽器中運行(甚至是 Internet Explorer 的舊版本等),並且在啟用"use strict"的情況下仍然有效

但是,將其作為模塊加載需要支持“頂級等待”,這是在模塊本身之后幾年添加的(~2021 vs~2018),所以請記住這一點。
(它也適用於 nodejs,在任何一種模式下)

我在自己編寫的庫中使用了這個技巧,幾個月來它在多個環境中都運行良好。 但是,它導致了一些外部工具(框架、編譯器、壓縮器等)的問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM