简短回答:
你可以通过创建以下文件并在manifest.json
中尽早列出它来模仿一些import
/export
的功能和获得一些好处,这适用于浏览器扩展:
let exportVars, importVarsFrom;
{
const modules = {};
exportVars = varsObj => ({
from(nameSpace) {
modules[nameSpace] || (modules[nameSpace] = {});
for (let [k,v] of Object.entries(varsObj)) {
modules[nameSpace][k] = v;
}
}
});
importVarsFrom = nameSpace => modules[nameSpace];
}
然后,像这样从一个文件/模块导出:
exportVars({ var1, var2, var3 }).from('my-utility');
像这样导入到另一个文件/模块中:
const { var1, var3: newNameForVar3 } = importVarsFrom('my-utility');
讨论:
此策略:
- 允许在浏览器扩展中使用模块化代码,使您可以将代码拆分为多个文件,但不会因不同文件之间共享的全局范围而出现变量冲突。
- 仍然允许您导出和导入变量到不同的JavaScript文件/模块中。
- 只引入了两个全局变量,即导出函数和导入函数。
- 在每个文件中保持完整的浏览器扩展功能(例如
chrome.runtime
等),这些功能被另一个答案中的方法(目前是接受的答案)使用模块脚本标签嵌入所消除。
- 使用类似于JavaScript中真正的
import
和export
函数的简洁语法。
- 允许命名空间,可以是导出模块的文件名,类似于JavaScript中真正的
import
和export
命令的工作方式,但不一定是(即名称空间名称可以是任何您想要的名称),并且
- 允许类似于
import { fn as myFn }...
的导入时进行变量重命名。
为了实现这一点,您的
manifest.json
需要按照以下方式加载JavaScript:
- 首先是建立导出/导入函数的文件(在下面的示例中命名为
modules-start.js
),
- 其次是导出文件,
- 最后是导入文件。
当然,您可能有一个既导入又导出的文件。在这种情况下,只需确保它在从中导入的文件之后但在导出到的文件之前列出即可。
下面的代码演示了这种策略。
需要注意的是,每个模块/文件中的所有代码都包含在花括号中。唯一的例外是
modules-start.js
中的第一行,它将导出和导入函数作为全局变量进行了定义。
下面的代码片段中的代码必须被放置在单个“位置”中。但是,在实际项目中,代码可以分成单独的文件。请注意,即使在这里的人工上下文中(即在下面的单个代码片段中),这种策略也允许其包含的不同代码部分是模块化的,但仍然相互连接。
let exportVars, importVarsFrom;
{
const modules = {};
exportVars = varsObj => ({
from(nameSpace) {
modules[nameSpace] || (modules[nameSpace] = {});
for (let [k,v] of Object.entries(varsObj)) {
modules[nameSpace][k] = v;
}
}
});
importVarsFrom = nameSpace => modules[nameSpace];
}
{
const wontPolluteTheGlobalScope = 'f';
const myString = wontPolluteTheGlobalScope + 'oo';
const myFunction = (a, b) => a + b;
exportVars({ myString, myFunction }).from('my-general-utilities');
}
{
const { myString, myFunction: sum } = importVarsFrom('my-general-utilities');
console.log(`The imported string is "${myString}".`);
console.log(`The renamed imported function shows that 2 + 3 = ${sum(2,3)}.`);
}
使用此示例,您的
manifest.json
应按以下顺序列出文件:
{ ...
"content_scripts": [
{
"js": [
"modules-start.js",
"my-general-utilities.js",
"content.js"
]
}
], ...
}
import
语句是同步的,这与普通JavaScript不兼容。 - Derek 朕會功夫my-script.js
的路径添加到manifest.json
中的列表中,它将按照您指定的顺序加载。 - Derek 朕會功夫