meteor / meteor-feature-requests

A tracker for Meteor issues that are requests for new functionality, not bugs.
Other
89 stars 3 forks source link

aliases and npm build #353

Open CaptainN opened 5 years ago

CaptainN commented 5 years ago

I'd like to be able to fiddle with npm packages a bit more than we currently are able to. Specifically, to be able to simply set an alias, and also configure meteor to compile an npm package in some cases to get the modern bundle advantages.

What I'd like to see is an expansion to the package.json meteor area to accomplish this. Something like:

{
  "name": "My Wonderfull App",
  ...
  "meteor": {
    "mainModule": {
      "web.browser": "client/main.js",
      "server": "server/main.js",
      "legacy": "client/legacy.js"
    },
    "alias": {
      "react-helmet": "react-helmet-async",
      "react": {
        "server": "react",
        "client": "preact"
      },
      "@material-ui/core": {
        "server": "@material-ui/core",
        "web.browser": "@material-ui/core/es",
        "legacy": "@material-ui/core"
      }
    },
    "ecmascriptModules": [
      "@material-ui/core/es"
    ]
  }
}

There is a partial description of how to do package aliasing in #60 but it's too hard to get right. A simple configuration like above would be miles better.

There is also some info about how to configure an npm package to get them compiled by basically moving the package outside of the node_modules directory either directly or by using a symlink (which is problematic on Windows) - which is also a pain for a number of reasons. Having a place to specify individual packages (or import prefixes maybe) should be run through the ecmascript package would be wonderful.

Another useful "alias" feature would be the ability to alias a location on disk. In a couple of cases, I have created a local package just to get a single import location for differing modules server/client (in one case to deliver either Ground:DB or Mongo directly, and avoid Ground:DB from being included in the server bundle, and in the other to make sure domjs is included in the server, but does not bloat the client bundle). This works well, but using an alias in the package.json configuration area would have been even easier.

CaptainN commented 5 years ago

Actually, I made an error in the example above. It uses a sub package "@material-ui/core/es" which I assume would be harder to white-list for compilation. In the case of "@material-ui/core" it should be find to alias the whole thing, or even forget aliasing, and tell the compiler to always compile that package (even precompiled stuff) then simply be disciplined about always importing from the /es sub-directory. That's no idea. but it would achieve the same at a package level.

CaptainN commented 5 years ago

I wonder if an easier way to get modern builds from npm packages would be to add an import prefix. We already have "meteor/atmosphere:package" - how hard to add "modern/@material-ui/core/es"? Basically, if it starts with "modern/" we send it to ecmascript package.

Ah, but the downside of this is that if a third-party package uses the normal import, it'll still use the precompiled assets - which would be worse, because now we'd have two copies.. We need the alias feature first.

sakulstra commented 5 years ago

Not sure if that helps but aliases are a feature in npm 6.9 https://github.com/npm/rfcs/blob/latest/implemented/0001-package-aliases.md

CaptainN commented 4 years ago

@sakulstra That's pretty neat, but it has a similar problem that other alias tricks have, which is that it only works in the current project, and not for other packages which pull in the same package.

trusktr commented 4 years ago

Continuing from https://github.com/meteor/meteor/issues/10661:

A feature like this would be great. What about something more like

{
  // ...
  "meteor": {
    "nodeModules": {
      "some-package": {
        "recompile": true, // ("compile" would sound better, by the way)
        "srcRoot": "dist/modules/"
      }
    }
  }
}

And for backwards compatibility with the current design, the following

{
  // ...
  "meteor": {
    "nodeModules": {
      "some-package": true
    }
  }
}

would default to srcRoot of some-package being the root of the package.

trusktr commented 4 years ago

For the differing aliases for different builds, I don't see why we would need to do that, but following my previous pattern, it could be:

{
  // ...
  "meteor": {
    "nodeModules": {
      "some-package": {
        "recompile": true, // ("compile" would sound better, by the way)
        "srcRoot": {
          "server": "src/",
          "web.browser": "dist/modules",
          "legacy": "src"
        }
      }
    }
  }
}

Why might we want different aliases for different build targets? Seems like Meteor compile steps already handle the build for those targets. What may aliasing for build targets achieve?