我正在为react-leaflet编写一个自定义组件。这是一个可编辑的弹出窗口,具有其他一些功能。以Here is a codesandbox为例。该组件的源代码为here。本示例仅执行import EditablePopup from 'my-react-leaflet-popup-plugin'
,这是我项目中的.js文件。效果很好。
我正在尝试使用webpack将其打包为一个节点模块,以便其他人可以使用它。它编译没有问题。您可以看到我的webpack.config.js here。然后,我使用npm link
将此模块链接到本地计算机上的测试项目。这样做时,我收到错误消息:
TypeError: Cannot read property 'leafletElement' of null
460 | value: function value() {
461 | var e = this;
462 | this.props.open && setTimeout(function () {
> 463 | e.thePopup.leafletElement._source.openPopup();
| ^ 464 | }, .001);
465 | }
466 | }, {
即使我摆脱了该条款,我也得到了:
TypeError: Cannot read property 'openPopup' of undefined
9226 | // @method openOn(map: Map): this
9227 | // Adds the popup to the map and closes the previous one. The same as `map.openPopup(popup)`.
9228 | openOn: function openOn(map) {
> 9229 | map.openPopup(this);
| ^ 9230 | return this;
9231 | },
9232 | onAdd: function onAdd(map) {
就像弹出窗口试图将自身添加到地图中一样,但是没有找到父Map组件的地图实例。我的直觉是,由于某种原因,当使用webpack构建它并将其作为npm模块导入时,react-leaflet映射的上下文未正确传递给我的组件。我不太了解,因为我的组件只是react-leaflet的<Popup>
组件的修饰版本。我的<EditablePopup>
使用<Popup>
作为直接子代,该子代本来应该接收LeafletConsumer上下文使用者包装器。
我不确定为什么在我的项目中链接此组件时,该组件会很好用,但是在通过webpack构建并通过npm导入时会出现此错误。
我发布的答案受this anwer中的Cannot read property 'Component' of undefined - webpack build of react component plugin启发。我的问题似乎至少与问题React Context API not working from custom NPM component library 相关,并且那些人仍在寻找答案-也许这会有所帮助。
为了解决此问题,我必须对webpack.config.js
和package.json
进行调整。
webpack.config.js
中更改此:
libraryTarget: 'commonjs2'
至此:
library: "EditablePopup",
libraryTarget: 'umd'
以及将mode: development
添加到module.exports
。
package.json
中将我的一些dependencies
移到peerDependencies
:
// Change from this:
"dependencies": {
"html-react-parser": "^0.10.0",
"leaflet": "^1.6.0",
"react": "^16.12.0",
"react-contenteditable": "^3.3.3",
"react-dom": "^16.12.0",
"react-leaflet": "^2.6.1",
"webpack": "^4.41.5"
},
"peerDependencies": {
"react": "^16.12.0",
"react-dom": "^16.12.0",
"react-leaflet": "^2.6.1",
"leaflet": "^1.6.0"
}
// to this:
"dependencies": {
"html-react-parser": "^0.10.0",
"react-contenteditable": "^3.3.3",
"webpack": "^4.41.5"
},
"peerDependencies": {
"react": "^16.12.0",
"react-dom": "^16.12.0",
"react-leaflet": "^2.6.1",
"leaflet": "^1.6.0"
}
我很确定它的webpack.config.js
更改是起因。为了完整起见,以下是对该文件的更改:
// webpack.config.jsvar path = require('path');module.exports = {条目:“ ./ src / EditablePopup.js”,输出:{路径:path.resolve(__ dirname,'build'),文件名:“ EditablePopup.js”,-libraryTarget:'commonjs2',+库:“ EditablePopup”,+ libraryTarget:'umd'},+模式:“开发”,模块:{规则:[{测试:/ \。js $ /,包括:path.resolve(__ dirname,'src'),排除:/(node_modules | bower_components | build)/,采用: [{加载程序:“ babel-loader”,选项:{预设:['@ babel / preset-env']}}]},{测试:/\.css$/,采用: [{loader:'style-loader'},{loader:'css-loader'}]}]},外部因素:{'react-dom':'commonjs react-dom',传单:{commonjs:'传单',commonjs2:'传单',根:“ L”},“反应传单”:{commonjs:'反应叶',commonjs2:'反应叶',root:“ ReactLeaflet”},反应:{commonjs:'反应',commonjs2:'反应',root:“反应”}}};
我在工作场所遇到类似的问题,现在我怀疑我们宣布Webpack配置的(类似)方法是罪魁祸首。但是对我来说,仅更改libraryTarget并没有任何效果。在描述我们的设置后,我的见解如下...
我们有一个视觉组件集合,我们正在捆绑到一个“库”中,该库将被导入到一个主要项目中。主项目需要获取一些外部数据,但需要在整个库组件的任意位置使用。而且我们不想到处传递道具。那么背景吧?除非提供者(我们在“主”项目中设置和初始化)和使用者位于库边界的不同侧面,否则使用者的上下文始终是未定义的(或者,无论“ createContext”的默认设置如何) ...我们没有使用初始化程序。
无论如何,快向前走一堆。如果我从将库中的每个不同组件都列为自己独立的“入口”(在webpack文件中)改为改为构建一个index.js文件,该文件可以导入并重新导出所有内容,并且仅以单数形式包含该文件“进入”(在webpack中)-然后事情开始起作用。
因为React上下文API需要创建要共享的Context对象,但是共享的概念(无论如何,我想还是在模块级别)。它不能是truly全局的。因此,不同的入口点,不同的模块,不同的上下文对象。消费者被冷落。