Webpack HMR抛出响应由于jsPDF造成的syntheticEvent错误

系统信息:

OSX 10.12.4 Sierra Node v7.10.0 npm v4.2.0 

浏览器已testing:

 Chrome 58.0.3029.110 Safari 10.1 Firefox 53.0 

问题:

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

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

syntheticEvent错误

显然,该应用程序在这一点上不再起作用,因为点击事件不会引发任何事情。 有趣的是,我们在Node控制台和浏览器中也得到了以下404错误:

404 (注:这似乎是一个巨大的查询string,包括函数,特别是引用syntheticEvent。如果你愿意,我可以打印整个东西)

NODE v6.3.1

相关的NPMs:

 "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", 

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'] } ] } }; 

我们在哪里加载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)); 

现在,这是奇怪的部分。 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", 

更新5/16/17:

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

没有HMR的生产版本编译得很好; 引用Webpack通过该configuration产生的缩小文件可以使应用程序100%正常工作。

完全相同的构build在React / DOM 0.14.8 ,Dev模式下,使用HMR运行100%。 升级Webpack / HMR / webpack-hot-middleware到最新版本不会触发错误。

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

Clickeventobject 这是对React本地生成的实际事件对象的一个​​正确的浏览。 在这种情况下,“topClick”与我们创build的任何处理程序都没有关联。 我可以通过点击页面上的任何地方,从字面上触发这个错误。

发生错误的地方 这是错误实际发生的路线。 它来自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 

来自节点控制台的相同错误:

 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 

更新5/24/17:

我们终于find了这个问题 – 一个经典的错误!

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

然而,当我将完整的HTML页面迁移到一个<div id="root>元素时,它又开始吐出SyntheticEvent错误!很多工作和重组最终都将问题隔离到了HTML文件(实际上,它本来就是一个EJS文件,主要包含一个基本框架以及SEO跟踪)

这里是rub:我们有一个过时的<script/>标签,正在调用jsPDF v1.2.61 https://github.com/MrRio/jsPDF 。 我们已经不再使用这个插件了,而且由于合并冲突,脚本似乎已经悄悄地回到代码中。

回想起来,在OP 发布的代码确实引用了jsPDF插件,但是堆栈跟踪并没有真正提供错误发生地点的任何指示。 因为我们从应用程序一开始就没有触及插件,并且寻求另一种方法,所以名字没有响起任何响铃 – 考虑到后来对React脚本的调用,我简单地假设了前三行堆栈跟踪指出jspdf是React库中一些不太明确的部分。

这个问题有两个问题:

  1. 完全删除脚本 –这是我们所做的,因为我们不再在我们的应用程序中使用jsPDF。
  2. 更新jsPDF –插件现在在v1.3.4 。 先前版本v1.2.61React v15.0.0+本机库脚本产生了中断冲突 。 新版本不会产生冲突。

希望这会帮助一些人!

只有参考; 以前的解决scheme,没有工作,并给我们上面的修复:

为了推动我们的项目,我们select了使用create-react-appcustom-react-scripts的替代堆栈。

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

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

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

在这一天结束的时候,这实现了将新堆栈推向最新技术的目标。 而且,它可能比我们之前运行的更清洁。

但是,对于上述错误的来源,我还是完全迷惑不解。 我已经在一堆其他testing堆栈中移动了东西,似乎无法复制Webpack 2React 15+ – 而且我从原始堆栈设置它们的方式没有什么根本的不同。

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