Skip to content

Commit

Permalink
Add experimental version for oxc-transformer usage (#15)
Browse files Browse the repository at this point in the history
TODO:

- ✅ Validate dev watch mode works
- ✅ Experiment with JSX usage, see if we do want to expose some kind of
config
  • Loading branch information
hamlim committed Sep 29, 2024
1 parent 178760d commit 0f46f3c
Show file tree
Hide file tree
Showing 20 changed files with 609 additions and 124 deletions.
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
22.8.0
Binary file modified bun.lockb
Binary file not shown.
13 changes: 13 additions & 0 deletions packages/hohoro/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
### Unreleased:

### [0.3.0] - September 29th, 2024

_This change should be backwards compatible for existing installs_

This release introduces a new `experimental` export and binary:

- Export: `'hohoro/experimental'`
- Binary: `hohoro-experimental`

Both support the same API as the existing export and binary, however under the hood it's using [Oxc](https://oxc.rs/) and it's new [Oxc Transformer Alpha](https://oxc.rs/blog/2024-09-29-transformer-alpha.html).

What this means in practice is that you should be able to remove your `.swcrc` config (as well as related `swc` dependencies) and the `typescript` dependency if you're using the experimental export/binary. We use Oxc to both compile JavaScript/TypeScript into ESNext compatible JavaScript, and also use it to generate [isolated declarations](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-5.html#isolated-declarations).

### [0.2.1] - August 15th, 2024

Fix missing stderr output if `tsc` fails for type errors. Previously `hohoro` would exit with a successful exit code and it would be possible for no type declaration files to be generated in dist (or the target output directory).
Expand Down
20 changes: 19 additions & 1 deletion packages/hohoro/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,24 @@ Then add the following `dev` script to your `package.json`:
}
```

## Experimental:

This library also exposes a `hohoro-experimental` binary that builds code using [oxc](https://oxc.rs/) with [`oxc-transform`](https://www.npmjs.com/package/oxc-transform).

When using the experimental binary - you'll **need to also install `oxc-transform` as a devDependency**.

### Usage:

```json
{
"scripts": {
"build": "hohoro-experimental"
}
}
```

You **do not need additional configuration** when using the experimental build.

## Contributing:

### Code Quality:
Expand All @@ -62,7 +80,7 @@ This library uses [BiomeJS](https://biomejs.dev/) for linting, run `bun run lint

#### Tests

This library uses Node for running unit tests, run `bun run test` from the root or from this workspace!
This library uses Bun for running unit tests, run `bun run test` from the root or from this workspace!

### Publishing:

Expand Down
119 changes: 119 additions & 0 deletions packages/hohoro/__tests__/experimental-incremental-build.test.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import { afterEach, beforeEach, describe, expect, it } from "bun:test";
import { copyFileSync, rmSync, writeFileSync } from "node:fs";
import { dirname, join as pathJoin } from "node:path";
import { fileURLToPath } from "node:url";
import fg from "fast-glob";
import { runBuild } from "../experimental-incremental-build.mjs";

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

describe("experimental hohoro", () => {
// copy over files from the template dir to the src dir
beforeEach(() => {
const templateDir = pathJoin(
__dirname,
"..",
"sample-workspace-dir",
"template",
);
const srcDir = pathJoin(__dirname, "..", "sample-workspace-dir", "src");
const files = fg.sync(pathJoin(templateDir, "**/*.{ts,tsx,js,json}"));

for (const file of files) {
const filePath = file.replace(templateDir, srcDir);
copyFileSync(file, filePath);
}
});

it("[experimental] It correctly builds the library", async () => {
const logs = [];
const errors = [];
const logger = {
log(message) {
logs.push(message);
},
error(message) {
errors.push(message);
},
};
await runBuild({
rootDirectory: pathJoin(__dirname, "..", "sample-workspace-dir"),
logger,
});

const distFiles = fg.sync(
pathJoin(__dirname, "..", "sample-workspace-dir", "dist", "**/*"),
);

expect(distFiles.some((file) => file.includes("tsx-file.js"))).toBe(true);
expect(distFiles.some((file) => file.includes("tsx-file.d.ts"))).toBe(true);
expect(distFiles.some((file) => file.includes("js-file.js"))).toBe(true);
expect(distFiles.some((file) => file.includes("json-file.json"))).toBe(
true,
);
expect(errors.length).toBe(0);
expect(logs[0]).toContain("compiled: 2 files, copied 1 file");
});

it("[experimental] It only builds changed files", async () => {
const logs = [];
const errors = [];
const logger = {
log(message) {
logs.push(message);
},
error(message) {
errors.push(message);
},
};

await runBuild({
rootDirectory: pathJoin(__dirname, "..", "sample-workspace-dir"),
logger,
});

// change a file
const tsxFile = pathJoin(
__dirname,
"..",
"sample-workspace-dir",
"src",
"tsx-file.tsx",
);
writeFileSync(tsxFile, `export const foo = 'bar';`);

await runBuild({
rootDirectory: pathJoin(__dirname, "..", "sample-workspace-dir"),
logger,
});

// most important assertion, only the tsx file should have been compiled!
expect(logs[1]).toContain("compiled: 1 file");

const distFiles = fg.sync(
pathJoin(__dirname, "..", "sample-workspace-dir", "dist", "**/*"),
);

expect(distFiles.some((file) => file.includes("tsx-file.js"))).toBe(true);
expect(distFiles.some((file) => file.includes("tsx-file.d.ts"))).toBe(true);
expect(distFiles.some((file) => file.includes("js-file.js"))).toBe(true);
expect(distFiles.some((file) => file.includes("json-file.json"))).toBe(
true,
);
expect(errors.length).toBe(0);
});

// cleanup src and dist dirs after the tests run
afterEach(() => {
const srcDir = pathJoin(__dirname, "..", "sample-workspace-dir", "src");

const files = fg.sync(pathJoin(srcDir, "**/*.{ts,tsx,js,json}"));
for (const file of files) {
rmSync(file, { recursive: true });
}
rmSync(pathJoin(__dirname, "..", "sample-workspace-dir", "dist"), {
recursive: true,
});
});
});
Loading

0 comments on commit 0f46f3c

Please sign in to comment.