Giter VIP home page Giter VIP logo

Comments (12)

jamiebuilds avatar jamiebuilds commented on May 2, 2024 22

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:

  1. Aliases in package.json and node_modules/.../package.json apply to all dependencies - this seems like the best option to me but de-duping could prevent it from working.
  2. Aliases in package.json apply to all dependencies, but aliases in node_modules/.../package.json only applies to it's own source - this seems like the next best option
  3. 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.

devongovett avatar devongovett commented on May 2, 2024 15

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.

drewhamlett avatar drewhamlett commented on May 2, 2024 11

You can do this with babel.

https://github.com/tleunen/babel-plugin-module-resolver

from parcel.

kmiyashiro avatar kmiyashiro commented on May 2, 2024 9

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.

chee avatar chee commented on May 2, 2024 7

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 have
import Dog from "components/dog"

and then you npm install a package that depends on a package called components, your Dog stops working!

from parcel.

epitaphmike avatar epitaphmike commented on May 2, 2024 5

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.

  1. 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

  1. 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

  1. 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 .babelrc presets: [ "stage-2" ]

from parcel.

devongovett avatar devongovett commented on May 2, 2024 2

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.

devongovett avatar devongovett commented on May 2, 2024 2

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 of memory-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.

EduardoRFS avatar EduardoRFS commented on May 2, 2024

@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.

jamiebuilds avatar jamiebuilds commented on May 2, 2024

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.

jamiebuilds avatar jamiebuilds commented on May 2, 2024

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.

devongovett avatar devongovett commented on May 2, 2024

See #850 for an implementation of aliases as discussed above. Please comment there if you have any feedback.

from parcel.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.