webpack 是否会删除生产中附加到“window”的自定义变量或事件侦听器?

saa*_*adq 21 javascript node.js reactjs webpack

问题:

我们面临的问题是,我们附加的任何事件侦听器或全局变量window似乎都不存在于我们的production构建中(但它们存在于development构建中)。


语境

我们有一个用例,我们的 web 应用程序在父应用程序中呈现。父应用程序基本上需要告诉我们何时需要渲染我们的应用程序。为此,我们尝试使用事件侦听器和全局函数。

我们的应用程序如何加载到父应用程序中

要在父应用程序中渲染我们的 web 应用程序,会发生以下情况:

  1. 父应用程序对 进行 HTTP 调用myappwebsite.com/asset-manifest.json。这就像asset-manifest.json为任何 Web 应用程序创建的默认值create-react-app
  2. 父应用程序从此资产清单中查找到主应用程序的路径bundle.js,然后bundle.js使用此路径进行 HTTP 调用来获取我们的路径(例如myappwebsite.com/bundle.js)。
  3. 他们动态地将一个script标签注入到他们的集合中head,并将其src设置为我们的bundle.js以加载我们应用程序的捆绑JavaScript。
  4. 在尝试调用我们的任何代码或分派任何事件之前,它们会监听onload这个新元素的事件。script

尝试1

儿童应用程序:

// index.tsx

window.addEventListener('renderApp', (event) => {
  console.log('This is running!'); // This only prints in `development`
  const { rootId } = event.detail;
  ReactDOM.render(<App />, document.getElementById(rootId));
})
Run Code Online (Sandbox Code Playgroud)

父应用程序:

// index.tsx

console.log('Dispatch is running!'); // This prints in both `development` and `production`
const renderEvent = new CustomEvent('renderApp', { detail: rootId: 'root' });

// This runs in the script.onload function to wait for our app to load
window.dispatchEvent(renderEvent);
Run Code Online (Sandbox Code Playgroud)

该代码在构建中有效development,但在production构建中无效。在 中production,调度确实执行,但由于某种原因事件侦听器没有执行。当我们尝试在缩小的生产包上设置一些断点时,我们注意到代码addEventListener在那里,但它实际上并没有执行...这很奇怪,因为它addEventListener位于子应用程序的顶层index.tsx并且没有条件添加。


尝试2

儿童应用程序:

// index.tsx

window.renderApp = (rootId) => {
  console.log('Child render is running'); // This only prints in `development`
  ReactDOM.render(<App />, document.getElementById(rootId));
})
Run Code Online (Sandbox Code Playgroud)

父应用程序:

// index.tsx

console.log('Render is running!'); // This prints in both `development` and `production`

// This runs in the script.onload function to wait for our app to load
window.renderApp(rootId);
Run Code Online (Sandbox Code Playgroud)

这里同样的问题,代码在构建中有效development,但在production构建中无效。在 中production,调用成功,但全局功能似乎没有打开window。我可以通过window在控制台中打印来验证这一点。


似乎我设置的任何全局变量window或我设置的任何事件侦听器在生产版本中都会被忽略。这是Webpack设计的吗?或者您认为我的配置/构建脚本中有什么问题导致了这种情况的发生?

saa*_*adq 1

问题最终是我们的包的输出被分成 和main.jsvendor.js但我们只将 加载main.js到父应用程序中。