Zoo*_*Way 12 javascript ecmascript-6 systemjs es6-module-loader
我有一个使用SystemJS的SPA(在Aurelia/TypeScript中,但这无关紧要).让我们说它运行于http://spa:5000/app.
它有时会像waterservice/external.js外部URL一样按需加载JavaScript模块http://otherhost:5002/fetchmodule?moduleId=waterservice.external.js.我用SystemJS.import(url)它做这个,它工作正常.
但是当这个外部模块想要导入另一个模块时,import { OtherClass } from './other-class';这个(可理解的)不起作用.当它被SPA加载时,它会看到http://spa:5000/app/other-class.js.在这种情况下,我必须拦截路径/位置以将其重定向到http://otherhost:5002/fetchmodule?moduleId=other-class.js.
注意:waterservice/external.ts作品查找的Typescript编译因为typescript编译器可以./other-class.ts轻松找到.显然我不能使用绝对URL进行导入.
如何拦截我使用SystemJS导入的模块内的模块加载?
我已经测试过的一种方法是在SystemJS配置中添加映射.如果我像它一样导入它import { OtherClass } from 'other-class';并添加一个像"other-class": "http://otherhost:5002/fetchmodule?moduleId=other-class"它一样的映射.但是如果这种方法很好,我怎样才能在运行时动态添加映射?
其他方法,如通用加载URL拦截也是受欢迎的.
更新
我尝试拦截SystemJS,就像这样的artem
var systemLoader = SystemJS;
var defaultNormalize = systemLoader.normalize;
systemLoader.normalize = function(name, parentName) {
console.error("Intercepting", name, parentName);
return defaultNormalize(name, parentName);
}
Run Code Online (Sandbox Code Playgroud)
这通常不会改变任何东西,只会产生一些控制台输出以查看正在发生的事情.不幸的是,这似乎改变了一些东西,因为我得到一个错误未捕获(在承诺中)TypeError:this.has不是一个函数内部system.js.
然后我尝试添加映射SystemJS.config({map: ...});.令人惊讶的是,这个函数是增量的,所以当我调用它时,它不会松开已经提供的映射.所以我可以这样做:
System.config({map: {
"other-class": `http://otherhost:5002/fetchModule?moduleId=other-class.js`
}});
Run Code Online (Sandbox Code Playgroud)
这不适用于相对路径(以.或开头的那些路径..),但如果我将共享路径放在根目录中,则可以解决这个问题.
我仍然希望拦截加载以便能够处理更多场景,但目前我不知道has上述方法中缺少哪个功能.
如何在运行时动态添加映射?
AFAIK SystemJS 可以随时通过调用进行配置
SystemJS.config({ map: { additional-mappings-here ... }});
Run Code Online (Sandbox Code Playgroud)
如果它不适合您,您可以覆盖 loader.normalize 并添加您自己的从模块 id 到 URL 的映射。沿着这些思路:
// assuming you have one global SystemJS instance
var loader = SystemJS;
var defaultNormalize = loader.normalize;
loader.normalize = function(name, parentName) {
if (parentName == 'your-external-module' && name == 'your-external-submodule') {
return Promise.resolve('your-submodule-url');
} else {
return defaultNormalize.call(loader, name, parentName);
}
}
Run Code Online (Sandbox Code Playgroud)
我不知道这是否适用于打字稿。另外,您还必须弄清楚在您的情况下到底传递给 loader.normalize 的名称是什么。
另外,如果您使用 systemjs 构建器来捆绑代码,则需要将该重写添加到构建器使用的加载器中(这完全是另一个故事)。
| 归档时间: |
|
| 查看次数: |
400 次 |
| 最近记录: |