我正在尝试构建支持插件的Web应用程序,环境是Angular 2(到目前为止),Typescript 2.1和Webpack 2。 我有一些扩展点(插槽)插件可以在其中绘制内容:基本上我有一个组件能够托管运行时已知的其他组件(参见"掌握Angular 2组件"第10章的想法,和SO + plunker关于如何编译和"在运行时绘制" 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动态导入模块的唯一方法,因为import
是打字稿本身尚未支持(参考here)。 (有没有其他方法可以实现这一目标?)
现在,仅仅为了测试系统,我使用下面的目录树将插件目录包含在应用程序的同一根目录(src目录)中;请注意,这会导致webpack在编译时知道插件代码的存在,并将插件和应用程序打包在同一个软件包集中,为了测试插件架构功能,它是一个简化版本。 ;这里是文件夹树:
- src
- app
- core
- plugin.service.ts
- plugins
- pluginA
- pluginA.plugin.ts
以这种方式导入pluginA.plugin.ts
System.import('relativePathToPluginA')
一切都按预期工作:系统能够加载和编译插件组件并使用它。
但是,在现实世界的场景中,插件在编译时不可知,所以我使用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
});
}
我不知道引用主要边界是否正确(我确实缺少一些webpack的概念)但它至少是构建工件,所以我试一试。
这样我就错了
Unhandled Promise rejection: Cannot find module 'D:\pluginDist\main.bundle.js'. ; Zone: angular ; Task: Promise.then ; Value:
我做过的其他测试
在插件项目中转换* .ts文件,完全跳过webpack,所以只需在命令行中键入tsc
,然后尝试导入pluginA.plugin.ts
转换结果,我有与上述相同的错误。
将js结果(来自webpack或来自plain tsc transiplation)放在开发Web服务器实际提供文件的文件夹(.tmp)中,然后通过相对路径引用它们:这会导致webpack停止在编译时,因为当然,它在打包时找不到项目目录树中的文件。
现在我不知道去哪里,你有什么建议吗?
我想要实现的是使用webpack和typescript(一个js模块)动态加载,这在编译时是未知的。
答案 0 :(得分:0)
试试这个 https://blog.waffle.io/code-splitting-in-angular-2-with-webpack-2-ce8dd4b8b23e
这不会谈论插件的动态加载,而是谈论动态加载脚本,它可以帮助你实现你想要的。
答案 1 :(得分:0)
在 Webpack.config.js 下面更新代码。
解析器用于加载相对于 src 根目录的文件,并解析webpack.config.js中的 app 文件夹,该文件夹可以通过绝对路径访问,如上所示。
resolve: {
extensions: ['.ts', '.js', 'css'],
"modules": [
"./node_modules",
"src"
]
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].js',
publicPath: 'dist/',
}
在 system.import 中,如下所示:其中app是src文件夹中的文件夹
System.import('app/+ url').then(fileInstance=> {
console.log(fileInstance);
});