亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何動態引入DynamicImport

發布時間:2023-01-09 09:30:50 來源:億速云 閱讀:167 作者:iii 欄目:開發技術

本篇內容介紹了“如何動態引入DynamicImport”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

    什么是動態引入(DynamicImport)?

    本文介紹的動態引入實現方式基于 rollup 插件 @rollup/plugin-dynamic-import-vars

    通常情況下,我們都是通過確定的字面量路徑來引用文件模塊的,例如:

    import './a.js';
    require('./a.js');
    import('./a.js');

    對于確定的文件路徑來說,構建工具可以輕易的抓取文件并進行相關的轉換。

    但當import或者require的目標不是一個靜態字符串,而是一個動態表達式時,構建工具其實也不確定用戶到底引用了什么,所以通常這種情況只能依靠 JavaScript 的運行時來解析。

    若動態表達式實際代表的路徑無法被解析,則運行時會引起控制臺的錯誤。通常是因為生成的文件路徑并沒有被納入打包體系,所以找不到文件。

    下面列出了一些常見的動態引入表達式:

    // TemplateLiteral 模板字符串
    import(`./icons/arrow-${type}.svg`);
    require(`./icons/arrow-${type}.svg`);
    // BinaryExpression 二元表達式
    import('./icon/arrow-' + type + '.svg');
    // 直接引用一個變量
    import(path);
    require(path)

    但經過前人們的實踐發現,當動態表達式滿足一定的結構時,構建工具便可以通過一些特殊手段抓取并打包路徑匹配的相關文件,并自動注入一些 polyfill,從而實現動態引入(DynamicImport)的效果,也就是本文的主題。

    動態引入的實現原理

    本節內容翻譯加工自 @rollup/plugin-dynamic-import-vars README.md 部分章節

    當動態導入的路徑中包含變量時,經過 AST 分析可以生成對應的通配符。在構建的時候,這些通配符將被用于抓取匹配的文件。隨后這些文件會被添加進構建體系中,在運行時,根據導入的實際路徑返回對應的文件內容。

    下面是一些通配符的轉換示例:

    `./locales/${locale}.js` -> './locales/*.js'
    `./${folder}/${name}.js` -> './*/*.js'
    `./module-${name}.js` -> './module-*.js'
    `./modules-${name}/index.js` -> './modules-*/index.js'
    './locales/' + locale + '.js' -> './locales/*.js'
    './locales/' + locale + foo + bar '.js' -> './locales/*.js'
    './locales/' + `${locale}.js` -> './locales/*.js'
    './locales/' + `${foo + bar}.js` -> './locales/*.js'
    './locales/'.concat(locale, '.js') -> './locales/*.js'
    './'.concat(folder, '/').concat(name, '.js') -> './*/*.js'

    待轉換的代碼可能是這樣的:

    function importLocale(locale) {
      return import(`./locales/${locale}.js`);
    }

    經過轉換后它會變成下面這樣:

    function __variableDynamicImportRuntime__(path) {
      switch (path) {
        case './locales/en-GB.js':
          return import('./locales/en-GB.js');
        case './locales/en-US.js':
          return import('./locales/en-US.js');
        case './locales/nl-NL.js':
          return import('./locales/nl-NL.js');
        default:
          return new Promise(function (resolve, reject) {
            queueMicrotask(reject.bind(null, new Error('Unknown variable dynamic import: ' + path)));
          });
      }
    }
    function importLocale(locale) {
      return __variableDynamicImportRuntime__(`./locales/${locale}.js`);
    }

    可以看到,實際的 import 被替換成了注入的 __variableDynamicImportRuntime__ 函數,該函數會根據運行時拼接的具體字符串返回對應的打包文件。

    動態引入的限制

    本節內容翻譯加工自 @rollup/plugin-dynamic-import-vars README.md 部分章節

    為了知道要在代碼中注入什么,我們必須能夠對代碼進行一些靜態分析,并對可能的導入做出一些假設。例如,如果只使用一個變量,理論上可以從整個文件系統中導入任何內容。

    function importModule(path) {
      return import(path); // 這根本無法推斷引入了什么
    }

    為了能夠實現靜態分析,并避免可能出現的問題,動態引入的實現上限定了一些規則:

    Import 路徑須為相對路徑

    所有導入都必須相對于導入文件進行。導入不應該是純變量、絕對路徑或裸導入:

    // Not allowed
    import(bar); // 純變量
    import(`/foo/${bar}.js`); // 絕對路徑
    import(`${bar}.js`); // 裸導入
    import(`some-library/${bar}.js`); // 裸導入

    引用路徑需包含文件后綴

    文件夾中可能包含你不打算導入的文件。因此,我們要求導入的靜態部分以文件擴展名結束

    import(`./foo/${bar}`); // Not allowed
    import(`./foo/${bar}.js`); // Allowed

    導入當前目錄的文件需要指定具體的文件匹配格式

    如果你從當前目錄導入文件,很可能會導入一些原本不打算導入的文件,包括書寫代碼的這個文件本身。因此這種情況下需要給出一個更具體的文件名匹配格式:

    import(`./${foo}.js`); // not allowed
    import(`./module-${foo}.js`); // allowed

    通配符(Glob Pattern)僅有一層深度

    在生成通配符時,字符串中的每個變量都會被轉換為通配符中的*,每個層級的目錄最多一個星號。這避免了無意中從更多的目錄中添加文件到導入中。

    下面的例子中,最終將會生成 ./foo/*/.js 而非 ./foo/**/.js

    import(`./foo/${x}${y}/${z}.js`);

    核心流程解讀

    插件核心轉換代碼僅有 100 行,且非常易懂 —— plugins/index.js at master · rollup/plugins

    整體流程分為以下幾步:

    通過 AST 分析,拿到對應的導入路徑,也就是 import 表達式括號中的源碼部分。

    對這部分的源碼進行處理,調用 dynamicImportToGlob 函數

    執行上述限制條件的判斷,嘗試獲取一個合法的通配符。

    如果通配符不合法,將會引發錯誤,終止進程。

    執行通配符,抓取相關文件。

    替換 import 表達式,并注入 __variableDynamicImportRuntime__ 函數。

    附上插件核心轉換代碼的截圖。

    如何動態引入DynamicImport

    “如何動態引入DynamicImport”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    嘉义市| 广水市| 涿州市| 东平县| 菏泽市| 西华县| 廉江市| 新巴尔虎右旗| 长阳| 敦煌市| 宜君县| 裕民县| 崇仁县| 甘肃省| 遂昌县| 焦作市| 桂阳县| 达州市| 自治县| 乌苏市| 仁布县| 水富县| 江达县| 彭阳县| 米林县| 赤水市| 宁国市| 开原市| 油尖旺区| 永靖县| 澳门| 温宿县| 西乌珠穆沁旗| 南康市| 绥德县| 武隆县| 乳山市| 鲜城| 维西| 绥滨县| 博罗县|