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

chore(monorepo): separate each loader into its own package #23

Merged
merged 38 commits into from
Nov 14, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
0496d43
chore: convert to a monorepo
JakobJingleheimer Sep 15, 2024
c157d1f
docs: add "official loaders"
AugustinMauroy Sep 17, 2024
5a53b13
chore(ci-publish): support provenance for monorepo (#22)
AugustinMauroy Sep 17, 2024
a9d36bb
Merge remote-tracking branch 'origin/main' into chore/monorepo
JakobJingleheimer Nov 7, 2024
15fd97b
fix: tests for monorepo-isation
JakobJingleheimer Nov 7, 2024
184545e
fix: update tsx loader for monorepo-isation
JakobJingleheimer Nov 7, 2024
b2110ac
fix: media spec for monorepo
JakobJingleheimer Nov 7, 2024
7f99c6f
chore: rename hook fns to include their purpose
JakobJingleheimer Nov 7, 2024
d60890f
chore: rename `format` `'cssmodule'` → `'css-module'`
JakobJingleheimer Nov 7, 2024
5f3bfc9
chore: reset alias version to 1
JakobJingleheimer Nov 7, 2024
a17aa38
chore: hoist `@types/node` dev dep to root
JakobJingleheimer Nov 7, 2024
b0771bc
chore: remove disused dep
JakobJingleheimer Nov 8, 2024
ff88524
feat: restore `mismatched-format` loader
JakobJingleheimer Nov 8, 2024
59c2ad0
update editor config
AugustinMauroy Nov 8, 2024
0bbdcce
feat: update `tsx` README to mention `nodejs/amaro`
JakobJingleheimer Nov 8, 2024
7858a50
test: add e2e cases for `mismatched-format`
JakobJingleheimer Nov 8, 2024
ba6b34f
chore: replace `testdouble` with `node:test.mock`
JakobJingleheimer Nov 8, 2024
e94ca76
test: contains-cjs + mismatched-format → `assert/strict`
JakobJingleheimer Nov 9, 2024
a779408
fixup!: improve test-case descriptions
JakobJingleheimer Nov 11, 2024
bca2631
Merge remote-tracking branch 'origin/main' into chore/monorepo
JakobJingleheimer Nov 11, 2024
9652f94
feat: add badges to each package's readme & correct folder name
JakobJingleheimer Nov 11, 2024
b7fef5d
fix: separate `mismatched-format` unit & e2e to avoid mock interference
JakobJingleheimer Nov 11, 2024
d055bba
chore: remove accidental file commit
JakobJingleheimer Nov 11, 2024
3cf0b2f
test: support both human-readable output & computer coverage report
JakobJingleheimer Nov 11, 2024
104221b
test(ci): add node 23.x to list of versions to test
JakobJingleheimer Nov 11, 2024
06db7ef
chore: update `nodejs` → `node.js` in pjson keywords
JakobJingleheimer Nov 11, 2024
21e4b14
test(dep): update package-lock.json
JakobJingleheimer Nov 11, 2024
2f96b09
test: add case for SVGX underivable component name
JakobJingleheimer Nov 11, 2024
8c59066
fix: bad name error should be thrown before attempting to load the file
JakobJingleheimer Nov 11, 2024
36b8387
chore: extract `findEsbuildConfig` into own module
JakobJingleheimer Nov 11, 2024
4b33742
test: add spec for `findEsbuildConfig`
JakobJingleheimer Nov 11, 2024
e37b055
test: add `todo` case for `tsx`
JakobJingleheimer Nov 11, 2024
b3625cc
chore: update tsx pjson.engines to include all active lines
JakobJingleheimer Nov 11, 2024
fb17797
Update node version sequence in ci
JakobJingleheimer Nov 12, 2024
e5c6fa7
fail-fast: false
JakobJingleheimer Nov 12, 2024
c6075fe
chore: disregard warnings in CI runs
JakobJingleheimer Nov 12, 2024
5ac7156
test: add case for transpile errors in jsx
JakobJingleheimer Nov 12, 2024
5cd9a34
test: commit coverage for diff
JakobJingleheimer Nov 12, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
indent_style = tab
11 changes: 7 additions & 4 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
name: Publish to NPM
on:
release:
types: [created]
push:
tags:
- '**@*'

jobs:
build:
runs-on: ubuntu-latest
Expand All @@ -15,6 +17,7 @@ jobs:
node-version-file: '.nvmrc'
registry-url: 'https://registry.npmjs.org'
- run: npm ci
- run: npm publish --provenance --access public
- name: Get the name of the package
run : npm publish --workspace=\"packages/${GITHUB_REF_NAME##*@}\"
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} --provenance --access public
200 changes: 28 additions & 172 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,178 +2,34 @@

<img src="./logo.svg" height="100" width="100" alt="" />

This package provides a variety of loaders to facilitate a quick and easy local development and CI testing environment.

## Local dev

```console
--loader=nodejs-loaders/dev/alias \
--loader=nodejs-loaders/dev/tsx \
--loader=nodejs-loaders/dev/svgx \
--loader=nodejs-loaders/dev/mismatched-format
```

Sequence here **is** important (you want to correct a mismatched package format before you try to use it, and SVGX is a form of JSX, so it needs TSX loader to finish the job).

### Alias

This loader supports 2 options, both of which follow TypeScript's [`paths`](https://www.typescriptlang.org/docs/handbook/modules/reference.html#paths); if you're using TypeScript, this loader handles the (important) half of work TypeScript ignores. It checks for `tsconfig.json` in the project root (the current working directory) and builds aliases from `compilerOptions.paths` if it exists.

If you're not using TypeScript (or you're not using `compilerOptions.paths`¹), you can specify aliases in `package.json` in the project root (the current working directory) in the same way `compilerOptions.paths` are defined:

```json
{
"aliases": {
"…/*": "./src/*",
"CONF": "./config.json"
}
}
```

¹ Note that if you are using aliases and do not set up `compilerOptions.paths`, TypeScript will make your life hell.

#### A simple prefix

This is commonly used to reference the project root; common prefixes are `@/` (or some variation like `@app/`) and `…/`: `import foo from '…/app/foo.mts;` → `${project_root}/src/app/foo.mts`.

> [!TIP]
> Due to package namespacing (aka ["scopes"](https://docs.npmjs.com/about-scopes)) it may be best to avoid using the "at" symbol (`@`) since that could lead to confusion over what is a package and what is an alias (especially if you eventually add a package named with the alias you're using).

> [!IMPORTANT]
> When configuring these aliases, ensure astrisks (`*`) are used correctly; configuring this for TypeScript can be extremely confusing. See [_Why are these tsconfig paths not working?_](https://stackoverflow.com/q/50679031) for some of the litany of ways configuration can fail.

#### A pointer

This is a static specifier similar to a bare module specifier: `foo` → `${project_root}/src/app/foo.mts`. This may be useful when you have a commonly referenced file like config (which may conditionally not even live on the same filesystem): `import CONF from 'conf';` → `${project_root}/config.json`.

## Mismatched format

Many packages are incorrectly configured, claiming to be ESM yet not actually surfacing ESM. This is most commonly due to a `package.json` using the non-standard `"module"` field:

```json
{
"name": "mismatched-example",
"type": "module",
"main": "./dist/cjs.js",
"module": "./dist/esm.js"
}
```

`mismatched-example` has told node its main entry point is `./dist/cjs.js` and that it is ESM. Therefore, trying to import this package will (likely) explode in a `SyntaxError` as node loads `./dist/cjs.js` as ESM (instead of the CJS it actually is).

This loader detects the explosion and re-instructs node to ignore the misconfiguration and instead load `./dist/cjs.js` as CJS (the loader doesn't try to find a potential ESM main entry point the package may have—there are too many options, several of which are non-standard).

Note to package authors reading this: The simplest fix here is to distribute only CJS. See [_Configuring CommonJS & ES Modules for Node.js_](https://dev.to/jakobjingleheimer/configuring-commonjs-es-modules-for-nodejs-12ed) for a thorough explanation of options.

> [!IMPORTANT]
> Node.js now has experimental support that better handles this via [`--experimental-detect-module`](https://nodejs.org/api/cli.html#--experimental-detect-module). This loader may be re-purposed to address the root of the problem instead: that `mismatched-example`'s configuration is wrong.

## JSX / TS(X)

This loader checks for a `esbuild.config.mjs` in the project root (if you want to keep it elsewhere, consider a symlink in the project root pointing to its actual location); only options for [esbuild's "transform" API](https://esbuild.github.io/api/#transform) are valid (esbuild handles looking for a tsconfig). When none is found, it uses a few necessary default.

This loader does _not_ handle TypeScript's file extension nonsense. Import specifiers must use the actual file extension of the file actually on disk:

```
./
├ …
└ foo.ts
```

💥 `import foo from './foo.js';`<br />
✅ `import foo from './foo.ts';`

<details>
<summary>Supported file extensions</summary>

* `.jsx`
* `.mts`
* `.ts`
* `.tsx`
</details>

## CI testing

```console
--loader=nodejs-loaders/testing/css-module \
--loader=nodejs-loaders/testing/media \
--loader=nodejs-loaders/testing/text
```

Sequence here is not important.

### CSS Module

This loads the module as a plain-object of simple key-value pairs of the css specifiers like:

```css
/* main.module.css */
#Bar { font-weight: bold }

.Foo {
text-decoration: none

.Baz { color: red }
}

.Qux .Zed { font-size: 1.1em }
```

```js
import styles from 'main.module.css';

styles.Bar; // 'Bar'
styles.Baz; // 'Baz'
styles.Foo; // 'Foo'
styles.Zed; // 'Zed'
```

This ensures snapshots are unaffected by unrelated changes.
This package provides a variety of loaders to facilitate a quick and easy CI testing environment.

> [!WARNING]
> This loader does not differentiate classes vs ids; thus duplicate names can create a last-wins conflict. For example `#Foo` and `.Foo` will result in just `Foo: 'Foo'`. This is unlikely to cause any real-world problems (and you probably shouldn't be doing this anyway).

### Media

This loader returns the specifier (truncated from project root / current working directory) as the default export:

```js
import photo from './team.jpg'; // photo = '[…]/team.jpg'
```

This ensures snapshots are unaffected by the file system on which the test is run.

<details>
<summary>Supported file extensions</summary>
> These should NOT be used in production; they will likely not do what you need there anyway.

Audio/Video:
* `.av1`
* `.mp3`
* `.mp3`
* `.mp4`
* `.ogg`
* `.webm`

Images:

* `.avif`
* `.gif`
* `.ico`
* `.jpeg`
* `.jpg`
* `.png`
* `.webp`
</details>

### Text

This loader handles files that are effectively plain text.

<details>
<summary>Supported file extensions</summary>

* `.graphql`
* `.gql`
* `.md`
* `.txt`
</details>
```console
node
# sequence here IS important:
--loader=@nodejs-loaders/alias \
--loader=@nodejs-loaders/tsx \
--loader=@nodejs-loaders/svgx \
# sequence here is NOT important:
--loader=@nodejs-loaders/css-module \
--loader=@nodejs-loaders/media \
--loader=@nodejs-loaders/text \
./main.js
```

* [Alias loader](./packages/alias/)
* [JSX / TSX loader](./packages/tsx/)
* [SVGX loader](./packages/svgx/)
* [CSS Modules loader](./packages/css-module/)
* [Media loader](./packages/media/)
* [Text loader](./packages/text/)

## Official Loaders

These loaders are officially maintained by their respective projects and are recommended, 'cause they are the most up-to-date and have the best support.

* [MDX loader](https://mdxjs.com/packages/node-loader/)
* [SWC register](https://github.com/swc-project/swc-node/tree/master/packages/register#swc-noderegister)
28 changes: 0 additions & 28 deletions containsCJS.mjs

This file was deleted.

69 changes: 0 additions & 69 deletions containsCJS.spec.mjs

This file was deleted.

File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
36 changes: 0 additions & 36 deletions mismatched-format.mjs

This file was deleted.

Loading
Loading