diff --git a/javascript/jsr-esbuild.md b/javascript/jsr-esbuild.md new file mode 100644 index 0000000000..67f8097152 --- /dev/null +++ b/javascript/jsr-esbuild.md @@ -0,0 +1,225 @@ +# Using packages from JSR with esbuild + +[JSR](https://jsr.io/) is a brand new package repository for "modern JavaScript and TypeScript", [launched on March 1st](https://deno.com/blog/jsr_open_beta) by the Deno team as a new alternative to [npm](https://www.npmjs.com/) + +My JavaScript ecosystem fluency isn't great, so it took me a bit of work to figure out how to use packages from JSR in my browser. + +## Installing yassify with npx jsr add + +[@kwhinnery/yassify](https://jsr.io/@kwhinnery/yassify) is the demo package created as part of that [introductory blog post](https://deno.com/blog/jsr_open_beta#publishing-to-jsr). The code itself is a tiny snippet of TypeScript: + +```typescript +/** + * Yassify a string of text by appending emoji + * + * @param str The string of text to yassify. + * @returns a string of text with emoji appended + */ +export function yassify(str: string): string { + return `${str} 💅✨👑`; +} +``` +It's published to JSR [here](https://jsr.io/@kwhinnery/yassify). That page includes `npm` instructions for using it that look like this: + +> ```bash +> npx jsr add @kwhinnery/yassify +> ``` +> ```javascript +> import * as mod from "@kwhinnery/yassify"; +> ``` +For someone with limited JavaScript ecosystem fluency like myself, that is **not enough information**! I want to run this code in a browser. + +Part of the problem is that there are a bewildering array of build tool options. I wanted the thing with the least number of steps - eventually I found this pattern using `esbuild` that seems to work. + +I already had `npm` and `npx` installed. + +First I created myself a directory for my experiment: + +```bash +mkdir /tmp/site +cd /tmp/site +``` +I used the `npx jsr add` command from the JSR documentation: +```bash +npx jsr add @kwhinnery/yassify +``` +Output: +``` +Setting up .npmrc...ok +Installing @kwhinnery/yassify... +$ npm install @kwhinnery/yassify@npm:@jsr/kwhinnery__yassify + +added 1 package in 711ms + +Completed in 824ms +``` +This created a bunch of files. Running `find .` reveals the following: +``` +./node_modules +./node_modules/@kwhinnery +./node_modules/@kwhinnery/yassify +./node_modules/@kwhinnery/yassify/mod.d.ts +./node_modules/@kwhinnery/yassify/package.json +./node_modules/@kwhinnery/yassify/mod.js +./node_modules/.package-lock.json +./.npmrc +./package-lock.json +./package.json +``` +The `package.json` file contains: +```json +{ + "dependencies": { + "@kwhinnery/yassify": "npm:@jsr/kwhinnery__yassify@^1.0.1" + } +} +``` +`.npmrc` has the following, which is described in the JSR documentation about [npm compatibility](https://jsr.io/docs/npm-compatibility#advanced-setup): +``` +@jsr:registry=https://npm.jsr.io +``` +The actual `yassify` code lives in that `./node_modules/@kwhinnery/yassify/mod.js` file. + +OK - so we've run a command and got ourselves a `node_modules` directory with the `yassify` code in it. How do we use that in a browser? + +## Building an index.js file with esbuild + +Here's a tiny JavaScript file that uses `yassify`: + +```javascript +import { yassify } from "@kwhinnery/yassify"; +const h1 = document.querySelector("h1"); +h1.innerText = yassify(h1.innerText); +``` +And the incantation to have `esbuild` resolve that import and bundle all of the code together into a single file: +```bash +npx esbuild index.js --bundle +``` +That outputs directly to standard out: +```javascript +(() => { + // node_modules/@kwhinnery/yassify/mod.js + function yassify(str) { + return `${str} \u{1F485}\u2728\u{1F451}\u{1F984}`; + } + + // index.js + var h1 = document.querySelector("h1"); + h1.innerText = yassify(h1.innerText); +})(); +``` +Or you can add `--outfile=bundle.js` to write it to a file: +```bash +npx esbuild index.js --bundle --outfile=bundle.js +``` +Now here's an `index.html` file that makes use of this bundle: +```html + + +
+ +