如何使用webpack绑定库而不捆绑重复的反应依赖关系?

问题描述:

我正在构建一个使用其他反应库作为依赖关系的可重用反应库。我使用webpack作为构建工具。如何使用webpack绑定库而不捆绑重复的反应依赖关系?

是我遇到的是当我输入我的图书馆到我的应用程序,这是建立与创造 - 反应 - 应用所面临的挑战,我得到以下错误:

addComponentAsRefTo(...): Only a ReactOwner can have refs. 
You might be adding a ref to a component that was not created inside a component's `render` method, 
or you have multiple copies of React loaded (details: https://facebook.github.io/react/warnings/refs-must-have-owner.html). 

的问题,因为我了解它,webpack是否在我的库中以冲突版本捆绑了一个额外的反应副本。

我试了几个建议,但他们都没有工作。我试着:

1.添加一个别名反应在我的WebPack
resolve: { 
    alias: { 
     'react' : path.resolve(__dirname, 'node_modules/react'), 
    }, 
    modules: [path.join(__dirname, 'node_modules')], 
    extensions: [".js", ".jsx"] 
    }, 
2.添加反应和反应-DOM中的WebPack的外部:
externals: { 
    'ReactCSSTransitionGroup': 'react/lib/ReactCSSTransitionGroup', 
    'react': { 
     commonjs: 'react', 
     commonjs2: 'react', 
     amd: 'react', 
     umd: 'react', 
     root: 'React' 
    }, 
    'react-dom': { 
     commonjs: 'react-dom', 
     commonjs2: 'react-dom', 
     amd: 'react-dom', 
     umd: 'react-dom', 
     root: 'ReactDOM' 
    } 
    }, 
3.也试图加入一个反应package.json中的devDependency和peerDependency。

如果我在将库链接到应用程序时删除了node_modules文件夹,它将开始工作。这显然不是一个解决方案,但更多的暗示是它正在从node_modules中获取额外的反应副本。只要我运行npm i问题就会返回。

这里是我的全部的WebPack:

const path = require('path') 
const SRC_DIR = path.resolve(__dirname, 'src') 
const DIST_DIR = path.resolve(__dirname, 'dist') 

module.exports = { 
    entry: SRC_DIR + '/index.js', 
    output: { 
    path: DIST_DIR, 
    filename: 'index.js', 
    libraryTarget: 'umd' 
    }, 
    resolve: { 
    alias: { 
     'react' : path.resolve(__dirname, 'node_modules/react'), 
    }, 
    modules: [path.join(__dirname, 'node_modules')], 
    extensions: [".js", ".jsx"] 
    }, 
    resolveLoader: { 
    modules: [path.join(__dirname, 'node_modules')] 
    }, 
    externals: { 
    'ReactCSSTransitionGroup': 'react/lib/ReactCSSTransitionGroup', 
    'react': { 
     commonjs: 'react', 
     commonjs2: 'react', 
     amd: 'react', 
     umd: 'react', 
     root: 'React' 
    }, 
    'react-dom': { 
     commonjs: 'react-dom', 
     commonjs2: 'react-dom', 
     amd: 'react-dom', 
     umd: 'react-dom', 
     root: 'ReactDOM' 
    } 
    }, 
    module: { 
    loaders: [ 
     { test: /\.css$/, loader: 'style-loader!css-loader' }, 
     { 
      test: /\.js?/, 
      include: SRC_DIR, 
      loader: 'babel-loader', 
      exclude: /node_modules/, 
      query: { 
      presets: ['es2015', 'react', 'stage-0'], 
      plugins: [ 
       'transform-class-properties', 
       'transform-object-rest-spread' 
      ] 
      } 
     } 
    ] 
    } 
}; 

而且我的package.json:

{ 
    "name": "test-library", 
    "version": "1.0.0", 
    "main": "dist/index.js", 
    "scripts": { 
    "start": "webpack --progress --colors --watch", 
    "test": "echo \"Error: no test specified\" && exit 1" 
    }, 
    "author": "", 
    "license": "ISC", 
    "description": "", 
    "devDependencies": { 
    "babel-core": "6.26.0", 
    "babel-loader": "7.1.2", 
    "babel-plugin-react-css-modules": "3.2.1", 
    "babel-plugin-transform-class-properties": "6.24.1", 
    "babel-plugin-transform-object-rest-spread": "6.26.0", 
    "babel-plugin-transform-runtime": "6.23.0", 
    "babel-preset-es2015": "6.24.1", 
    "babel-preset-react": "6.24.1", 
    "babel-preset-stage-0": "6.24.1", 
    "react": "^15.0.0", 
    "react-bootstrap-table": "4.0.2", 
    "react-dom": "15.6.1" 
    } 
} 

我还创建了两个回购重现错误,一个是测试应用程序,一个是测试库。要重现:

  1. 克隆的应用程序和库和运行npm i: 应用:https://github.com/scottmcpherson/test-app 库:https://github.com/scottmcpherson/git-library

  2. 光盘放入库中并运行npm link

  3. CD到应用程序并运行npm link test-library

  4. cd回到应用程序并运行npm start

  5. 您应该看到错误出现在浏览器中。如果你在你的编辑器中打开应用程序,并看看App.js,你可以看到我想要导入测试库的位置。

此错误仅发生是因为库取决于react-bootstrap-table。如果我注释掉这个模块,只是渲染一个普通的jsx表,一切都可以找到。

根据documentation避免重复的依赖,你可以试试这个:

new webpack.optimize.CommonsChunkPlugin({ 
    name: 'common' 
})