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.
2
Answers
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.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.From https://github.com/facebook/fbjs#purpose
The way of defining a module by adding
@providesModule
in the license header and loading those modules withrequire
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 ofReactClass.js
is declared at https://github.com/facebook/fbjs/blob/master/packages/fbjs/src/__forks__/invariant.js#L9As 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 orinvariant
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
require
s 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.