Webpack HMR因jsPDF引发React syntheticEvent错误

Zfa*_*len 7 node.js jspdf reactjs webpack webpack-hmr

系统信息:

OSX 10.12.4 Sierra
Node v7.10.0
npm v4.2.0
Run Code Online (Sandbox Code Playgroud)

浏览器测试:

Chrome 58.0.3029.110
Safari 10.1
Firefox 53.0
Run Code Online (Sandbox Code Playgroud)

问题:

我有一个在生产中有效运行的应用程序,我已经克隆并且正在尝试更新以准备构建续集.但是,我通过将它/ React/HMR更新到更新的版本来遇到一个奇怪的Webpack问题.

HMR将连接,Webpack似乎编译得很好.但是,与页面交互(例如单击)会生成以下错误:

syntheticEvent错误

显然,应用程序在那时不再起作用,因为点击事物不会触发任何事情.有趣的是,我们还在Node控制台和浏览器中收到以下404错误:

404 (注意:这似乎是一个巨大的查询字符串,包括函数,特别是引用syntheticEvent.如果你愿意,我可以打印整件事)

NODE v6.3.1

相关的NPM:

"react": "^15.5.4",
"react-dom": "^15.5.4",
"react-transform-catch-errors": "^1.0.0",
"react-transform-hmr": "^1.0.4",

"webpack": "^2.5.1",
"webpack-dev-middleware": "^1.10.2",
"webpack-hot-middleware": "^2.18.0"

"babel-cli": "^6.11.4",
"babel-core": "^6.24.1",
"babel-eslint": "^7.2.1",
"babel-loader": "^7.0.0",
"babel-plugin-array-includes": "^2.0.0",
"babel-plugin-transform-decorators-legacy": "^1.0.0",
"babel-plugin-transform-object-assign": "^6.0.0",
"babel-preset-es2015": "^6.24.1",
"babel-preset-react": "^6.24.1",
"babel-preset-react-hmre": "^1.1.1",
"babel-preset-stage-1": "^6.24.1",
Run Code Online (Sandbox Code Playgroud)

WEBPACK.CONFIG.DEV.JS:

var path = require('path');
var webpack = require('webpack');
var autoprefixer = require('autoprefixer');
var hotMiddlewareScript = 'webpack-hot-middleware/client';

console.log('using the dev config file');
console.log('THE PUBLIC PATH: ' + path.join(__dirname, '/CLIENTSIDE/static'));

module.exports = {
  devtool: 'eval',
  entry: {
    background: ['webpack-hot-middleware/client', path.join(__dirname, '/CLIENTSIDE/components/background')],
    uniqueShare: ['webpack-hot-middleware/client',  path.join(__dirname, '/CLIENTSIDE/components/uniqueShare')],
    starRating: ['webpack-hot-middleware/client', path.join(__dirname, '/CLIENTSIDE/components/starRating')],
    testingPage: ['webpack-hot-middleware/client', path.join(__dirname, '/CLIENTSIDE/components/testingPage')],
    style: ['webpack-hot-middleware/client', path.join(__dirname, '/CLIENTSIDE/components/style')]
  },
  output: {
    path: path.join(__dirname, '/CLIENTSIDE/static'),
    filename: '[name].js',
    publicPath: '/static/'
  },
  plugins: [
    new webpack.optimize.OccurrenceOrderPlugin(),
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NoEmitOnErrorsPlugin()
  ],
  module: {
    loaders: [
        {
            test: /\.(js|jsx)$/,
            exclude: /(node_modules|bower_components)/,
            loader: 'babel-loader',
            query: {
              cacheDirectory: true,
              presets: ['react', 'es2015', 'stage-1'],
              plugins: ['transform-decorators-legacy', 'transform-object-assign', 'array-includes'],
            },
        },
        {
            test: /\.scss$/,
            loaders: ['style-loader', 'css-loader', 'sass-loader']
        }
      ]
    }
  };
Run Code Online (Sandbox Code Playgroud)

我们加载HMR的地方:

  console.log('****************************** RUNNING IN DEV MODE ******************************');
  var webpack = require('webpack');
  var webpackConfig = require('./webpack.config.dev');
  var compiler = webpack(webpackConfig);

  console.log('Looking for the HMR here: ' + webpackConfig.output.publicPath);

  app.use(require('webpack-dev-middleware')(compiler, {
    noInfo: true,
    publicPath: webpackConfig.output.publicPath
  }));

  app.use(require('webpack-hot-middleware')(compiler));
Run Code Online (Sandbox Code Playgroud)

现在,这是奇怪的部分.Babel/Webpack 在生产模式下编译所有内容都很好,没有热重新加载器.当我们将Node ENV设置为'PRODUCTION'时,应用程序运行完全正常 - 没有syntheticEvent错误.

此外,应用程序以开发模式(使用热重新加载)运行,使用前一个堆栈,包括以下NPM版本:

"react": "^0.14.8",
"react-dom": "^0.14.3",
"react-transform-catch-errors": "^1.0.0",
"react-transform-hmr": "^1.0.0",

"webpack": "^1.13.1",
"webpack-dev-middleware": "^1.2.0",
"webpack-hot-middleware": "^2.0.0"

"babel": "^6.5.2",
"babel-cli": "^6.10.1",
"babel-core": "^6.10.4",
"babel-loader": "^6.2.4",
"babel-plugin-transform-es2015-modules-commonjs": "^6.0.2",
"babel-plugin-transform-react-constant-elements": "^6.0.2",
"babel-preset-es2015": "^6.0.8",
"babel-preset-react": "^6.0.2",
Run Code Online (Sandbox Code Playgroud)

更新5/16/17:

我们已经将问题从React/React DOM迁移0.14.8到了v15.0.0.这样做会立即触发我们的错误 - 但仅限于HMR/Dev模式.

没有HMR的生产版本编译得很好; 引用Webpack通过该配置生成的缩小文件让应用程序正常运行100%.

确切相同的构建运行在阵营/ DOM 100%细0.14.8,在开发模式下,HMR.升级ONLY的WebPack/HMR /的WebPack热中间件到最新版本确实触发错误.

我花了一些时间深入调试面板,发现以下内容:

Clickeventobject 这是对React本机生成的实际事件对象的一瞥.在这种情况下,"topClick"与我们创建的任何处理程序都没有关联.我可以通过单击页面上的任意位置来解决此问题和错误.

错误发生的地方 这是实际发生错误的行.它来自react-dom/lib/SyntheticUIEvent.js - 并且似乎无法在SyntheticEvent类上初始化.call方法... 在此输入图像描述

还值得注意的是,每次重新加载时,控制台也会触发以下错误.

GET http://localhost:3333/[object%20Object]?url=function%20SyntheticEvent(dispa…d%20%3D%20emptyFunction.thatReturnsFalse%3B%0A%20%20return%20this%3B%0A%7D 404 (Not Found)
(anonymous) @ jspdf.debug.js:17350
l @ jspdf.min.js:284
u @ jspdf.min.js:284
XHR @ jspdf.debug.js:17334
Proxy @ jspdf.debug.js:16928
(anonymous) @ SyntheticEvent.js:188
(anonymous) @ SyntheticEvent.js:268
(anonymous) @ background.js:805
__webpack_require__ @ background.js:658
fn @ background.js:86
(anonymous) @ SyntheticCompositionEvent.js:13
(anonymous) @ background.js:2110
__webpack_require__ @ background.js:658
fn @ background.js:86
(anonymous) @ BeforeInputEventPlugin.js:16
(anonymous) @ background.js:1767
__webpack_require__ @ background.js:658
fn @ background.js:86
(anonymous) @ ReactDefaultInjection.js:14
(anonymous) @ background.js:1963
__webpack_require__ @ background.js:658
fn @ background.js:86
(anonymous) @ ReactDOM.js:16
(anonymous) @ ReactDOM.js:111
(anonymous) @ background.js:1844
__webpack_require__ @ background.js:658
fn @ background.js:86
(anonymous) @ index.js:3
(anonymous) @ background.js:812
__webpack_require__ @ background.js:658
fn @ background.js:86
(anonymous) @ background.js:9
(anonymous) @ background.js:3178
__webpack_require__ @ background.js:658
fn @ background.js:86
(anonymous) @ background:2
(anonymous) @ background.js:3287
__webpack_require__ @ background.js:658
(anonymous) @ background.js:707
(anonymous) @ background.js:710
Run Code Online (Sandbox Code Playgroud)

来自Node控制台的相同错误:

GET /[object%20Object]?url=function%20SyntheticEvent(dispatchConfig%2C%20targetInst%2C%20nativeEvent%2C%20nativeEventTarget)%20%7B%0A%20%20if%20(process.env.NODE_ENV%20!%3D%3D%20%27production%27)%20%7B%0A%20%20%20%20%2F%2F%20these%20have%20a%20getter%2Fsetter%20for%20warnings%0A%20%20%20%20delete%20this.nativeEvent%3B%0A%20%20%20%20delete%20this.preventDefault%3B%0A%20%20%20%20delete%20this.stopPropagation%3B%0A%20%20%7D%0A%0A%20%20this.dispatchConfig%20%3D%20dispatchConfig%3B%0A%20%20this._targetInst%20%3D%20targetInst%3B%0A%20%20this.nativeEvent%20%3D%20nativeEvent%3B%0A%0A%20%20var%20Interface%20%3D%20this.constructor.Interface%3B%0A%20%20for%20(var%20propName%20in%20Interface)%20%7B%0A%20%20%20%20if%20(!Interface.hasOwnProperty(propName))%20%7B%0A%20%20%20%20%20%20continue%3B%0A%20%20%20%20%7D%0A%20%20%20%20if%20(process.env.NODE_ENV%20!%3D%3D%20%27production%27)%20%7B%0A%20%20%20%20%20%20delete%20this%5BpropName%5D%3B%20%2F%2F%20this%20has%20a%20getter%2Fsetter%20for%20warnings%0A%20%20%20%20%7D%0A%20%20%20%20var%20normalize%20%3D%20Interface%5BpropName%5D%3B%0A%20%20%20%20if%20(normalize)%20%7B%0A%20%20%20%20%20%20this%5BpropName%5D%20%3D%20normalize(nativeEvent)%3B%0A%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20if%20(propName%20%3D%3D%3D%20%27target%27)%20%7B%0A%20%20%20%20%20%20%20%20this.target%20%3D%20nativeEventTarget%3B%0A%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20this%5BpropName%5D%20%3D%20nativeEvent%5BpropName%5D%3B%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%20%20%7D%0A%0A%20%20var%20defaultPrevented%20%3D%20nativeEvent.defaultPrevented%20!%3D%20null%20%3F%20nativeEvent.defaultPrevented%20%3A%20nativeEvent.returnValue%20%3D%3D%3D%20false%3B%0A%20%20if%20(defaultPrevented)%20%7B%0A%20%20%20%20this.isDefaultPrevented%20%3D%20emptyFunction.thatReturnsTrue%3B%0A%20%20%7D%20else%20%7B%0A%20%20%20%20this.isDefaultPrevented%20%3D%20emptyFunction.thatReturnsFalse%3B%0A%20%20%7D%0A%20%20this.isPropagationStopped%20%3D%20emptyFunction.thatReturnsFalse%3B%0A%20%20return%20this%3B%0A%7D 404 4.745 ms - 35162
Run Code Online (Sandbox Code Playgroud)

Zfa*_*len 2

2017 年 5 月 24 日更新:

我们终于解决了这个问题——一个典型的错误!

在重新调整我们的整个堆栈以使其更符合 后create-react-app,我将之前的 React 应用程序迁移到开发服务器索引文件中。按预期工作,尽管没有正确的 HTML 包装和样式等。

然而,当我将应用程序渲染到的完整 HTML 页面迁移到某个<div id="root>元素时,它再次开始抛出 SyntheticEvent 错误!经过大量工作和重组,最终将问题隔离到 HTML 文件(实际上,该文件最初实际上是一个 EJS 文件,主要包含基本框架以及 SEO 跟踪)

问题是:我们有一个过时的<script/>标签,正在调用jsPDF v1.2.61 ( https://github.com/MrRio/jsPDF )。我们实际上不再使用这个插件,并且由于合并冲突,该脚本似乎又回到了我们的代码中。

回想起来,OP 中发布的代码确实引用了 jsPDF 插件,但堆栈跟踪并没有真正提供任何错误起源的指示。因为我们从应用程序一开始就没有接触过这个插件,并且追求了一种替代方法,所以这个名字并没有敲响任何警钟——考虑到后来对 React 脚本的调用,我只是假设了前三行左右堆栈跟踪表明 jspdf 是 React 库中一些不起眼的部分。

此问题有两个修复方法:

  1. 完全删除脚本 -这就是我们所做的,因为我们不再在应用程序中使用 jsPDF。
  2. 更新 jsPDF -该插件现在位于v1.3.4. 之前的版本v1.2.61与本机库脚本产生严重冲突React v15.0.0+。新版本不会产生冲突。

希望这会对某人有所帮助!

仅供参考;之前的解决方案不起作用,并提示我们进行上述修复:

为了推动我们的项目向前发展,我们选择了使用create-react-app和的替代堆栈custom-react-scripts

https://github.com/facebookincubator/create-react-app

https://github.com/kitze/custom-react-scripts

最终,我们(松散地)遵循这种模式来同时运行 CRA Stack 和我们的 Node / Express 内容: https://www.fullstackreact.com/articles/using-create-react-app-with-a-server/

最终,这实现了我们将新堆栈推向最新技术的目标。而且,它可能比我们之前运行的要干净一些。

然而,我仍然对上述错误的根源感到完全困惑。我已经在一堆其他测试堆栈中移动了一些东西,并且似乎无法通过和复制问题Webpack 2-React 15+而且我设置它们的方式与我们原来的堆栈没有什么本质上的不同。

无论发生什么,这都很奇怪。