微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用动态导入处理类似于 AMD/requirejs

如何解决使用动态导入处理类似于 AMD/requirejs

我正在拼命寻找一种将静态导入(捆绑)与动态导入(amd)相结合的方法。作为 Bundler,我目前正在将 webpack+babel-env 用于 polyfills(顺便说一句:我已经厌倦了所有的配置、所有的限制和发生的所有神奇的事情,我很乐意摆脱 webpack)。

使用 webpack 创建 AMD 模块并不令人满意,因为 requirejs 使调试变得非常复杂,而 webpack 只是不喜欢模块化构建/多入口点的想法。澄清一下:我有许多入口点将使用一些共享库。对于 webpack 来说,它始终是“一个包”的概念,它控制着一切。我阅读了有关动态导入的信息,并认为它是面向未来的方法

所以我最终有了这个想法:

const library = await import("library.js");

export default function() {
    return library.foo("bar");
}

或者对于多个依赖项

const depenencies = await Promise.all([
    import("library1.js"),import("library2.js")
]);
const library1 = dependencies[0];
const library2 = dependencies[1];

export default function() {
    return library1.foo("bar") + library2.bar("baz);
}

当然我开始实现我自己的加载器函数来使语法更好

const [library1,library2] = await load('library1.js','library2.js');

但所有这些都不起作用,因为在解析导入 Promise 之前导出已定义。所以我需要预先分析目标模块以找出依赖项并将特殊处理添加到我的加载函数中。而且我仍然会处于异步上下文中,所以它可能 - 即使那样 - 它也不会工作。

我想实现与 AMD 非常相似的东西,我可以在其中定义一个模块,该模块对另一个模块具有依赖性,应该由浏览器以异步方式加载。

我的主要目标是一种直观的编码方式,因为源代码将用于中等技能的团队。我不想为每个模块添加一个异步初始化函数,这将加载其依赖项,因为这会导致代码,这将很难理解。

想象一下,我提供了一些 preact-components(或其他),并希望在多个模块之间共享通用/通用组件。每个模块都需要导入 preact 核心,所以 - 当然 - 我想提供该 preact 核心作为一个单独的模块 (vendor/preact.js)。

但我仍然想编写类似的代码

const Preact = await import("vendor/preact");

export default class StatefulComponent extends Preact.Component {
    render() {
        return "hello world";
    }
}

使用 ES6 我需要做类似的事情:

export default async function init() {
    return new Promise(resolve => {
        const Preact = await import("vendor/preact.js");
        class StatefulComponent extends Preact.Component {
            render();
        }
        resolve(StatefulComponent);
    });
}

这只是愚蠢和丑陋...

import() api 不适合依赖管理,这是正确的吗? 我唯一的选择是 AMD/requirejs 并删除 webpack 吗?

如果解决方案超级简单而我只是愚蠢地看到它,那是因为我在最后几天用 AMD/UMD/Commonjs/ES6/andsoonandsoforth 折磨了我的大脑,并且目前我对 javascript 非常生气.

解决方法

没有必要弄得那么乱,但如果您确实有依赖于 import 的导出,那么它们将需要是 async(基于承诺)。

我会做的是这样的:

//mylibrary.js
export default (async function(){
    let dep1 = await import('1');
    let dep2 = await import('2');
    //so on and so on...

    return {
        myClassThatDependsOnDep1,myFunctionThatDependsOnDep2,}
})();

然后您可以以类似的方式使用它:

(async function(){
   let myLibrary = await import('mylibrary.js')
                   .then(m => m.default);

   //You use `myLibrary` here
   //                      v
   
})();

使用 TLA,可以在此处放弃 async IIFE。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?