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

Add support for import-maps #16

Closed
itskingori opened this issue May 10, 2024 · 9 comments
Closed

Add support for import-maps #16

itskingori opened this issue May 10, 2024 · 9 comments

Comments

@itskingori
Copy link

I am trying to use this library with import-maps but can't seem to get it to work. See reproduced error on JSPM Online Generator or the error below ...

$ curl -sS --request POST   --url https://api.jspm.io/generate   --header 'Content-Type: application/json'   --data '{
        "install": [
                "fancy-ansi"
        ],
        "flattenScope": true,
        "env": [
                "browser",
                "module",
                "production"
        ],
        "provider": "jspm"
}'     
{
  "error": "TypeError: version.match is not a function"
}

Here's an example of a library that works ...

$ curl -sS --request POST   --url https://api.jspm.io/generate   --header 'Content-Type: application/json'   --data '{
        "install": [
                "react"
        ],
        "flattenScope": true,
        "env": [
                "browser",
                "module",
                "production"
        ],
        "provider": "jspm"
}'
{
  "staticDeps": [
    "https://ga.jspm.io/npm:react@18.3.1/index.js"
  ],
  "dynamicDeps": [],
  "map": {
    "imports": {
      "react": "https://ga.jspm.io/npm:react@18.3.1/index.js"
    }
  }
}

References

amorey added a commit to amorey/fancy-ansi that referenced this issue May 10, 2024
amorey added a commit that referenced this issue May 10, 2024
* copied ansi-regex into source code in order to fix jspm installation issue #16
@amorey
Copy link
Member

amorey commented May 10, 2024

I tracked down the issue to the use of ansi-regex internally. I was able to install ansi-regex with jspm separately but for some reason when it's included as a dependency, it breaks the fancy-ansi installation. To solve the problem I copied the regex into the source code and removed the dependency. JSPM import-map generation should work with fancy-ansi@0.1.2:

curl -sS --request POST   --url https://api.jspm.io/generate   --header 'Content-Type: application/json'   --data '{
        "install": [
                "fancy-ansi@0.1.2"
        ],
        "flattenScope": true,
        "env": [
                "browser",
                "module",
                "production"
        ],
        "provider": "jspm"
}'
{"staticDeps":["https://ga.jspm.io/npm:escape-html@1.0.3/index.js","https://ga.jspm.io/npm:fancy-ansi@0.1.2/_/e9xSNm3_.js","https://ga.jspm.io/npm:fancy-ansi@0.1.2/dist/main.js"],"dynamicDeps":[],"map":{"imports":{"fancy-ansi":"https://ga.jspm.io/npm:fancy-ansi@0.1.2/dist/main.js","escape-html":"https://ga.jspm.io/npm:escape-html@1.0.3/index.js"}}}

Let me know if that fixed the problem.

@itskingori
Copy link
Author

It did! 🙌🏽

Tested it on JSPM's Online generator ...

Screenshot 2024-05-10 at 16 19 21

@itskingori
Copy link
Author

Oh, and thank you for looking into it. It's an amazing library 🏆 ... also the kubetail demo looks dope! 😍

@amorey
Copy link
Member

amorey commented May 10, 2024

Awesome! Happy to hear it's working and that you liked the kubetail demo!

@itskingori itskingori reopened this May 10, 2024
@itskingori
Copy link
Author

It's working with import-maps but only when you point the packages to the CDN, but when you vendor the packages locally it can't find _/e9xSNm3_.js file. You can see it listed here ...

{
  "staticDeps": [
    "https://ga.jspm.io/npm:escape-html@1.0.3/index.js",
    "https://ga.jspm.io/npm:fancy-ansi@0.1.2/_/e9xSNm3_.js",
    "https://ga.jspm.io/npm:fancy-ansi@0.1.2/dist/main.js"
  ],
  "dynamicDeps": [],
  "map": {
    "imports": {
      "fancy-ansi": "https://ga.jspm.io/npm:fancy-ansi@0.1.2/dist/main.js",
      "escape-html": "https://ga.jspm.io/npm:escape-html@1.0.3/index.js"
    }
  }
}

I can use the CDN, so this is not a blocking issue for me anymore, but figured I'd let you know. For more context, I'm using importmap-rails which is the Rails integration with import-maps and it vendors JS packages by default. It looks something like this ...

$ ./bin/importmap pin fancy-ansi@0.1.2                                                                                
Pinning "fancy-ansi" to vendor/javascript/fancy-ansi.js via download from https://ga.jspm.io/npm:fancy-ansi@0.1.2/dist/main.js
Pinning "escape-html" to vendor/javascript/escape-html.js via download from https://ga.jspm.io/npm:escape-html@1.0.3/index.js

I can't quite figure out where e9xSNm3_.js comes from so lemme know if it's related to this issue. If not, I'll close it.

@amorey
Copy link
Member

amorey commented May 11, 2024

😖Sorry about that! Thanks for the heads up. I'm not sure where that particular file reference is coming from but it's probably a reference to a build artifact used internally. I'll take a look.

@amorey
Copy link
Member

amorey commented May 11, 2024

I took a look and e9xSNm3_.js is from an internal dynamic import. The build processes creates a file with shared constants that is used internally by main.js and colors.js (colors-B3F3SizO.js) and referenced by each:
https://www.unpkg.com/fancy-ansi@0.1.2/dist/main.js
https://www.unpkg.com/fancy-ansi@0.1.2/dist/colors.js

When you install the package from ga.jspm.io, it rewrites the import statement (colors-B3F3SizO.js -> ../_/e9xSNm3_.js):
https://ga.jspm.io/npm:fancy-ansi@0.1.2/dist/main.js

And places the shared file in a different directory:
https://ga.jspm.io/npm:fancy-ansi@0.1.2/_/e9xSNm3_.js

When you include fancy-ansi in your importmap via the CDN, it works because the browser is able to resolve the dynamic import relative to the CDN url, but it's failing on importmap-rails because the initial pin only downloads main.js and the bundling process doesn't resolve the dynamic import.

One way to fix this is by inlining dynamic imports in the fancy-ansi package but publishing a library in a format that is suited for bundles doesn't seem ideal. Another way is for the user to use webpack/esbuild in the rails bundling step but requiring the user to add complexity to their setup isn't ideal either. Have you come across this issue before? Do you know how other libraries are handling this?

@itskingori
Copy link
Author

Your explanation helped me avoid wasting time trying to figure out why another package (parse-link-header) was failing when vendored. So it doesn't seem like the problem is unique to you. It works when I link to CDN directly.

Unfortunately I don't have a good grasp of modern JavaScript bundling to be able to assist. I'm primarily a Ruby & Go developer who can write enough JavaScript to get by. Which is why I'm avoiding Webpack & ESBuild etc ... I've tried them and they seem overkill for someone who just want to sprinkle a little JavaScript. I much prefer import-maps which allow me to use ES6 in the browser with simple imports akin to how JavaScript used to be included with simple <script> tags back in the day.

Anyway, thanks for looking into it. I consider my issue solved and at least this discussion can help someone in the future who may be scratching their heads.

@amorey
Copy link
Member

amorey commented May 14, 2024

Thanks for the follow-up! It's good to hear that at least Fancy-ANSI isn't alone with this problem so maybe importmap-rails will implement a solution downstream.

In terms of JavaScript bundling, there are a lot of options and it can get complicated very quickly especially when you want a tight integration with the backend so I understand your hesitation. For kubetail, I'm using go on the backend and vite+typescript on the frontend (with graphql in between) and I'm very happy with the developer experience. Vite takes care of the bundling details for you so don't have to worry about webpack configs or vendor bundling. It also has hot-module-loading so you can see your changes instantly. It looks like there's a vite plugin for Rails so you might want to consider that.

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

2 participants