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

Use esbuild's automatic JSX runtime handling #18

Merged
merged 8 commits into from
Jul 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 8 additions & 0 deletions .changeset/hot-horses-burn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
'esbd': major
---

Remove built-in jsx-automatic handling in favor of esbuild's

This change sets the minimum version of esbuild to be `>= 0.14.51` and removes
the old SWC plugin, since esbuild now supports the automatic runtime natively.
12 changes: 6 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@
"devDependencies": {
"@awesome-code-style/eslint-config": "^4.0.0",
"@awesome-code-style/prettier-config": "^4.0.0",
"@changesets/cli": "^2.23.0",
"@changesets/cli": "^2.24.1",
"@tsconfig/node16": "^1.0.3",
"@typescript-eslint/eslint-plugin": "^5.29.0",
"@typescript-eslint/parser": "^5.29.0",
"esbuild": "^0.14.47",
"eslint": "^8.18.0",
"@typescript-eslint/eslint-plugin": "^5.31.0",
"@typescript-eslint/parser": "^5.31.0",
"esbuild": "^0.14.51",
"eslint": "^8.20.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-header": "^3.1.1",
"eslint-plugin-import": "^2.26.0",
Expand All @@ -40,7 +40,7 @@
"execa": "^5.0.0",
"prettier": "^2.7.1",
"tslib": "^2.4.0",
"typedoc": "^0.22.18",
"typedoc": "^0.23.9",
"typescript": "^4.7.4"
},
"scripts": {
Expand Down
12 changes: 0 additions & 12 deletions packages/esbd/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ In an ideal world, esbd would not exist. If any of its extended features get add
- Live-reload for web applications and restart-on-change for Node applications
- Opt-in sideband type checking for TypeScript projects
- In-browser error overlay for esbuild and TypeScript errors (dismissable)
- Optional support for React's `"jsxRuntime": "automatic"` mode via a small [SWC](https://swc.rs) plugin
- Copy static assets into the build folder
- Full support for other esbuild plugins (JS only)

Expand Down Expand Up @@ -288,16 +287,6 @@ If `src/entry.tsx` included any CSS assets, either directly or indirectly via it

There are two configuration options that affect HTML entry point behavior: `ignoreAssets` and `integrity`. You can read about them in the [API](#api) section.

### JSX runtime mode

React 17 introduced a new [JSX transform](https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html) that enables some internal performance optimizations and obviates having to import 'React' in every module. Unfortunately, esbuild does not support this transform natively, even though both Babel and the TypeScript compiler do support it.

Esbd adds optional support for the new transform on top of esbuild through the use of [SWC](https://swc.rs). If you set the `jsxRuntime` configuration option to `automatic` and have `@swc/core` installed as a dependency in your project, esbd will transform `.jsx` and `.tsx` files first using SWC to transform JSX elements and then again using esbuild to transpile or downlevel according to the build target.

This adds minimal time to each build because SWC is a very fast transpiler and because only files that use JSX will be processed twice. And again, this is entirely opt-in.

If you are using TypeScript, note that you should set the "jsx" tsconfig option to "react-jsx" so that your editor does not require the "React" import. Esbd does not currently read this option from tsconfig.json, so `jsxRuntime` must be set to `automatic` explicitly for the new transform to be used.

### Copying static assets

Esbd can copy static assets to the output directory that would not otherwise be discovered through esbuild's dependency resolution. This works for files referenced by [HTML entry points](#html-entry-points) and also via the `copy` [configuration option](#api).
Expand Down Expand Up @@ -350,7 +339,6 @@ Note that these esbuild options are ignored:
| copy | `[from: string, to?: string][]` | - | Files to copy to the output directory during the build.<br><br>Each entry is a tuple representing the source file path to copy and, optionally, the destination file path.<br><br>Source paths may be absolute or relative to `absWorkingDir`. Destination paths may be absolute or relative to `outdir`. If no destination path is provided, the source file will be copied to `outdir` with the same name.<br><br>If `esbd` is started in a watch mode (serve, node-dev, or build --watch), source files will be watched and copied whenever they change.<br><br>Note that `copy` does not support glob patterns. |
| ignoreAssets | `boolean` | - | By default, assets (images, manifests, scripts, etc.) referenced by `<link>`, `<style>` and `<script>` tags in the HTML template will be collected as esbuild assets if their `src` attributes are specified as relative paths. The asset paths will be resolved relative to the *template file* and will be copied to the output directory, taking `publicPath` into consideration if it has been set.<br><br>Absolute paths or URIs will be ignored.<br><br>To ignore all `src` attributes and avoid collecting discovered assets, set this option to `true`. |
| [integrity](https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity) | `"sha256" \| "sha384" \| "sha512"` | - | If specified, a cryptographic digest for each file referenced by a `<link>` or `<script>` tag will be calculated using the specified algorithm and added as an `integrity` attribute on the associated tag. |
| [jsxRuntime](https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html) | `"automatic" \| "classic"` | `"classic"` | React 17 introduced a new JSX transform that enables some internal performance optimizations and obviates having to import 'React' in every module.<br><br>Though esbuild does not support this new transform natively, setting this option to `automatic` will add a load plugin (powered by SWC) for ".jsx" and ".tsx" files so they use the new tranform as expected.<br><br>If you are using TypeScript, note that you should set the "jsx" tsconfig option to "react-jsx" so that your editor does not require the "React" import. esbd does not currently read this option from tsconfig.json, so "jsxRuntime" must be set to "automatic" explicitly for the new transform to be used. |
| name | `string` | - | Name of this configuration.<br><br>This is required for configurations that appear in an array. |
<!-- end -->
<!-- prettier-ignore-end -->
20 changes: 6 additions & 14 deletions packages/esbd/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,25 +24,17 @@
"@jgoz/esbuild-plugin-typecheck": "workspace:*"
},
"peerDependencies": {
"@swc/core": ">= 1.2.111",
"esbuild": ">= 0.13.0"
},
"peerDependenciesMeta": {
"@swc/core": {
"optional": true
}
"esbuild": ">= 0.14.51"
},
"devDependencies": {
"@playwright/test": "^1.22.2",
"@swc/core": "^1.2.205",
"@playwright/test": "^1.24.1",
"@types/mkdirp": "^1.0.2",
"@types/parse5": "^6.0.3",
"@types/pretty-time": "^1.1.2",
"@types/serve-static": "^1.13.10",
"@types/wait-on": "^5.3.1",
"chokidar": "^3.5.3",
"cleye": "^1.2.1",
"esbuild": "^0.14.47",
"esbuild": "^0.14.51",
"esbuild-node-externals": "^1.4.1",
"execa": "^5.0.0",
"get-port": "^5.0.0",
Expand All @@ -52,7 +44,7 @@
"node-graceful": "^3.1.0",
"parse5": "^7.0.0",
"picocolors": "^1.0.0",
"playwright": "^1.22.2",
"playwright": "^1.24.1",
"prettier": "^2.7.1",
"pretty-bytes": "^5.6.0",
"pretty-time": "^1.1.0",
Expand All @@ -62,8 +54,8 @@
"source-map": "^0.7.4",
"tslib": "^2.4.0",
"typescript": "^4.7.4",
"vite": "^2.9.12",
"vitest": "^0.16.0",
"vite": "^3.0.3",
"vitest": "^0.19.1",
"wait-on": "^6.0.1"
},
"scripts": {
Expand Down
19 changes: 0 additions & 19 deletions packages/esbd/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,25 +55,6 @@ export interface EsbdSpecificOptions {
*/
integrity?: HashAlgorithm;

/**
* React 17 introduced a new JSX transform that enables some internal performance
* optimizations and obviates having to import 'React' in every module.
*
* Though esbuild does not support this new transform natively, setting this option to
* `automatic` will add a load plugin (powered by SWC) for ".jsx" and ".tsx" files so
* they use the new tranform as expected.
*
* If you are using TypeScript, note that you should set the "jsx" tsconfig option to
* "react-jsx" so that your editor does not require the "React" import. esbd does not
* currently read this option from tsconfig.json, so "jsxRuntime" must be set to "automatic"
* explicitly for the new transform to be used.
*
* @see {@link https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html}
*
* @default "classic"
*/
jsxRuntime?: 'automatic' | 'classic';

/**
* Name of this configuration.
*
Expand Down
5 changes: 2 additions & 3 deletions packages/esbd/src/esbd-build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import { writeTemplate } from './html-entry-point';
import type { BuildIncrementalResult } from './incremental-build';
import { incrementalBuild } from './incremental-build';
import type { Logger } from './log';
import { swcPlugin } from './swc-plugin';
import { timingPlugin } from './timing-plugin';

interface EsbdBuildOptions {
Expand Down Expand Up @@ -84,7 +83,7 @@ async function esbdBuildHtml(
copy: config.copy,
incremental: true,
logger,
plugins: [...config.plugins, swcPlugin(config.jsxRuntime, mode), timingPlugin(logger, name)],
plugins: [...config.plugins, timingPlugin(logger, name)],
watch,
write: false,

Expand Down Expand Up @@ -125,7 +124,7 @@ async function esbdBuildSource(
copy: config.copy,
incremental: true,
logger,
plugins: [...config.plugins, swcPlugin(config.jsxRuntime, mode), timingPlugin(logger, name)],
plugins: [...config.plugins, timingPlugin(logger, name)],
watch,
write: false,

Expand Down
7 changes: 1 addition & 6 deletions packages/esbd/src/esbd-serve.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import { getHtmlBuildOptions } from './get-build-options';
import { writeTemplate } from './html-entry-point/write-template';
import { incrementalBuild } from './incremental-build';
import type { Logger } from './log';
import { swcPlugin } from './swc-plugin';
import { timingPlugin } from './timing-plugin';

interface EsbdServeConfig {
Expand Down Expand Up @@ -113,11 +112,7 @@ export default async function esbdServe(
copy: config.copy,
incremental: true,
logger,
plugins: [
...config.plugins,
swcPlugin(config.jsxRuntime, mode),
timingPlugin(logger, config.name && `"${config.name}"`),
],
plugins: [...config.plugins, timingPlugin(logger, config.name && `"${config.name}"`)],
watch: true,
onBuildResult: async (result, options) => {
if (!result.errors?.length) {
Expand Down
10 changes: 1 addition & 9 deletions packages/esbd/src/get-build-options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ export async function getHtmlBuildOptions(
const {
copy: _,
format = 'esm',
jsxRuntime: __,
integrity,
ignoreAssets,
name: ___,
Expand Down Expand Up @@ -99,14 +98,7 @@ export function getBuildOptions(
const outdir = config.outdir;
if (!outdir) throw new Error('"outdir" option must be set');

const {
copy: _,
jsxRuntime: __,
integrity: ___,
ignoreAssets: ____,
name: _____,
...options
} = config;
const { copy: _, integrity: ___, ignoreAssets: ____, name: _____, ...options } = config;

const allEntryPoints: EntryPoints = {};
for (const [entryName, entryPath] of entries) {
Expand Down
47 changes: 0 additions & 47 deletions packages/esbd/src/swc-plugin.ts

This file was deleted.

Loading