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

2023-11-25

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

我在运行时使用导入模块System.import来自 Webpack,虽然我知道它已被弃用,但据我所知,这是使用 typescript 动态导入模块的唯一方法,因为importTypescript 本身尚不支持(参考here)。 (还有其他方法可以实现这一点吗?)

现在,为了测试系统,我使用下面的目录树将插件目录包含在应用程序的同一根目录(src 目录)中;请注意,这会导致 webpack 在编译时知道插件代码的存在,并将插件和应用程序打包在同一个包集中,这是为了测试插件架构功能的简化;这是文件夹树:

- src
    - app
        - core
            - plugin.service.ts
    - plugins
        - pluginA
            - pluginA.plugin.ts

这样如果我导入pluginA.plugin.ts with System.import('relativePathToPluginA')一切都按预期进行:系统能够加载和编译插件组件并使用它。

But在现实场景中,插件在编译时一定是未知的,因此我使用 angular-cli 创建了一个新项目,并添加了pluginA 目录,然后在其 app.module 中引用了它。然后我构建了项目并将 js 输出移动到一个文件夹中,比方说D:\pluginDist\。 然后我参考了main.bundle.js来自上面的 loadPlugin 方法,如下例所示(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 或来自普通 tsc 转换)放在开发 Web 服务器实际提供文件的文件夹中(.tmp),然后通过相对路径引用它们:这会导致 webpack 在编译时停止,因为,当然,打包时并没有在项目目录树中找到文件。

现在我不知道该去哪里,你有什么建议吗?

我想要实现的是使用 webpack 和 typescript 动态加载一个 js 模块,该模块在编译时是未知的。


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

The resolver用于加载相对于src根并通过解决appwebpack.config.js 中的文件夹,可以通过绝对路径访问该文件夹中的文件,如上所示。

resolve: {
    extensions: ['.ts', '.js', 'css'],
    "modules": [
        "./node_modules",
        "src"
    ]
},

output: {
        path: path.resolve(__dirname, 'dist'),
        filename: '[name].js',
        publicPath: 'dist/',
    }

而在你的系统导入如下:其中 app 是 src 文件夹中的文件夹

System.import('app/+ url').then(fileInstance=> {          
    console.log(fileInstance);            
});
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Typescript 通过 Webpack 动态加载模块 的相关文章

随机推荐