是否将功能动态导入ES5 JS文件?

时间:2018-10-29 21:42:42

标签: javascript node.js

这似乎有些令人费解,所以我事先对此表示歉意。 我试图在Node.js中为Chrome扩展程序创建构建工具,因此最终的JS文件必须符合ES5。

对于扩展程序中用于导出对象的每个设置,我都有单独的JS文件,该对象中的功能需要导入到contentScript.js文件中,并放置在其自己的设置对象中。

我整理了一个basic screenshot来说明应该如何进行,但是我不确定如何解决此问题。我考虑过在contentScript中使用某种类型的字符串插值,然后由Node替换,但这似乎是一种解决方法,而不是解决方案。

假设我们有一个名为settings的文件夹,其中有两个JavaScript文件,每个文件的名称,类型和功能都不同,它们看起来像这样。

// settingName1.js
module.exports = {
    name: 'Setting Name 1',
    type: 'switch',
    function: () => {
        console.log('Setting 1 initialized');
    }
}

例如,理想情况下,这两个文件都将各自的功能导入到contentScript中,例如在设置对象下。

// contentScript.js
    // Settings Functions Go Here
    const settings = {
        settingName1: function() {
            console.log('Setting 1 initialized')
        },
        settingName2: function() {
            console.log('Setting 2 initialized')
        }
    }
});

基本上从源设置文件本身剪切/复制功能,并将其粘贴到contentScript的设置对象中的功能下(使用文件名命名)。

1 个答案:

答案 0 :(得分:0)

这是生成文件的一个主意:

// header on the file
const capturedExports = [];

// insert this prologue before each inserted file
(function() {
// =============================
// insert settingName1.js here
module.exports = {
    name: 'Setting Name 1',
    type: 'switch',
    function: () => {
        console.log('Setting 1 initialized');
    }
}

// =============================

// insert this epilogue after each inserted file
})();
capturedExports.push(module.exports);


// insert this prologue before each inserted file
(function() {
    // =============================
// insert settingName2.js here
module.exports = {
    name: 'Setting Name 2',
    type: 'switch',
    function: () => {
        console.log('Setting 2 initialized');
    }
}
// =============================

// insert this epilogue after each inserted file
})();
capturedExports.push(module.exports);

// insert code that builds the settings object
const settings = {};
for (let exportItem of capturedExports) {
    let name = exportItem.name.replace(/\s/, "");
    name = name.slice(0, 1).toLowerCase() + name.slice(1);
    settings[name] = exportItem.function;
}

执行以下步骤以输出一个新文件,该文件是所有settingNamex.js文件的集合。

  1. 创建新文件。
  2. const capturedExports = [];行和IIFE的开头为其写一个标题。
  3. 对于每个settingNameX.js文件,将该文件写入其中。
  4. 然后在IIFE及其后的capturedExports.push(module.exports);的结尾处写上。这将获取分配给module.exports的先前代码,并将其添加到caputuredExports数组中。
  5. 为每个settingNameX.js文件重复此过程。
  6. 然后,插入从capturedExports数组构建设置对象的代码。

将每个插入的模块包含在自己的IIFE中,为其提供了自己的作用域,因此不会与其他插入的模块产生符号冲突。

这有以下假设。

  1. 它假定每个settingNameX.js文件中的代码都将适当的对象分配给module.exports,如您的示例所示。在现实世界中,您可能想添加一堆测试,以查看是否将正确的东西分配给module.exports(适当的防御性编码)。
  2. 假定插入的模块未将冲突对象分配给全局对象。
  3. 假定您自己的模块不需要module.exports,或者在插入的模块使用完模块后可以覆盖它。如果此假设不可行,则必须手动将module.exports =更改为您在主模块中定义的其他内容。