You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Document src/node_modules as official solution for absolute imports #1065
This is a very interesting idea! I'm wondering though if it'd make more sense to support a top-level packages directory (exactly like lerna) and symlink that to src/node_modules. This binding could exist for all create-react-apps.
The reasoning for this is that typically your external modules are general purpose and not application-specific (therefore not desirable in the application source directory), and to support something like lerna. Maybe you want to do code splitting via npm packages? This would allow you to support lerna and create-react-app in the same project.
For selfish reasons, this would allow me to use create-react-app to kitchen sink/playground a bunch of lerna components.
what's the issue with cross-env NODE_PATH=./src react-scripts start ? I think it's cleaner and more clear rather than having a node_modules inside src folder.
Most people don't know about cross-env so they just write commands that don't work on Windows. This hurts open-source examples (e.g. people can't run a React example because of its reliance on Bash environment variable syntax). NODE_PATH is also considered legacy and slightly discouraged so it doesn’t feel right to promote this as a solution. Just using src as the root can also be a bit surprising, and the explicitness of node_modules has some benefits (e.g. you know for sure they’ll have priority over regular node_modules).
Ultimately I just want both ways to work, and we can document them. People can then choose whichever way they prefer.
Reacted by Ade Viankakrisna Fadlil, Veniamin Krol, Ivan Babak, Doug Day, Tomasz Cichocinski, Huy Giang, Joe, Ardy Kamdani and Ben Carp
I personally like the idea of a src/node_modules, just because it's absolutely free of hacks.
But right now there's some problems with linters:
eslint by default ignores /node_modules (that is not so bad running the command in the project directory and ignoring vendor's node_modules, but would ignore all code if running in src/).
If we place .css files or similar along with components inside src/node_modules, stylelint ignores with hardcode **/node_modules/** (that would ignore every file always).
Reacted by Sean Matheson, Jimmy Miller, Rossen K, Jan Potoms, Connor Elsea, Ivan Babak, Jason Axelson, Rafa Yepes, Ardy Kamdani, Enrique Juan de Dios and 1 more
As project's readme states — they just use watchman to watch for certain dirs and copy files to node_modules subfolders. We've added some additional scripts to automate bootstrapping but it turned out to work really smooth.
Sure it's not an ideal solution but it seems to work really nice and does not force you to follow any conventions so it's easily can be applied to any project.
I've created a link src/node_modules to src/common and this allows me to import a component using import Rating from 'components/Rating' (components is a folder in common).
However, when I run my tests, jest gives me the following error:
Test suite failed to run
SyntaxError: Unexpected reserved word
on the line where I am doing that import.
Is there something I need to add to my jest config to make this work properly?
If I understand correctly, the only reason we are not using NODE_PATH env by default is because it would conflict with node_modules. But it's much cleaner than adding node_modules in src and configuring jest to ignore node_modules inside src.Instead, we could use NODE_PATH=src by default with cross environment support and document it properly that the modules in src have preference over node_modules.
Further, we could enforce the direct folders or files inside src be in PascalCase and as npm doesn't allow package names to start with capital letters,
importReactfrom'React'
won't conflict with the react in node_modules and the user will know that it is an absolute import from src.
For the absolute import, beside of packages approach which is good pattern to split code into packages, why not simply put the src as the first one for webpack resolve.modules?
for code in src/routes/jobs/details/actions to import something from src/routes/jobs/actions, it still needs to use ../../actions to relative import. This is simple case, with nest structure getting deeper, it will be something like ../../../../actions which is hard to read what is imported. With src as root resolved, it is crystal to say import from src/routes/jobs/actions
And with packages approach, even routes is package under packages folder, this long back path relative import is still inevitable.
=============== UDATE: ===============
Find it is simple to add NODE_PATH=src in .env file so that webpack modules.resolve will have src. even better to add NODE_PATH=src:packages, then no npm link need for packages in packages folder
For me using node_modules inside src is not beeing a option because jest is crashing. Very annoying.
So my solution was using NODE_PATH=src in my package.json and in WebStorm/Intellij I simply did:
Right click on src folder -> Mark Directory as -> Sources Root
Voi lá! Everything is working fine! (go to files, open classes, moving files to another directory automatically change the references)
A note about NODE_PATH is that in the current docs (Node 8.1.2) is not saying that NODE_PATH is legacy or will be deprecated but that it is not used as it was used before:
NODE_PATH is still supported, but is less necessary now that the Node.js ecosystem has settled on a convention for locating dependent modules. Sometimes deployments that rely on NODE_PATH show surprising behavior when people are unaware that NODE_PATH must be set. Sometimes a module's dependencies change, causing a different version (or even a different module) to be loaded as the NODE_PATH is searched.
the docs quote above convinces me that it's not deprecated, contrary to what OP has implied.
I'm a 'new' developer myself and I feel like this node_modules solution will be confusing or seem strange to some. the alternative of using NODE_PATH seems like the better way.
NODE_PATH require an extra dependency to be cross-platform, tools has to specify the extra variable, and it works here only because it's the toplevel (as the react app isn't a module that can be imported in another module), otherwise it would introduce extra complexity there too.
But pick whatever you prefer: I'm not fond of /src/node_modules either, just is the most pragmatic in the end given the way Node is at the moment.
I tried playing around with using this approach in my project and I noticed react-scripts start wasn't picking up changes inside src/node_modules because it was ignoring node_modules. I opened #2760 to update the dev server config to play nicely with src/node_modules.
For absolute imports, it seems like it'd be a lot better to have some kind of special prefix and set up webpack's alias functionality for it. For example, my personal projects use:
It keeps a clear distinction from npm-tracked node_modules, avoiding the "I can't get it to work and I don't understand why" potential of having overlapping names or having imports start with just ./.
Reacted by Adrian, Ernesto García, Silvère Lestang, Maayan Glikser, Jeff Baumgardt, Leonardo Ascione, Denis Orlov, Alex Streed, Raman Gupta, Callum and 3 more
Sorry to resurrect an old issue, though with #1333 being not quite ready, is src/node_modules a viable option for people to wanting aboslute imports @gaearon? I like the idea that it relies on Node resolution mechanism, but wasn't sure if this approach was discouraged.
Activity
fadeojo commentedon Nov 21, 2016
I want to help but I will need someone to shadow.
gaearon commentedon Nov 21, 2016
Feel free to jump on either of those issues and let me know if you need any help!
tbranyen commentedon Nov 21, 2016
This is a very interesting idea! I'm wondering though if it'd make more sense to support a top-level packages directory (exactly like lerna) and symlink that to
src/node_modules. This binding could exist for all create-react-apps.The reasoning for this is that typically your external modules are general purpose and not application-specific (therefore not desirable in the application source directory), and to support something like lerna. Maybe you want to do code splitting via npm packages? This would allow you to support lerna and create-react-app in the same project.
For selfish reasons, this would allow me to use create-react-app to kitchen sink/playground a bunch of lerna components.
viankakrisna commentedon Nov 23, 2016
what's the issue with
cross-env NODE_PATH=./src react-scripts start? I think it's cleaner and more clear rather than having a node_modules inside src folder.gaearon commentedon Nov 23, 2016
Most people don't know about
cross-envso they just write commands that don't work on Windows. This hurts open-source examples (e.g. people can't run a React example because of its reliance on Bash environment variable syntax).NODE_PATHis also considered legacy and slightly discouraged so it doesn’t feel right to promote this as a solution. Just usingsrcas the root can also be a bit surprising, and the explicitness ofnode_moduleshas some benefits (e.g. you know for sure they’ll have priority over regularnode_modules).Ultimately I just want both ways to work, and we can document them. People can then choose whichever way they prefer.
gaearon commentedon Nov 23, 2016
I believe this is what I suggested in the opening comment (but only as opt-in):
It has to be opt-in though, please read the discussion about Windows issues in #741.
daltones commentedon Nov 25, 2016
I personally like the idea of a
src/node_modules, just because it's absolutely free of hacks.But right now there's some problems with linters:
/node_modules(that is not so bad running the command in the project directory and ignoring vendor'snode_modules, but would ignore all code if running insrc/).node_modulesfolder (see Consider that somenode_modulesfolders aren't vendor import-js/eslint-plugin-import#677).cssfiles or similar along with components insidesrc/node_modules, stylelint ignores with hardcode**/node_modules/**(that would ignore every file always).kompot commentedon Nov 29, 2016
Another way of managing absolute paths that might have come up but could not find it in
#741
We've been using wix's wml
https://github.com/wix/wml
to get any required project structure with:
As project's readme states — they just use
watchmanto watch for certain dirs and copy files tonode_modulessubfolders. We've added some additional scripts to automate bootstrapping but it turned out to work really smooth.Sure it's not an ideal solution but it seems to work really nice and does not force you to follow any conventions so it's easily can be applied to any project.
What do you think?
AdamTyler commentedon Dec 1, 2016
I've created a link
src/node_modulestosrc/commonand this allows me to import a component usingimport Rating from 'components/Rating'(components is a folder in common).However, when I run my tests, jest gives me the following error:
on the line where I am doing that import.
Is there something I need to add to my jest config to make this work properly?
gaearon commentedon Dec 1, 2016
@AdamTyler
Please see the first post in this thread 😉
15 remaining items
Janpot commentedon May 14, 2017
@viankakrisna Indeed, sort of the
create-react-appequivalent of thatnwbfeature I guess.sidoshi commentedon May 20, 2017
If I understand correctly, the only reason we are not using
NODE_PATHenv by default is because it would conflict with node_modules. But it's much cleaner than adding node_modules insrcand configuringjestto ignorenode_modulesinsidesrc.Instead, we could useNODE_PATH=srcby default with cross environment support and document it properly that the modules insrchave preference overnode_modules.Further, we could enforce the direct folders or files inside
srcbe in PascalCase and as npm doesn't allow package names to start with capital letters,won't conflict with the
reactin node_modules and the user will know that it is an absolute import fromsrc.tbranyen commentedon May 20, 2017
@doshisid Wouldn't that only work in case sensitive filesystems? If so, 👎
sidoshi commentedon May 20, 2017
We could find a common case for all filesystems and enforce that. Like maybe prefixing with _
shendepu commentedon Jun 15, 2017
For the absolute import, beside of
packagesapproach which is good pattern to split code into packages, why not simply put thesrcas the first one for webpackresolve.modules?In the fractal project structure
for code in
src/routes/jobs/details/actionsto import something fromsrc/routes/jobs/actions, it still needs to use../../actionsto relative import. This is simple case, with nest structure getting deeper, it will be something like../../../../actionswhich is hard to read what is imported. Withsrcas root resolved, it is crystal to say import fromsrc/routes/jobs/actionsAnd with
packagesapproach, evenroutesis package underpackagesfolder, this long back path relative import is still inevitable.=============== UDATE: ===============
Find it is simple to add
NODE_PATH=srcin .env file so that webpackmodules.resolvewill have src. even better to addNODE_PATH=src:packages, then no npm link need for packages inpackagesfolderDanilo-Araujo-Silva commentedon Jun 27, 2017
For me using node_modules inside src is not beeing a option because jest is crashing. Very annoying.
So my solution was using NODE_PATH=src in my package.json and in WebStorm/Intellij I simply did:
Right click on src folder -> Mark Directory as -> Sources Root
Voi lá! Everything is working fine! (go to files, open classes, moving files to another directory automatically change the references)
A note about NODE_PATH is that in the current docs (Node 8.1.2) is not saying that NODE_PATH is legacy or will be deprecated but that it is not used as it was used before:
nazreen commentedon Jul 1, 2017
the docs quote above convinces me that it's not deprecated, contrary to what OP has implied.
I'm a 'new' developer myself and I feel like this node_modules solution will be confusing or seem strange to some. the alternative of using NODE_PATH seems like the better way.
cecilemuller commentedon Jul 1, 2017
NODE_PATH require an extra dependency to be cross-platform, tools has to specify the extra variable, and it works here only because it's the toplevel (as the react app isn't a module that can be imported in another module), otherwise it would introduce extra complexity there too.
But pick whatever you prefer: I'm not fond of /src/node_modules either, just is the most pragmatic in the end given the way Node is at the moment.
bmac commentedon Jul 10, 2017
I tried playing around with using this approach in my project and I noticed
react-scripts startwasn't picking up changes insidesrc/node_modulesbecause it was ignoringnode_modules. I opened #2760 to update the dev server config to play nicely withsrc/node_modules.icopp commentedon Sep 22, 2017
For absolute imports, it seems like it'd be a lot better to have some kind of special prefix and set up webpack's alias functionality for it. For example, my personal projects use:
...after which you can reference files via...
You can also inject the same schema into Jest:
It keeps a clear distinction from npm-tracked
node_modules, avoiding the "I can't get it to work and I don't understand why" potential of having overlapping names or having imports start with just./.Fix absolute imports.
gaearon commentedon Jan 8, 2018
Closing in favor of #1333.
src/node_modulesis too weird to most people and not very ergonomic.There's been a few underlying issues with Jest which have been fixed so we can take another shot at this.
bjankord commentedon Oct 1, 2018
Sorry to resurrect an old issue, though with #1333 being not quite ready, is
src/node_modulesa viable option for people to wanting aboslute imports @gaearon? I like the idea that it relies on Node resolution mechanism, but wasn't sure if this approach was discouraged.