我正在尝试构建一个支持插件的Web应用程序,环境是Angular 2(到目前为止),Typescript 2.1和Webpack 2.我有一些扩展点(插槽)插件可以在其中绘制内容:基本上我有一个组件它能够托管在运行时已知的其他一些组件(请参阅"Mastering Angular 2 Components"第10章的想法,并且SO plunker关于如何编译和"draw"在运行时的Angular组件)
这就是我想要实现的目标:
// in plugin.service.ts
loadPlugin(url)
{
return System.import('absolute OR relative ?? plugin base path' + name)
.then((pluginModule) => {
const Plugin = pluginModule.default;
// then use the plugin
});
}
...
//content of the plugin file being imported
export default class HeaderButtonsPlugin {
constructor() {}
//useful things about the plugin
}
我正在使用Webpack中的 System.import
在运行时导入模块,虽然我知道不推荐使用,但AFAIK是使用typescript动态导入模块的唯一方法,因为typescript本身尚不支持 import
(参考here) . (有没有其他方法可以实现这一目标?)
现在,仅仅为了测试系统,我使用下面的目录树将插件目录包含在应用程序的同一根目录(src目录)中;请注意,这会导致webpack在编译时知道插件代码的存在,并将插件和应用程序打包在同一个bundle的集合中,这是为了测试插件架构功能而进行的简化;这是文件夹树:
- src
- app
- core
- plugin.service.ts
- plugins
- pluginA
- pluginA.plugin.ts
这样,如果我用 System.import('relativePathToPluginA')
导入 pluginA.plugin.ts
,一切都按预期工作:系统能够加载和编译插件组件并使用它 .
But ,在现实世界的场景中,插件在编译时不可知,所以我使用angular-cli创建了一个新项目,并添加了pluginA目录,然后我在app.module中引用了它 . 然后我构建了项目并将js输出移动到一个文件夹中,让我们说 D:\pluginDist\
. 然后我从上面的loadPlugin方法引用了 main.bundle.js
,如下例所示(使用url = 'main.bundle.js')
loadPlugin(url)
{
return System.import('D:\\pluginDist\\' + url)
.then((pluginModule) => {
const Plugin = pluginModule.default;
// then use the plugin
});
}
我肯定不是't know if referencing the main boundle is correct (I lack some webpack'的概念,但它至少是建筑工具,所以我试一试 . 这样我有错误 Unhandled Promise rejection: Cannot find module 'D:\pluginDist\main.bundle.js'. ; Zone: angular ; Task: Promise.then ; Value:
我做的其他测试是
-
在插件项目中转换* .ts文件,完全跳过webpack,所以只需在命令行输入
tsc
,并尝试导入pluginA.plugin.ts
transpilation结果,我有与上面相同的错误 . -
将js结果(来自webpack或来自plain tsc transiplation)放在开发Web服务器实际提供文件的文件夹(.tmp)中,然后通过相对路径引用它们:这会导致webpack在编译时停止,因为,当然,它在打包时找不到项目目录树中的文件 .
现在我不知道去哪里,你有什么建议吗?
我想要实现的是使用webpack和typescript(一个js模块)动态加载,这在编译时是未知的 .
2 回答
试试https://blog.waffle.io/code-splitting-in-angular-2-with-webpack-2-ce8dd4b8b23e
这不会谈论插件的动态加载,而是谈论动态加载脚本,它可以帮助你实现你想要的 .
在 Webpack.config.js 更新下面的代码 .
resolver 用于加载相对于 src root的文件,通过解析webpack.config.js中的 app 文件夹,该文件夹中的文件可以通过绝对路径访问,如上所示 .
并在您的 system.import 中如下:其中app是您的src文件夹中的文件夹