-
Notifications
You must be signed in to change notification settings - Fork 24.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Packager] Configure the locations from which modules can be imported #3099
Comments
Do systems like Webpack and Browserify support require.paths? I thought Node deprecated that feature awhile ago too and asks for NODE_PATH. It's been a few years since I've looked into this so perhaps things have changed. Generally the packager needs to be able to resolve requires statically so it can produce a bundle. So we could support NODE_PATH or a similar kind of configuration at compile-time but I don't know how we'd support require.paths because client code doesn't have the same capability as server code in this way. |
Couple caveats to consider:
Also, there's a great thread for and against this pattern over at https://gist.github.com/branneman/8048520, which might lend some more insight |
The key thing is that (some of) the configuration needs to happen at compile-time because we need to create a bundle. Another important point to consider is how this will interact with ES6 |
NODE_PATH would be a huge win. I was just looking at webpack myself and saw the resolvers configuration options. Another win. |
Take a look at the ES7+ spec loader, too (System.js will layer on top of it): https://github.com/whatwg/loader |
Excellent. See 10.3.1. node_modules is not in their tbd search path ... FWIW On Monday, September 28, 2015, Ian MacLeod notifications@github.com wrote:
|
http://webpack.github.io/docs/configuration.html#resolve-alias Read on in that link... Read the through the comment thread on that gist linked by @nevir ... Node's require is poorly implemented. No reason to have a bad require for react-native. IMO |
Might be possible to implement an offline version of this: https://github.com/systemjs/systemjs/blob/master/docs/config-api.md#map |
I like it. |
Just a question: would support for symlinks help you out with this problem? I haven't read through all the material linked about different module systems, all I know is that with React Native being based on CommonJS (node) and relying on NPM it'll be quite the change to break from that. While that may or may not be inevitable in the future is not a question I'm looking to answer or claim I have answer to, but perhaps the symlink support is a more short term achievable goal. |
You can use an absolute path on imports/requires: import {ProximaNovaText} from 'MyApp/src/components';
require('MyApp/src/utils/moment-twitter'); where 'MyApp' is whatever name you registered in your |
Well, looks like this has improved slightly in latest versions. As long as your folder added to See my structure with React Native 0.15 below:
packager starts from platform/mobile with ../../core added to roots with a help of const defaultConfig = require('react-native/local-cli/default.config.js');
module.exports {
getProjectRoots() {
const roots = defaultConfig.getProjectRoots();
roots.unshift(path.resolve(__dirname, '../../assets'));
roots.unshift(path.resolve(__dirname, '../../core'));
return roots;
}
}; I can see the paths getting transformed from: require('../../core/redux/reducer.js') to require('@g/core/redux/reducer.js') and require('./index.ios.js') to require('@g/mobile/index.ios.js') which basically means package name from @brentvatne @mkonicek is that how packager works or have I just entered an edge-case that I should not rely on? Something is definitelly in the air since when I set up the same name for
Note Looks like the approach for assets is slightly different: require('../../../../../assets/a.png') is converted to require('/Users/grabbou/project/assets/a.png') However, when you have require('@g/assets/a.png') which is equivalent. |
Hey @mschwartz! Thanks for bringing this issue up. |
The ability to define import paths is an absolutely essential part of any programming environment that "has" even the vaguest notion of "import". Its absence from React Native is a bug-level deficiency. I request reopening this issue. Product Pains looks like a toy; I am unconvinced that it receives any actual attention. |
Have you seen my article on Medium how to define import paths? https://medium.com/@grabbou/a-cure-for-relative-requires-in-react-native-2b263cecf0f6 It works well :) Also Product Pain was working really well recently and we closed one of the most up voted issues - see this for more details https://www.facebook.com/groups/react.native.community/permalink/759574700844777/ |
It doesn't work well for inherited codebase with dozens of files, most of them importing several other files from the same codebase. Your solution would still require rewriting every last one of those 500+ import lines, it would just require rewriting them with something that only depends on the imported module's location and not on the importing module's location. |
@grabbou the problem with this solution is that it breaks intellisense, for example, in visual studio (don't know the rest of gui). Then it cannot find where is the file, which are the properties and worse of it, you cannot jump to class definition with cmd+click |
Ah ok, didn't know. I am mainly using |
Please vote on Product Pains instead, that way we can prioritise the issues. |
A simple solution I found was creating a very minimalistic package.json inside the top-most folder you want to absolutely import from. That package.json should look like this: The you can simply do |
Thanks @dutzi it's not perfect but it works! |
@marcshilling, is that |
Have you tried pasting |
It won't work on tests though :( |
@mmazzarolo Isn't that a Jest issue, though? |
This issue seems relevant. |
@grabbou is this solution working for react-native 0.40? |
I miss the way webpack alias does so much :"( import Navigation from '@components/Navigation'
import navigationReducer from '@reducers/navigation' |
Doesn't this work just as well ? |
Yeah. Babel plugins are generally easier to grok and author. One caveat is that if you change them you need to clear the packager cache but they work well otherwise. |
Unfortunately @dutzi's solution does not seem to work with react-native@0.44.0. Also this post here says it is not allowed to fetch from outside of your React Native Project root. I have followed this medium article and other such sources which suggest similar way. I am running - Folder Structure
packager console:
NOTE- Web application which is in Need help getting things right. |
@yugalbagul did you solve this?? I'm currently getting the similar error and would like to have some help. Thanks. |
@yugalbagul @maotora I haven't found a work-around. |
As of 0.46 I have noticed that trying to import by the name set in |
Thanks @dutzi |
Hi @ALL, here's my way to solve this. This may be a little help. CRNA (create-react-native-app) module resolve & eslint rules check |
I need to give a simple explanation because I've tried many ways to accomplish this simple goal of having a separate folder for my files and make
|
try this: don't forget to reload packager with '--reset-cache' |
Relevant link: The website seems to suggest (as I read it) the package.json approach first, then adjusting NODE_PATH second.
|
require() and import are really important features that deserve some love, IMO.
Forcing us to use relative paths in all our import/require statements is not ideal. It works only ok for the react demos that have a handful of files all in the root. For example, the Movie example in this repo:
The require on line 19 works because you've basically hardcoded require to search node_modules/ where react-native exists.
The require on line 26 forces you to put a ./ on the beginning of the path, and it works, but not ideally as I said.
Consider you want to actually break up this file: https://github.com/facebook/react-native/blob/master/Examples/Movies/SearchScreen.js
One file per component, even if they're private (for now). Reusability is the goal, no?
If you move this file into a directory called "components/", now you have to go and edit the require() statement to reflect the new path.
Things get really ugly if you want to organize your project into a more complex structure. Consider search/component1, search/component2, details/movie1, details/movie2, and so on. Now you're relative paths, if they are sharing code, are ../search/whatever, ../details/whatever. Moving these files around to reorganize your project now means you have to deduce what the new relative paths must be and you have to edit all those files.
I suggest you think about implementing a robust require() implementation. I suggest at least the following features:
require.paths array
This is an array of search paths used by require. It searches the paths in the order of the array. It is allowed by the CommonJS require specification.
Example:
Now you can simply require('component1) ANYWHERE in your source code and search/component1 will be used. You can move your files around without having to edit your require() statements in every one. Just change the require.paths.
Support directories
If you require('foo') and foo is a directory, you should:
Benefits
If you implement these changes, people will be easily able to share components via mechanisms other than npm. You will easily be able to copy components from one project to another without having to refactor the require() statements in each.
Please consider this.
The text was updated successfully, but these errors were encountered: