Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't find modules required in React

I was going through the React codebase, and I noticed how React's require doesn't quite behave like in Nodejs. I don't get what's going on here.

Looking at line 19 on ReactClass.js for instance, there's a require('emptyObject'), but emptyObject isn't listed in package.json, nor does it say anywhere where that module's coming from.

https://github.com/facebook/react/blob/master/src/isomorphic/classic/class/ReactClass.js#L19

I did find "emptyObject" on npmjs, but the API there seems different from the one used in React; the .isEmpty grepped in React isn't related to emptyObject.

So where is emptyObject getting loaded from, and how is React's require doing what it's doing? This is not intuitive. At all.

like image 580
omul Avatar asked Nov 01 '16 02:11

omul


People also ask

Can not find module node?

To fix the Cannot find module error, simply install the missing modules using npm . This will install the project's dependencies into your project so that you can use them. Sometimes, this might still not resolve it for you. In this case, you'll want to just delete your node_modules folder and lock file ( package-lock.

Can not find module index JS?

If you are getting the "Cannot find module" error when trying to run a local file, make sure that the path you passed to the node command points to a file that exists. For example, if you run node src/index. js , make sure that the path src/index. js points to an existing file.

How fix npm module not found?

If you have run the npm install command before, then it's possible that the installation of the module is incomplete or corrupted. Delete the node_modules/ folder using the rm -rf node_modules command, then run npm install again. That may fix the issue.


2 Answers

The location of the emptyObject module which React refers to is https://github.com/facebook/fbjs/blob/master/packages/fbjs/src/core/emptyObject.js#L9 Note that it doesn't follow the CommonJS module system.

To make it easier for Facebook to share and consume our own JavaScript. Primarily this will allow us to ship code without worrying too much about where it lives, keeping with the spirit of @providesModule but working in the broader JavaScript ecosystem.

From https://github.com/facebook/fbjs#purpose

The way of defining a module by adding @providesModule in the license header and loading those modules with require in Node is called Haste, a customized module system built for Facebook's open source projects.

In fact, unless you would like to understand the inner workings of React or contribute to Facebook's open source projects, you don't need to know that. In other words, it's not recommended to use Haste to write your own project.

Along the same lines, the invariant module being loaded at line 10 of ReactClass.js is declared at https://github.com/facebook/fbjs/blob/master/packages/fbjs/src/__forks__/invariant.js#L9

As far as I know, both Eclipse and WebStorm don't support Haste so IDE can't help. But with Haste, the name of file and module should be the same, so you can find a module by searching for the filename, i.e. double shift in Webstorm and Ctrl+Shift+r in Eclipse. However, the emptyObject you asked about or invariant are not part of React so it's still cumbersome to find their origin.

Otherwise, there is a team that shares and organizes what they learn from hacking React that I contribute to occasionally and they have linked those requires by following Haste to the corresponding origin file e.g. https://annot.io/github.com/facebook/react/blob/cc3dc21/src/isomorphic/classic/class/ReactClass.js?l=19 You may want to see that.

like image 104
Donghwan Kim Avatar answered Oct 04 '22 11:10

Donghwan Kim


I noticed how React's require doesn't quite behave like in Nodejs.

Right. Facebook has its own module loader. All modules have unique identifiers, provided by the @providesModule directive in each module. This allows you to use the identifier to load the module, instead of the file path.

Of course that doesn't work in a Node.js based environment. So when React or any other Facebook project is published to npm, all require calls are rewritten automatically to something that Node understands.

This functionality is provided by fbjs which contains shared dependencies and build helpers for all Facebook projects. This is where you find the emptyObject module.

If you look at React's gulp file, you can see how the module maps are constructed and that a custom Babel plugin is used to convert all require calls.

like image 22
Felix Kling Avatar answered Oct 04 '22 13:10

Felix Kling