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

[Feature] Outdated packages considers package dependencies #134

Open
coder2000 opened this issue Jun 11, 2022 · 7 comments
Open

[Feature] Outdated packages considers package dependencies #134

coder2000 opened this issue Jun 11, 2022 · 7 comments

Comments

@coder2000
Copy link

I don't know how easy it would be to add given how the pins are kept but it would be nice if the outdated packages considered the dependencies of other packages. Currently I use Dropzone,js in my app, and it depends on just-extend. There is a new version of just-extend but Dropzone would break as it's requirements are different. Taking that into consideration would be easier than wondering why scripts are breaking.

@toddcesere
Copy link

toddcesere commented Jan 25, 2023

I have a similar problem where jquery from cdn.jsdelivr.net works for me and jquery from ga.jspm.io doesn't work. For this reason I have the pin set to jsdelivr like this:

pin "jquery", to: "https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.js"

However, when I use the importmap command to pin blueimp-file-upload, it changes the jquery pin to use jspm, as seen here:

% bin/importmap pin blueimp-file-upload
Pinning "blueimp-file-upload" to https://ga.jspm.io/npm:blueimp-file-upload@10.32.0/js/jquery.fileupload.js
Pinning "jquery" to https://ga.jspm.io/npm:jquery@3.6.3/dist/jquery.js

You may have noticed that it upgraded from 3.6.0 to 3.6.3. I verified that the problem is not the version number by trying jquery 3.6.3 from jsdelivr. It worked fine. After changing that, I ran the command for pinning blueimp-file-upload and it changes jquery to using jspm again. In other words, it just replaces that line no matter what. In fact, the line that it will replace is entirely chosen by the name of the module, in this case just "jquery", which is a little bit of a problem because you can (usefully) pin things to whatever module name you want, and if you don't know it is a name for an npm package, or worse, it becomes an npm package after you start using that name, it will change that line that has nothing to do with the npm package, and you'll have a confusing problem to deal with.

This command is supposed to be for convenience, so I can understand if it isn't able to take conflicting dependencies into account. However, the fact that the documentation uses it, and the fact that it is even available, means that it should, at the very least, not replace lines quite so blindly and unexpectedly, especially in a file that is also meant to be edited manually. Especially when you consider that I might not commit the file after every change I make to it.

My proposal would be that when it is pinning dependencies and it encounters one that is already in the file, until the point where it does something a little smarter, it should just make no changes to that line.

As far as doing something smarter, I'm not sure I know enough to know what it should be, but it might be:

  • update the line only if the version number is the only thing that will get updated (don't change the host, don't update the line if it isn't using a cdn), and probably print something saying that this happened
  • somehow indicate which lines were added by the importmap command and, if necessary, options given such as cdn source, so that you can update only the automatically generated pins and only in such a way that dependency updates won't undo whatever options were selected when you pinned the package the first time

As it stands, I would at least be able to work around the problem if there was a way to indicate which pins should not be touched. Instead, I think my best option is that every time I change a package in a manual way I will copy that line and comment it, and basically say, "If these lines don't match, you've probably run the importmap command and it has probably updated this package to something you don't want." And then I'll have to either avoid the command (which would be inconvenient and I would likely forget at some point) or check the file for these notes every time I run it. And/Or maybe wrap bin/importmap in something that reminds me to check the notes.

@guybedford
Copy link
Contributor

JSPM Generator has two features that may be able to help here:

  1. The inputMap option allows providing an import map as input, where versions and resolutions from that input map are respected as a source of truth for resolution.
  2. The provider option allows choosing a provider to use for all resolutions. In general this option tries to switch all resolutions over to the provided provider rather than acting as multi-provider as the idea here is that there is benefit in unifying on one CDN (single source of failure) over multiple from a reliability perspective. (It's only within a single CDN domain, that multi-CDN architecture makes sense for redundancy of course).

@Caleb-T-Owens
Copy link
Contributor

Using the inputMap could help address some of the concerns about implementing scopes (#148).

I did some experimenting with the Generate API, and I've noticed there is no way to uninstall packages when passing in the inputMap. @guybedford Is there a plan for uninstalling with the inputMap; and if there is, how would it handle uninstalling dependencies?

To me, it seems like if we did a little bit of work just keeping track of what is a dependency and what has been installed by the user, we could work without using the inputMap and just pass a more complete list of packages into the install argument when pinning and unpinning.

Using the inputMap param

Pinning:

POST https://api.jspm.io/generate, body:

{
    "install": [ "alpinejs" ],
    "flattenScope": true,
    "env": [ "browser", "module" ],
    "inputMap": {
        "imports": {
            "react": "https://ga.jspm.io/npm:react@18.2.0/index.js"
        }
    }
}

Returning:

{
    "staticDeps": [
        "https://ga.jspm.io/npm:alpinejs@3.13.5/dist/module.esm.js",
        "https://ga.jspm.io/npm:react@18.2.0/index.js"
    ],
    "dynamicDeps": [],
    "map": {
        "imports": {
            "alpinejs": "https://ga.jspm.io/npm:alpinejs@3.13.5/dist/module.esm.js",
            "react": "https://ga.jspm.io/npm:react@18.2.0/index.js"
        }
    }
}

This installs the package alongside the existing ones

Updating:

POST https://api.jspm.io/generate, body:

{
    "install": [ "alpinejs" ],
    "flattenScope": true,
    "env": [ "browser", "module" ],
    "inputMap": {
        "imports": {
            "alpinejs": "https://ga.jspm.io/npm:alpinejs@3.13.0/dist/module.esm.js"
        }
    }
}

Response:

{
    "staticDeps": [
        "https://ga.jspm.io/npm:alpinejs@3.13.5/dist/module.esm.js"
    ],
    "dynamicDeps": [],
    "map": {
        "imports": {
            "alpinejs": "https://ga.jspm.io/npm:alpinejs@3.13.5/dist/module.esm.js"
        }
    }
}

This updates the package to the latest version.

Unpinning...

There is no "uninstall" or "remove" parameter here?

Without passing inputMap but we keep track of installed packages

Pinning

POST https://api.jspm.io/generate, body:

{
    "install": [ "alpinejs", "react@18.1.0" ],
    "flattenScope": true,
    "env": [ "browser", "module" ]
}

response:

{
    "staticDeps": [
        "https://ga.jspm.io/npm:alpinejs@3.13.5/dist/module.esm.js",
        "https://ga.jspm.io/npm:react@18.1.0/index.js"
    ],
    "dynamicDeps": [],
    "map": {
        "imports": {
            "alpinejs": "https://ga.jspm.io/npm:alpinejs@3.13.5/dist/module.esm.js",
            "react": "https://ga.jspm.io/npm:react@18.1.0/index.js"
        }
    }
}

Installs alpinejs latest and keeps react at its current version

Updating

Same as above - for packages we want to update, we just don't include their version in the install part

Unpinning

Similar to above - for packages we want to unpin, we just omit them from install.

@guybedford
Copy link
Contributor

@Caleb-T-Owens you're 100% right about these package management features in inputMap. Currently the generate API doesn't support the uninstall and update functions of the generator (https://github.com/jspm/generator/blob/main/src/generator.ts#L1107, https://github.com/jspm/generator/blob/main/src/generator.ts#L1039), but we could add these to the API by supporting update or uninstall in place of the install key currently, to provide iterative package management workflows.

I'm all out of time for this weekend now, but will add it to my list for next weekend if that might be useful.

@guybedford
Copy link
Contributor

Just following up here to check if there would be interest in the /update and /uninstall API features against inputMap?

@coder2000
Copy link
Author

I am assuming that using the update API feature would add the ability to update dependent packages at the same time rather than potentially breaking dependencies? Then yes.

@guybedford
Copy link
Contributor

@coder2000 yes it will automatically update subdependencies as well, even if they are top-level imports too. I added this update feature in https://jspm.org/cdn/api#generate-operation.

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

No branches or pull requests

4 participants