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

Dependency updates and package-lock #1164

Open
matthewp opened this issue Dec 28, 2018 · 6 comments
Open

Dependency updates and package-lock #1164

matthewp opened this issue Dec 28, 2018 · 6 comments
Labels

Comments

@matthewp
Copy link
Contributor

matthewp commented Dec 28, 2018

DoneJS 3 apps have a problem where an update to any canjs package can result in multiple versions of certain packages when using package-lock (or even in newly generated apps).

The cause is that because can has pinned versions, but other donejs projects such as done-autorender and done-component do not, those packages might load a newer version of can-stache, but can itself depends on an older version.

Solutions

These are the possible solutions I can think of

Move all can-dependant packages into can

Any package that uses can, such as done-autorender and done-component could become a dependency of canjs. Then the user would not use any can package except through can.

Problems

  • If the user uses any 3rd party can package the problem can still occur (although it's unlikely, this problem relies on the newer versions to be loaded before can itself loads).
  • done-autorender is used by the end user through the index.stache!done-autorender main. To work around this we'd need a can/done-autorender or something.
  • Tight coupling is never fun.

Create a can5 package

This idea is to create a package that uses the latest versions of packages. This prevents the multiple versions problem because any compatible version would be included.

We'd likely want to do this as a part of the build of can somehow.

Then in donejs we'd create a steal map of "can": "can5" so that users could write import { Component } from "can";.

Create a local can.js

Another option is to go back to depending on individual packages and having a local can.js that contains all of the exports.

It should probably only be core and a few other select things (like can-stache-route-helpers) that are steal related.

This is likely the easiest solution.

@matthewp matthewp added the bug label Dec 28, 2018
@matthewp
Copy link
Contributor Author

Downside to the can.js option is that some people already have projects using can. How do we migrate those?

@chasenlehara
Copy link
Member

I think the “easiest” solution might be the best one. It’s what we recommend in our setup guide anyway, and I feel like the idea is somewhat validated in that it’s what’s being recommended in Ryan Dahl’s Deno project:

The solution is to import and re-export your external libraries in a central package.ts file (which serves the same purpose as Node's package.json file). For example, let's say you were using the above testing library across a large project. Rather than importing "https://deno.land/x/testing/testing.ts" everywhere, you could create a package.ts file the exports the third-party code:

export { test, assertEqual } from "https://deno.land/x/testing/testing.ts";

And throughout project one can import from the package.ts and avoid having many references to the same URL:

import { test, assertEqual } from "./package.ts";

From https://github.com/denoland/deno/blob/master/Docs.md#linking-to-third-party-code

@matthewp
Copy link
Contributor Author

A local can.js doesn't help people who already switched to can 5 though. :-(

@matthewp
Copy link
Contributor Author

I'm a little torn on this. More and more it feels to me like can pinning versions is just the wrong choice. It will break any time a user uses an external package that loads before can. For example this could easily break:

import "bit-tabs/unstyled";
import { Component } from "can";

Component.extend({
  tag: "my-app",
  view: `
    <bit-tabs>
      <bit-panel title="CanJS">
        CanJS provides the MV*
      </bit-panel>
      <bit-panel title="StealJS">
        StealJS provides the infrastructure.
      </bit-panel>
    </bit-tabs>
  `,
  ViewModel: {}
});

Using package-lock.json. It seems like as it is today, can is only useful if used by itself.

@matthewp
Copy link
Contributor Author

matthewp commented Jan 2, 2019

From a high level I think we need to decide:

  • Should DoneJS (including CanJS) use pinned or semver versions.
    • If pinned versions then DoneJS should do the same. Maybe people should be importing from donejs instead of can. This could also cause problems when the user users any 3rd party libraries.

Stop-gaps:

  • Push done-autorender and done-component into can, give rid of their usage in donejs.
  • Say we don't support package-lock at this time, add an .npmrc file to the app generator. (not sure this will fix it)

@frank-dspeed
Copy link
Contributor

i am for a alternate option and that is maybe not what you like but i think its the best
we rename the donejs packages to can namespace then we do a extra donejs util or canjs util that automates the version stuff like checking for redundant versions and we call this tool simply as postinstall hook from every package.

i am not for the reexport method as this leads to some other bugs with tree shaking also it would be a good idea to investigate on some packages that are using can packages via a i call it side effect.

when we would code some parts in a more FRP like style this would help a lot with the state as we don't need global state then we would reduce overall state fullness.

when you would consider my idea i would also dedicate my time for creation and identification of a roadmap to do that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants