将 opentok-layout-js 添加到 Rails 的 webpack

Add opentok-layout-js to webpack for Rails

我正在尝试将 opentok-layout-js 添加到使用 webpack 的 rails 6 应用程序。 (https://github.com/aullman/opentok-layout-js)

我看到我可以通过纱线添加它。所以我已经做到了。在我的 app/javascript/packs/application.js 文件中,我添加了:

require("opentok-layout-js")

当我尝试 运行 示例时:

<script type="text/javascript" charset="utf-8">
    var layoutContainer = document.getElementById("layoutContainer");

    // Initialize the layout container and get a reference to the layout method
    var layout = initLayoutContainer(layoutContainer).layout;

    // Below is a normal hello world OpenTok application for v2 of the API
    // The layout container will redraw when the layout mtehod is called and
    // adjust the layout accordingly
    var sessionId = "mySessionId";
    var token = "myToken";
    var apiKey = "myAPIKey";

    var session = OT.initSession(sessionId);
    session.on("streamCreated", function(event){
        session.subscribe(event.stream, "layoutContainer", {
            insertMode: "append"
        });
        layout();
    }).connect(apiKey, token, function (err) {
        if (!err) {
            session.publish("publisherContainer");
            layout();
        }
    });
</script>

这会不断产生 "initLayoutContainer" is not defined 消息。

在他们的示例中,他们使用:

<script src="js/opentok-layout.min.js"></script>

初始化该脚本。我在哪里使用 webpack 并将其包含在我的包中。我做错了什么,为什么 initLayoutContainer 在按我的方式完成后看不到?我的包包含在页面的 header 中,可用于所有其他目的。

默认情况下,Webpack 不会将任何内容导出到全局范围。要处理您描述的问题,您有几种选择:

  1. 把你的JS放在Webpack中(这是我推荐的)

    无需使用 <script> 标记来初始化和设置 opentok,只需将 JS 文件添加到执行相同操作的 Webpack 依赖关系图中即可。在这里,您可以获得捆绑此 JS 的好处,确保模块可用于 import 语句、linting、单元测试等

    // app/javascript/src/setup.js 
    import initLayoutContainer from 'opentok-layout-js'
    
    document.addEventListener('DOMContentLoaded', function() {
      const layoutContainer = document.getElementById("layoutContainer")
      const layout = initLayoutContainer(layoutContainer)
      // ...
    })
    
    // app/javascript/packs/application.js
    
    import '../src/setup'
    
  2. 或者,配置 Webpack 以使用 expose-loader

    initLayoutContainer 公开到全局范围

    如果您坚持在 <script> 标记中的 Webpack 包外部进行设置,您可以扩展 Webpacker 配置以确保您选择的导出在 window 对象上可用在您的依赖关系图中导入时的浏览器。

    // config/webpack/environment.js
    
    const { environment } = require('@rails/webpacker')
    
    environment.loaders.append('opentok-layout', {
      test: require.resolve('opentok-layout-js'),
      use: [{
        loader: 'expose-loader',
        options: 'initLayoutContainer'
      }]
    })
    
    module.exports = environment
    
    // app/javascript/packs/application.js
    
    import 'opentok-layout-js'
    
  3. 或者,在第一次导入时手动将 initLayoutContainer 公开到全局范围

    2. 的替代方法是简单地将导入的函数附加到 window 你自己从 Webpack 中。这是我最不喜欢的,因为我更愿意避免这样的副作用,而且我发现它很容易出错;但是,大多数人发现这更容易。

    // app/javascript/packs/application.js
    
    import initLayoutContainer from 'opentok-layout-js'
    window.initLayoutContainer = initLayoutContainer
    

这是因为在他们的示例中,他们将其直接存储在本地 src 中。您可以在 repo 的根目录中找到它并执行相同的操作。 https://github.com/aullman/opentok-layout-js 这就是我为解决问题所做的。