|
| 1 | +# @hackbg/ubik |
| 2 | + |
| 3 | + |
| 4 | + |
| 5 | +***Ubik***, named after the mysterious "reality-restoring substance" from |
| 6 | +[Philip K. Dick's eponymous novel](https://en.wikipedia.org/wiki/Ubik), |
| 7 | +helps you restore compatibility, interoperability, and correctness when |
| 8 | +building libraries in TypeScript. |
| 9 | + |
| 10 | +What it does: |
| 11 | + |
| 12 | +* Add missing extensions to TypeScript output. |
| 13 | +* Add missing `/index.js` to directory imports. |
| 14 | +* Separate undifferentiated `import`/`import type` within a package. |
| 15 | +* Merge packages that were prematurely separated but ended up tightly coupled. |
| 16 | +* Publish patched packages then restore your working tree to a pristine state. |
| 17 | + |
| 18 | +## Quick start |
| 19 | + |
| 20 | +Add to `package.json`: |
| 21 | + |
| 22 | +```json |
| 23 | +{ |
| 24 | + "devDependencies": { |
| 25 | + "@hackbg/ubik": "^2" |
| 26 | + }, |
| 27 | + "scripts": { |
| 28 | + "ubik": "ubik" |
| 29 | + } |
| 30 | +} |
| 31 | +``` |
| 32 | + |
| 33 | +Add to `tsconfig.json`: |
| 34 | + |
| 35 | +```json |
| 36 | +{ |
| 37 | + "exclude": [ |
| 38 | + "dist/**/*" |
| 39 | + ] |
| 40 | +} |
| 41 | +``` |
| 42 | + |
| 43 | +Add to `.gitignore`: |
| 44 | + |
| 45 | +``` |
| 46 | +dist/ |
| 47 | +*.dist.js |
| 48 | +*.dist.mjs |
| 49 | +*.dist.cjs |
| 50 | +*.dist.d.ts |
| 51 | +``` |
| 52 | + |
| 53 | +Now you can publish your library with `npm run ubik publish`. |
| 54 | + |
| 55 | +## Basic premise |
| 56 | + |
| 57 | +TypeScript wants you to import modules with: |
| 58 | + |
| 59 | +```ts |
| 60 | +import { foo } from "./foo" |
| 61 | +``` |
| 62 | + |
| 63 | +but the ECMAScript specification expects: |
| 64 | + |
| 65 | +```js |
| 66 | +import { foo } from "./foo.js" |
| 67 | +``` |
| 68 | + |
| 69 | +TypeScript doesn't add the extensions; it also doesn't provide an extensibility hook |
| 70 | +which could be used to add them. [The documentation](https://www.typescriptlang.org/docs/handbook/esm-node.html) |
| 71 | +is confusing and unhelpful; the solution that it suggests is ridiculous and unacceptable. |
| 72 | +On GitHub issues, the TypeScript developers have repeatedly reacted with indifference. |
| 73 | + |
| 74 | +**Before Node.js 16, this was less of a problem:** imports without extensions still |
| 75 | +worked. However, since Node 16 started enforcing the ES Modules spec (which requires |
| 76 | +extensions), the code that `tsc` outputs became effectively **invalid and impossible to run** |
| 77 | +(unless you were writing your program in a single file). |
| 78 | + |
| 79 | +What, were you expecting the compiler for evertone's favorite "strict superset of JS" |
| 80 | +to, idk, output correct JS that is ready to execute? You crazy person. |
| 81 | + |
| 82 | +## Also goes well with... |
| 83 | + |
| 84 | +When using Ubik alongside the [**`@hackbg/ganesha`**](https://github.com/hackbg/ganesha) |
| 85 | +module loader for Node 16+, TypeScript on the backend becomes completely transparent: |
| 86 | +no build step during development + monolithic publish step 🐘 |
| 87 | + |
| 88 | +<div align="center"> |
| 89 | + |
| 90 | +--- |
| 91 | + |
| 92 | +Made with **#%&!** @ [**Hack.bg**](https://foss.hack.bg) |
| 93 | +in response to the Node16/TS4 incompatibility event of Q2 2022. |
| 94 | + |
| 95 | +</div> |
0 commit comments