simonw / til

Today I Learned
https://til.simonwillison.net
Apache License 2.0
1.08k stars 84 forks source link

Get JSR @datasette/table to work #89

Open simonw opened 7 months ago

simonw commented 7 months ago

As shown in this TIL, I got stuck! https://til.simonwillison.net/javascript/jsr-esbuild

mkdir /tmp/datasette-demo2
cd /tmp/datasette-demo2

echo '@jsr:registry=https://npm.jsr.io' > .npmrc
npm install @jsr/datasette__table

echo 'import * as mod from "@jsr/datasette__table";' > index.js
npx esbuild index.js --bundle --outfile=bundle.js

Error:

✘ [ERROR] Could not resolve "npm:lit@^2.2.7"

    node_modules/@jsr/datasette__table/datasette-table.js:1:36:
      1 │ import {LitElement, html, css} from 'npm:lit@^2.2.7';
        ╵                                     ~~~~~~~~~~~~~~~~

  You can mark the path "npm:lit@^2.2.7" as external to exclude it from the bundle, which will
  remove this error and leave the unresolved path in the bundle.

1 error

I want to run my https://jsr.io/@datasette/table component in a browser, installed via JSR.

Here's what it looks like when it works: https://simonw.github.io/datasette-table/

Code here: https://github.com/simonw/datasette-table/

ThisIsMissEm commented 7 months ago

I wonder if you're needing to manually add dependencies of your dependencies to your project? That seems weird though, but might work

simonw commented 7 months ago

Got some help on JSR Discord, it turns out this may actually be a bug!

Bill Mill figured out a workaround using Deno and a plugin: https://notes.billmill.org/programming/javascript/build_tools/using_esbuild_to_package_a_deno_package_for_the_browser.html

JReinhold commented 7 months ago

Looks like JSR is adding the npm: protocol/prefix to your lit import automatically when you publish. This is evident when comparing the code on JSR vs what's in your repo.

I assume this is to make your package compatible with Deno, which uses that specifier for Node compatibility: https://docs.deno.com/runtime/manual/node/npm_specifiers

My gut feeling tells me this is a JSR bug/edge case because I don't see this documented anywhere. The primary use case for JSR is to publish TypeScript source, and then for npm compatibility, JSR will compile that to JavaScript. The TS source will be used by Deno/Bun while the JS dist will be used by Node/browser.

But since you're publishing JavaScript, the "source" and the "dist" is the same file, and so JSR tries to make it compatible with Deno by adding the npm: specifier, but that ironically breaks compatibility with npm.

My gut feeling could be wrong though.

EDIT: Oh wow, while researching and writing this it turns out you reached the same conclusion. 😅