【问题标题】:Consuming a UMD created by Webpack results in duplicate libs in output使用 Webpack 创建的 UMD 会导致输出中出现重复的库
【发布时间】:2016-01-15 17:22:18
【问题描述】:

图书馆

我正在创建一个 React.js 库并尝试将其打包为 UMD 以进行分发。库中webpack.config.js文件如下:

module.exports = {
  entry: [
    __dirname+'/modules/index.js'
  ],
  output: {
    path: path.join(__dirname, 'lib'),
    filename: 'index.js',
    library: 'MyLibrary',
    libraryTarget: 'umd'
  },
  externals: {
    root: 'React',
    commonjs2: 'react',
    commonjs: 'react',
    amd: 'react'
  },
  resolve: {
    extensions: ['', '.js']
  },
  plugins: [
    new webpack.optimize.OccurenceOrderPlugin(true)
  ]
};

运行 webpack 会在 ./lib/index.js 中正确创建 UMD 版本。

消费者

但是,当尝试在另一个项目中使用这个库时,Webpack 错误地解析了 MyLib 中 lib/index.js 中的 require('react') 语句,并两次包含了 React 库。

消费者的webpack.config.js 文件是:

module.exports = {
  entry: [
    __dirname + '/src/index.js'
  ],
  output: {
    path: path.join(__dirname, 'dist'),
    pathinfo: true,
    filename: 'index.js'
  }
};

消费者的入口点很简单(src/index.js):

React = require('react');
MyLib = require('my-lib');

console.log('React.Component', React.Component);

在消费者返回中运行webpack

Version: webpack 1.12.11
Time: 1179ms
   Asset     Size  Chunks             Chunk Names
index.js  1.35 MB       0  [emitted]  main
   [0] multi main 28 bytes {0} [built]
   [1] ./src/index.js 199 bytes {0} [built]
 [170] ../my-lib/lib/index.js 165 kB {0} [built] [1 error]
    + 168 hidden modules

ERROR in ../my-lib/lib/index.js
Module not found: Error: Cannot resolve module 'react' in [...]my-lib/lib
 @ ../my-lib/lib/index.js 3:27-43

如果我通过 npm 在node_modules/my-lib 中安装react,那么 webpack 将运行而不会出现错误,但 React.js 将在最终输出中包含两次。检查构建的文件显示,当 Webpack 在 node_modules/my-lib/lib/index.js 中遇到 require('react') 时,它会尝试直接从本地 node_modules 包含一个新版本,而不是从 src/index.js 包含已有的版本。

我觉得我在这里遗漏了一些非常明显的东西,但我无法取得任何进展。

【问题讨论】:

  • 注意:我找到了一种解决方法,强制消费者中的 webpack 首先解析根目录 node_modules (从而找到已经包含的 react 实例)。然而这感觉不正确......root: [ __dirname, path.resolve('./node_modules') ]

标签: javascript reactjs webpack umd


【解决方案1】:

node_modules/react/lib/ReactTransitionGroup.js React 被包含为一个相对依赖:

var React = require('./React');

我不知道为什么在这个特定的文件中 React 以这种方式包含在 React 包中,而不是其他任何地方。

var React = require('react');

无论如何,正因为如此,React 被包含了两次,分别是 node module (require('react')) 和 file module (require('./React.js'))。 Webpack 会将它们视为两个不同的模块,并将它们添加两次。

我避免了这种重复,使这个相对模块成为指向同一个 React 的外部依赖项。与您对 React 模块所做的相同,但两者都适用。然后它只捆绑一次。

webpack.config.js

var reactExternals = {
  root: 'React',
  commonjs2: 'react',
  commonjs: 'react',
  amd: 'react'
};
var reactDOMExternals = {
  root: 'ReactDOM',
  commonjs2: 'react-dom',
  commonjs: 'react-dom',
  amd: 'react-dom'
};

module.exports = {
  entry: [
    __dirname+'/modules/index.js'
  ],
  output: {
    path: path.join(__dirname, 'lib'),
    filename: 'index.js',
    library: 'MyLibrary',
    libraryTarget: 'umd'
  },
  externals: [
    {
      'react': reactExternals,
      './React': reactExternals,
      'react-dom': reactDOMExternals
    }
  ],
  resolve: {
    extensions: ['', '.js']
  },
  plugins: [
    new webpack.optimize.OccurenceOrderPlugin(true)
  ]
};

【讨论】:

  • 感谢您的回答。我试过这个,但没有任何区别。我也尝试使用 lodash 而不是 react 来做同样的事情,看看 react 是否有什么特别之处,并看到了 lodash 的相同问题。
  • @BenSargent 我已经更新了webpack.config.js 以忽略react-dom 作为外部对象。在我的配置文件中,它也在外部,因为我认为它是 peerDependency,如 react。也许有帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-15
  • 2018-04-27
  • 2016-04-05
  • 1970-01-01
  • 1970-01-01
  • 2016-07-29
相关资源
最近更新 更多