简体   繁体   中英

Using Bower with Webpack - React

To preface, I'm aware that I should probably avoid using Bower and instead use NPM to manage all my JavaScript dependencies. However, I'm working with some legacy code which uses Bower heavily, and until I can move everything over to NPM, I'd like to get a working version of my code base with Bower and Webpack.

That being said, I'm following the configuration setup for using Bower with Webpack from the official guide: https://webpack.github.io/docs/usage-with-bower.html

In particular, I've set up a Github repo where I was able to bower install jquery and using the configuration from the official guide, I was able to require("jquery") in my source code and have it work with Webpack. Given that this worked for jQuery, I assumed that it would work for other bower packages, including React.

However, after running bower install react , I attempted to require("react") in my source code but Webpack threw an error saying, Module not found: Error: Cannot resolve module 'react' in /Users/wmock/Desktop/using-bower-with-webpack/src .

This is my Github repo: https://github.com/fay-jai/Using-Bower-Through-Webpack

I have 3 branches:

  1. The "jquery-working" branch follows the configuration from the official guide and works with jQuery installed via Bower.
  2. The "jquery-react-not-working" branch is the same configuration as above but with React installed via Bower. This doesn't work.
  3. The "master" branch has a working version for both jQuery and React installed via Bower, BUT it doesn't follow the configuration setup specified in the official Webpack documentation.

Question:

  1. Is there a way to get the "jquery-react-not-working" branch to work? In other words, is there a way to follow the official documentation and have bower packages like React work with Webpack?
  2. Are there any drawbacks to using the approach specified in the "master" branch? Should this be the more preferred way to use Bower with Webpack?

EDIT (4/12/2016):

  1. It seems like the DirectoryDescriptionFilePlugin can't handle an array of filenames which is why the "jquery-react-not-working" branch doesn't work.
  2. I'd love to hear more answers for my 2nd question but my gut tells me that using the approach specified in the "master" branch will not be ideal because: a) you have to manually alias each library and b) you might run into version conflicts if multiple libraries use the same underlying libraries as well.

jquery-react-not-working branch - DirectoryDescriptionFilePlugin

DirectoryDescriptionFilePlugin can't deal with arrays of filenames, so you can't import React, and ReactDOM. You can use a plugin like Bower Webpack Plugin to solve the array problem, but it only imports the first file in the array, and ignores the rest, so React can be imported, but ReactDOM can't.


master branch - Aliasing manually

Aliasing the files by yourself will always work. The main drawback is that you'll need to alias every bower dependency manually.

resolve: {
    alias: {
        "jquery": bower_dir + "/jquery/dist/jquery.js",
        "react": bower_dir + "/react/react.js",
        "react-dom": bower_dir + "/react/react-dom.js" // added alias for react-dom
    }
}

Combine

You can actually combine DirectoryDescriptionFilePlugin resolve, with manual resolve via aliasing. Normal modules, such as jQuery will be resolved in the official way, and multi file modules can be aliased:

resolve: {
    modulesDirectories: ["node_modules", "bower_components"],
    alias: {
        "react": bower_dir + "/react/react.js",
        "react-dom": bower_dir + "/react/react-dom.js"
    }
},
plugins: [
    new webpack.ResolverPlugin(
        new webpack.ResolverPlugin.DirectoryDescriptionFilePlugin(".bower.json", ["main"])
    )
]

This is a problem because the example uses react version 0.10.0, but from version 0.14.0 react is shipped as two packages. In the .bower.json config for the react package, the main property is an array and it seems webpack doesn't like that.

Unfortunately, the following issue outlines that there is no fix as such, but a plugin may work: Resolve main field as array for Bower #4

However, in the depths of that issue I managed to find a way to modify your webpack.config.js , where line 22 can be changed from:

...DirectoryDescriptionFilePlugin(".bower.json", ["main"])

to:

...DirectoryDescriptionFilePlugin(".bower.json", ["main", ["main", 0]])

which will then resolve both a string main and an array main , but only the first component. I don't know if it's possible to loop over all array entries with that Plugin, but it's slightly easier than writing your own. You can't add extra resolvers to the array (for example to resolve the react-dom):

...DirectoryDescriptionFilePlugin(".bower.json", ["main", ["main", 0], ["main", 1]])

So if you need the react-dom package, then you may need to find another way to do it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM