首页 文章

使用Typescript使用Webpack动态加载模块

提问于
浏览
7

我正在尝试构建一个支持插件的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 回答

  • 0

    试试https://blog.waffle.io/code-splitting-in-angular-2-with-webpack-2-ce8dd4b8b23e

    这不会谈论插件的动态加载,而是谈论动态加载脚本,它可以帮助你实现你想要的 .

  • 0

    Webpack.config.js 更新下面的代码 .

    resolver 用于加载相对于 src root的文件,通过解析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);            
    });
    

相关问题