Comments (12)
This can't be completely pushed onto Babel since it needs to work across transforms (html, css, etc).
I'm also not a fan of doing this for long paths, but it is important for mapping things like "react" to "preact". In which case you do want it to operate across module boundaries.
I think we might be able to scope this to packages, but for cases like Preact you'd have one of three options:
- Aliases in
package.json
andnode_modules/.../package.json
apply to all dependencies - this seems like the best option to me but de-duping could prevent it from working. - Aliases in
package.json
apply to all dependencies, but aliases innode_modules/.../package.json
only applies to it's own source - this seems like the next best option - Special configuration for applying an alias globally - this seems like the easiest to explain.
it'd have to include their children for those cases like Preact.
I can imagine something inside of package.json
like:
{
"name": "my-project",
"alias": {
"react": "preact"
}
}
from parcel.
So I take it that your usecase is to avoid typing long relative paths everywhere? In general I'm not a huge fan of doing this as it makes it much harder to reason about where the code you read in a project is coming from. I'd rather stick with the standard Node module resolution algorithm and avoid having each project define its own strategy.
If we did something here, I'd want the aliases to be scoped to a particular module. For example, the aliases in the top-level project shouldn't apply within node_modules, and aliases defined within node_modules shouldn't apply to other node_modules.
I'm open to proposals for how to implement this, but I can't guarantee that it's something I'll want to support. For JS, the above babel plugin might work OK for now.
from parcel.
You can do this with babel.
https://github.com/tleunen/babel-plugin-module-resolver
from parcel.
I've tried using babel-plugin-module-resolver
, but it seems to have no effect on Parcel. It works with webpack, but the same config does not work with Parcel, nor any kind of config permutation I could think of.
babelrc plugins config that works with webpack:
[
"module-resolver",
{
"alias": {
"ps": "./src"
}
}
]
]
Error in parcel
kelly@interconcernedcat:~/src/product-store/src (km/babel-alias *)$ parcel app.js
⏳ Building...
Server running at http://localhost:1234
🚨 /Users/kelly/src/product-store/src/app.js:6:18: Cannot resolve dependency 'ps/store'
4 | import { IntlProvider } from 'react-intl'
5 | import routes from 'ps/routes'
> 6 | import store from 'ps/store'
| ^
7 | import { getLocale, messages } from 'ps/lib/locale'
8 |
9 | export default class App extends Component {
It would be useful to know where parcel is looking when resolving them module, webpack outputs this for debugging. Looks like it uses enhanced-resolve
which outputs the error.
Example webpack resolution error:
at resolver.doResolve.createInnerCallback (/Users/kelly/src/product-store/node_modules/enhanced-resolve/lib/DescriptionFilePlugin.js:44:6)
resolve '../routes' in '/Users/kelly/src/product-store/src'
using description file: /Users/kelly/src/product-store/package.json (relative path: ./src)
Field 'browser' doesn't contain a valid alias configuration
after using description file: /Users/kelly/src/product-store/package.json (relative path: ./src)
using description file: /Users/kelly/src/product-store/package.json (relative path: ./routes)
as directory
/Users/kelly/src/product-store/routes doesn't exist
no extension
Field 'browser' doesn't contain a valid alias configuration
/Users/kelly/src/product-store/routes doesn't exist
.js
Field 'browser' doesn't contain a valid alias configuration
/Users/kelly/src/product-store/routes.js doesn't exist
.json
Field 'browser' doesn't contain a valid alias configuration
/Users/kelly/src/product-store/routes.json doesn't exist
error Command failed with exit code 1.
from parcel.
As a note, I am very into what I think is unpopular idea, which is to allow setting the effective root of a project. Sort of like a chroot, so you could do:
# somewhere.json
{
"root": "./src"
}
// file.js
import dogs from '/lists/dogs'
and that would get it from ./src/lists/dogs
.
This gets around the problem of code that can stop working when a module is installed with the common NODE_PATH
, babel-plugin-module-resolver
and webpack approach1.
I think it also gets around the problem of reasoning about where the code you are reading is coming from. It means that a user who has configured this can no longer require a file in their project using an absolute path. I've never seen this done, and it seems a worthwhile trade-off.
Footnote
By this i mean, if you've configured `plugins.module-resolver.root` to `'./src'`, and you haveimport Dog from "components/dog"
and then you npm install
a package that depends on a package called components, your Dog stops working!
from parcel.
I started by just attempting to do a "quick switch" from webpack to parcel to see how easy it would be and what results would be produced on a medium to large sized project. The alias issue was the first hurdle. As I started resolving those issues I came across a number of individual gotchas and bumps.
- When processing files, if you accidentally have an empty sass file in one of your directories you will get a error that looks something like this:
.../styles.scss:undefined:undefined: No input specified: provide a file name or a source string to process
Solution: Delete empty file
- Throughout resolving the aliases I had to continuously restart parcel because I was getting errors that looked like this:
Cannot read property 'js' of null at Bundler.createBundleTree (/Users/username/.config/yarn/global/node_modules/parcel-bundler/lib/Bundler.js:434:24)
Solution: Restart parcel
- Once the aliases were resolved I started getting errors about libraries I included:
/Users/username/.../node_modules/react-table/lib/index.js: Couldn't find preset "stage-2" relative to directory "/Users/username/.../node_modules/react-table"
Solution:
npm install --save-dev babel-preset-stage-2
and add to .babelrcpresets: [ "stage-2" ]
from parcel.
Yeah the react -> preact
case is pretty compelling. definitely need to support that.
In fact, parcel already supports a super basic version of that in the form of the browser
field in package.json
, which is also supported by browserify https://github.com/defunctzombie/package-browser-field-spec. However, this does only apply to the current package (e.g. not outside the current node_module).
Can someone write up a proposal for how this should work in detail? Basically, I think it should work the same way as browser
but apply globally, and only for the root package.json
(e.g. not inside node_modules
). I think if any package in node_modules
could affect aliases globally, there would be chaos. This is basically @thejameskyle's option #2.
Whether alias
should work at all for node_modules
or only the root package is still up for debate I think. If we want it to work, then it should work identically to browser
(i.e. only apply within the current package). If not, then there is always browser
which is already supported across bundlers.
from parcel.
from @shawwn, cc @sompylasar
Yep, resolve aliases are WIP. I have the heavy lifting done locally. All
the FS calls are trapped in a central filesystem object stored in Parser,
and you can even set Parcel to output files to an instance ofmemory-fs
to spit out files in memory instead of save them to disk.Suffice to say, require("~foo/bar") won't be a problem.
Still undecided whether to use ~ or just stick with / as the relative
root... Also, how to specify where the relative root should begin? What if
parcel's working directory is something other than project root? We can't
walk upwards looking for package.json, nor can we assume a .git folder
marks the top of the project.
from parcel.
@devongovett the main point it's a way to refer to "srcDir" and "rootDir" like in nuxt, of course it's a bad pattern creating an alias for every folder, but it's awful referencing files using ../../xxx.js
.
You can just enforce a standard like nuxt or allow alias, but for a "zero config", the idea of just the default: ~: srcDir
and ~~: rootDir
, when srcDir is basically a src/lib/app folder if it exists else srcDir reference rootDir, perhaps use ~
as rootDir, like in linux, when we use ~ as home folder and @
as srcDir
@chee idea as a problem, if a package it's on node_modules and on root what exacly happens?
from parcel.
Basically, I think it should work the same way as browser but apply globally, and only for the root package.json (e.g. not inside node_modules). I think if any package in node_modules could affect aliases globally, there would be chaos.
Why not leave it just as package.json#browser
for local stuff, and have an aliases
field which is only applied from the root?
from parcel.
I'm going to lock this because this issue is to discuss adding aliases to Parcel, not for people to figure out how to get it done today
from parcel.
See #850 for an implementation of aliases as discussed above. Please comment there if you have any feedback.
from parcel.
Related Issues (20)
- Cannot import css from mantine-datatable HOT 3
- postcss fails: @parcel/transformer-postcss: Cannot read properties of undefined HOT 1
- @parcel/register throws error `parcel[_core(...).INTERNAL_RESOLVE] is not a function`
- Parcel build fails on Chrome < 86 due to dynamic import and chunking issues HOT 1
- Unable to make `typeof process !== 'undefined'` false
- Parcel Macro in the REPL HOT 1
- segfault on parcel >= 2.10.0
- `parcel/config-webextension` can build extensions incompatible with Firefox's Add-Ons Store HOT 1
- Type-introspection with macros
- Vue 3 defineProps fail with imported types
- TypeScript syntax does not work in Vue templates
- I can't modified the HTML, cause every single time parcel brokes HOT 2
- Parcel build/watch silently fails HOT 1
- @parcel/transformer-css: Unexpected token Semicolon HOT 2
- Default Cache folder location is on root instead of workspace folder HOT 2
- Creating dynamic aliases. HOT 11
- https://github.com/parcel-bundler/parcel/commit/05604990d7531e5bd348abbc435b3dc5d49ad7fd breaks Typescript compilation HOT 1
- Parcel encountered error HOT 3
- There is typescript error in production build.
- parcel start works but not parcel build HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from parcel.