Skip to content

Commit

Permalink
v2.2.0 [publish]
Browse files Browse the repository at this point in the history
  • Loading branch information
ArnaudBarre committed Oct 30, 2022
1 parent a28b087 commit b5ca646
Show file tree
Hide file tree
Showing 11 changed files with 391 additions and 303 deletions.
11 changes: 6 additions & 5 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ jobs:
runs-on: ubuntu-latest
if: ${{ contains(github.event.head_commit.message, '[publish]') }}
steps:
- uses: actions/checkout@v2
- run: yarn install --frozen-lockfile
- run: yarn prettier-ci
- run: yarn build
- uses: ArnaudBarre/npm-publish@v1
- uses: actions/checkout@v3
- uses: xhyrom/setup-bun@v0.1.8
- run: bun install
- run: bun ci
- uses: ArnaudBarre/npm-publish@v1.1
with:
working-directory: dist
npm-token: ${{ secrets.NPM_TOKEN }}
4 changes: 1 addition & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
.idea/
node_modules/
*.js
*.d.ts
!src/refresh-runtime.js
dist/
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## 2.2.0

- Always provide parser options to fix issue with `.jsx` imports. Relying on file extension for this is more buggy [than I though](https://github.com/swc-project/swc/issues/3297)
- Extract line and column in SWC errors to make overlay filename clickable
- Fix plugin name (`react-refresh` -> `swc-react-refresh`)

## 2.1.0

Add source maps support
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# vite-plugin-swc-react-refresh [![npm](https://img.shields.io/npm/v/vite-plugin-swc-react-refresh)](https://www.npmjs.com/package/vite-plugin-swc-react-refresh)

Use the versatility of [swc](https://swc.rs/) for development and the maturity of [esbuild](https://esbuild.github.io/) for production.
Use the versatility of [SWC](https://swc.rs/) for development and the maturity of [esbuild](https://esbuild.github.io/) for production.

- ✅ A fast Fast Refresh (~20x faster than Babel)
- ✅ Compatible with [automatic JSX runtime](https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html)
Expand Down
Binary file added bun.lockb
Binary file not shown.
2 changes: 2 additions & 0 deletions bunfig.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[install.lockfile]
print = "yarn"
32 changes: 9 additions & 23 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,41 +1,27 @@
{
"name": "vite-plugin-swc-react-refresh",
"description": "Use the versatility of swc for development and the maturity of esbuild for production",
"version": "2.1.0",
"version": "2.2.0",
"license": "MIT",
"author": "Arnaud Barré (https://github.com/ArnaudBarre)",
"main": "src/swc-react-refresh.js",
"files": [
"src/*.js",
"src/*.d.ts"
],
"repository": "github:ArnaudBarre/vite-plugin-swc-react-refresh",
"keywords": [
"vite",
"vite-plugin",
"react",
"swc",
"react-refresh",
"fast refresh"
],
"scripts": {
"build": "tsc",
"build": "scripts/bundle.ts",
"prettier": "yarn prettier-ci --write",
"prettier-ci": "prettier --check '**/*.{js,ts,json,md,yml}'"
"prettier-ci": "prettier --ignore-path=.gitignore --check '**/*.{js,ts,json,md,yml}'",
"ci": "tsc && bun prettier-ci && bun run build"
},
"prettier": {
"trailingComma": "all"
},
"dependencies": {
"@swc/core": "^1.2.245"
"@swc/core": "^1.3.10"
},
"peerDependencies": {
"vite": "^2 || ^3"
},
"devDependencies": {
"@types/node": "^18.0.6",
"@nabla/tnode": "^0.7.0",
"@types/node": "^18.11.4",
"prettier": "^2.7.1",
"typescript": "^4.7.4",
"vite": "^3.0.5"
"typescript": "^4.8.4",
"vite": "^3.2.1"
}
}
57 changes: 57 additions & 0 deletions scripts/bundle.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#!/usr/bin/env tnode
import { rmSync, writeFileSync } from "fs";
import { execSync } from "child_process";
import { build } from "esbuild";

import * as packageJSON from "../package.json";

rmSync("dist", { force: true, recursive: true });

build({
bundle: true,
entryPoints: ["src/index.ts"],
outdir: "dist",
platform: "node",
target: "node14",
legalComments: "inline",
external: Object.keys(packageJSON.peerDependencies).concat(
Object.keys(packageJSON.dependencies),
),
}).then(() => {
execSync("cp src/refresh-runtime.js LICENSE README.md dist/");

writeFileSync(
"dist/index.d.ts",
`import { PluginOption } from "vite";
export declare const swcReactRefresh: () => PluginOption;
`,
);

writeFileSync(
"dist/package.json",
JSON.stringify(
{
name: packageJSON.name,
description:
"Use the versatility of SWC for development and the maturity of esbuild for production",
version: packageJSON.version,
author: "Arnaud Barré (https://github.com/ArnaudBarre)",
license: packageJSON.license,
repository: "github:ArnaudBarre/vite-plugin-swc-react-refresh",
main: "index.js",
keywords: [
"vite",
"vite-plugin",
"react",
"swc",
"react-refresh",
"fast refresh",
],
peerDependencies: packageJSON.peerDependencies,
dependencies: packageJSON.dependencies,
},
null,
2,
),
);
});
69 changes: 46 additions & 23 deletions src/swc-react-refresh.ts → src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import fs from "fs";
import path from "path";
import { readFileSync } from "fs";
import { join, extname } from "path";
import { SourceMapPayload } from "module";
import { transform } from "@swc/core";
import { Output, ParserConfig, transform } from "@swc/core";
import { PluginOption } from "vite";

const runtimePublicPath = "/@react-refresh";
Expand All @@ -16,8 +16,15 @@ const importReactRE = /(^|\n)import\s+(\*\s+as\s+)?React(,|\s+)/;
let define: { [key: string]: string } | undefined;
let automaticRuntime = false;

const parserMap = new Map<string, ParserConfig>([
[".tsx", { syntax: "typescript", tsx: true }],
[".ts", { syntax: "typescript", tsx: false }],
[".jsx", { syntax: "ecmascript", jsx: true }],
[".js", { syntax: "ecmascript", jsx: false }],
]);

export const swcReactRefresh = (): PluginOption => ({
name: "react-refresh",
name: "swc-react-refresh",
apply: "serve",
config: (config) => {
if (config.esbuild) {
Expand All @@ -34,33 +41,49 @@ export const swcReactRefresh = (): PluginOption => ({
resolveId: (id) => (id === runtimePublicPath ? id : undefined),
load: (id) =>
id === runtimePublicPath
? fs.readFileSync(path.join(__dirname, "refresh-runtime.js"), "utf-8")
? readFileSync(join(__dirname, "refresh-runtime.js"), "utf-8")
: undefined,
transformIndexHtml: () => [
{ tag: "script", attrs: { type: "module" }, children: preambleCode },
],
async transform(code, id) {
if (id.includes("node_modules")) return;
if (!/\.[jt]sx?$/.test(id)) return;

const result = await transform(code, {
filename: id,
swcrc: false,
configFile: false,
sourceMaps: true,
jsc: {
target: "es2020",
transform: {
react: {
refresh: true,
development: true,
useBuiltins: true,
runtime: automaticRuntime ? "automatic" : undefined,
const parser = parserMap.get(extname(id));
if (!parser) return;

let result: Output;
try {
result = await transform(code, {
filename: id,
swcrc: false,
configFile: false,
sourceMaps: true,
jsc: {
target: "es2020",
parser,
transform: {
react: {
refresh: true,
development: true,
useBuiltins: true,
runtime: automaticRuntime ? "automatic" : undefined,
},
optimizer: { globals: { vars: define } },
},
optimizer: { globals: { vars: define } },
},
},
});
});
} catch (e: any) {
const message: string = e.message;
const fileStartIndex = message.indexOf("╭─[");
if (fileStartIndex !== -1) {
const match = message.slice(fileStartIndex).match(/:(\d+):(\d+)]/);
if (match) {
e.line = match[1];
e.column = match[2];
}
}
throw e;
}
let mappingPrefix = "";

if (
Expand Down
6 changes: 4 additions & 2 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,16 @@
"module": "CommonJS",
"lib": ["ES2020"],
"target": "ES2020",
"declaration": true,
"skipLibCheck": true,

/* Transpile with esbuild */
"noEmit": true,
"isolatedModules": true,

/* Imports */
"moduleResolution": "node", // Allow `index` imports
"resolveJsonModule": true, // Allow json import
"forceConsistentCasingInFileNames": true, // Avoid difference in case between file name and import
"esModuleInterop": true, // Allow import fs from "fs"

/* Linting */
"strict": true,
Expand Down
Loading

0 comments on commit b5ca646

Please sign in to comment.