Skip to content
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

🙋 Support project-relative import paths #336

Closed
rondonjon opened this issue Dec 18, 2017 · 18 comments · Fixed by #850
Closed

🙋 Support project-relative import paths #336

rondonjon opened this issue Dec 18, 2017 · 18 comments · Fixed by #850

Comments

@rondonjon
Copy link

rondonjon commented Dec 18, 2017

Projects with a deep folder structure often have import paths with lots of "../../../../../a/b/c/d/actualFile.js" in them because import paths are kind of restricted.

One workaround in webpack is to define custom aliases for the resolver, but this approach would break the zero-configuration approach of parcel.

Would it be possible to have at least an additional notation for "project-relative" imports in parcel, so that the dotdot madness at the beginning could be stopped?

🎛 Configuration (.babelrc, package.json, cli command)

N/A

😯 Current Behavior

Apparently (??) no support for project-relative import paths.

💁 Possible Solution

  • Resolve './abc' relatibe to the current file (as is)
  • Resolve '/abc' absolute to filesystem (or webroot? as is)
  • Resolve 'x/abc' relative to module 'x' (as is)
  • Resolve '-/abc' or '.../abc' or similar relative to current or nearest parent folder with a package.json file in it (package root)
@davidnagli
Copy link
Contributor

Hmm I actually really like this idea! 😮 😃 👏

This would be supper useful

@davidnagli
Copy link
Contributor

Resolve ‘-/abc’ or '.../abc' or similar relative to current or nearest parent folder with a package.json file in it (package root)

Not sure about the syntax for package root though…

  • I don’t really like like -/abc since - looks a lot like ~ (maybe this was intentional, but it could make the difference hard to spot)
  • …/abc wouldn’t work either since it kinda implies “go back 3 directories”, or at least it does for anyone using ZSH as their terminal 0_O

I propose using @ to represent “package root”:

@/abc

As far as I know the “@“ simple doesn’t have any reserved meaning in file paths (@brandon93s maybe it does on Windows?).

If not we could also use #:

#/abc

@brandon93s
Copy link
Contributor

@ is good to go on Windows. This seems to be widely accepted as the "package root" character, especially among webpack users which would ease adoption.

@davidnagli davidnagli added this to Discussion in RFC via automation Dec 19, 2017
@davidnagli davidnagli moved this from Discussion to Design in RFC Dec 19, 2017
@psimoneau22
Copy link

psimoneau22 commented Dec 19, 2017

I believe react-native(or one of the tools for it)allows you to define a package.json in any folder. The 'name' property defined in that json file can then be used as an alias for the folder, as if it was in node_modules, just like webpack alias.

For example: in app/someDir2/someDir2, i put a package.json file with name = 'myDep', now 'anywhere' in the folder hierarchy i can simply import ... from 'myDep/someFile', the same way webpack alias works.

https://medium.com/@davidjwoody/how-to-use-absolute-paths-in-react-native-6b06ae3f65d1

@rondonjon
Copy link
Author

rondonjon commented Dec 19, 2017

Please remember that @ is also a namespace indicator for scopes npm packages, so under no circumstances should a leading @ alone be treated as a reference to the package home; @/ should work though.

Another option that I've sometimes stumbled upon is ~.

@shawwn
Copy link
Contributor

shawwn commented Dec 20, 2017 via email

@shawwn
Copy link
Contributor

shawwn commented Dec 21, 2017

Unless anyone has objections, I'm going to add tilde support, like vue-loader. Also I really like the package.json name idea; we might be able to do that.

This relies on some FS changes I've been working on; stay tuned.

@rondonjon
Copy link
Author

@shawwn awesome, many thanks!

@alex-bezek
Copy link

Hello, I wanted to try out parcel with my team's component library and ran into a snag, and i'm wondering if this issue will resolve it.
In our scss file we use the tilde to do an import of a scss file that is a separate package in our node_modules
@import '~terra-mixins';

Based off https://github.com/webpack-contrib/sass-loader#imports

webpack provides an advanced mechanism to resolve files. The sass-loader uses node-sass' custom importer feature to pass all queries to the webpack resolving engine. Thus you can import your Sass modules from node_modules. Just prepend them with a ~ to tell webpack that this is not a relative import:

Based off the conversation, it seems this fix might resolve my issue, just wanted to check.

Thanks!

@devongovett
Copy link
Member

IMO this should only resolve to the project root for files actually in the project. For node_modules, it should resolve to the root of that module. e.g. in node_modules/test/foo/bar.js, ~/baz should resolve to node_modules/test/baz. This way code in node_modules always works the same way regardless of what application it is installed in.

@rondonjon
Copy link
Author

Sure, hence "nearest parent folder" in the initial suggestion.

@devongovett
Copy link
Member

So, we have two different approaches to basically the same problem: how to reference files starting at the root of a module. This issue proposes using tilde (e.g. ~/foo/bar.js), but #86 + #290 uses absolute paths (e.g. /foo/bar.js). Not sure we should support two ways to do the same thing. What do we think? Are there plusses and minuses to each?

@DeMoorJasper
Copy link
Member

DeMoorJasper commented Jan 3, 2018

@devongovett I think "~" would be the easiest one to implement as it will not be used for an actual absolute path inside the resolver for example when trying to implement it in my pull request i kinda hit a wall for the fs resolves as some already include __dirname and are absolute paths.

Also I think we should support absolute paths like /index.html, but solely for html assets, as this is supported by servers/browsers by default

I could change my PR to handle what I just said perfectly pretty easily, and it would probably end up being less code than the current implementation

@raphinesse
Copy link

raphinesse commented Feb 16, 2018

@devongovett @DeMoorJasper I strongly advise against mixing absolute and project relative paths as it is done in the current implementation of #290. This makes the build machine-dependent! Resolving /foo to <PROJECT_ROOT>/foo or /foo depending on the existence of the absolute path is a build debugging nightmare waiting to happen:

  1. Build works
  2. > touch foo
  3. Build broken 😱

IMO, absolute paths should be resolved as exactly that (apart from document-root-relative handling for HTML maybe; I have yet to look into that use case) and paths starting with ~/ should be resolved relative to the closest package containing the importing file.

Other than that, I can't wait for this feature to be released! 😍

@raphinesse
Copy link

raphinesse commented Feb 16, 2018

@shawwn @rondonjon Regarding the question of ~/ vs @/:

  • The official vue.js webpack template uses @
  • @ by itself is not a valid package name (checked by trying to create such a package with npm), so there is no potential for shadowing. I don't know if that is true for ~.
  • Unsuspecting Linux users could mistake ~/ as a reference to their home directory. On the other hand, this syntax could be seen as a kind of home directory metaphor in the context of a package.

That being said, I stand slightly in favor of @/, but ~/ would be perfectly fine for me too ☺️

@devongovett
Copy link
Member

See #850 for an implementation of both absolute and tilde paths, which mean slightly different things. Let me know if you have any feedback!

RFC automation moved this from Design to Done Feb 22, 2018
@uoziod
Copy link

uoziod commented Mar 27, 2018

Is there any way to set root path once in configuration or CLI?
Like in Webpack it is possible via context configuration property.

@fnune
Copy link

fnune commented Jul 1, 2018

For anyone using TypeScript, you're gonna need this to support ~ imports and keep tsserver happy:

In tsconfig.json:

  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "~*": ["./app/*"]
    },

Documentation: https://www.typescriptlang.org/docs/handbook/module-resolution.html in the Path mappings section.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
No open projects
RFC
  
Done