使用Typescript

时间:2017-03-29 07:32:58

标签: angular webpack-2 typescript2.0 plugin-architecture

我正在尝试构建支持插件的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模块)动态加载,这在编译时是未知的。

2 个答案:

答案 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);            
});