Skip to content
This repository has been archived by the owner on Apr 25, 2024. It is now read-only.

Commit

Permalink
use SWC to transpile
Browse files Browse the repository at this point in the history
  • Loading branch information
bruceharrison1984 committed Apr 24, 2024
1 parent b21b4d0 commit 5fa905a
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 91 deletions.
8 changes: 4 additions & 4 deletions example/react-app/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion example/react-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.6",
"typescript": "^5.2.2",
"vite": "^5.2.8",
"vite": "^5.2.10",
"wrangler": "^3.49.0"
}
}
181 changes: 95 additions & 86 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,27 @@ import type { Options as SWCOptions } from '@swc/core';
let wranglerDevServer: UnstableDevWorker;

const defaults: SWCOptions = {
minify: true,
jsc: {
target: 'esnext',
parser: {
tsx: true,
syntax: 'typescript',
decorators: true,
},
transform: {
decoratorMetadata: true,
legacyDecorator: true,
},
minify: {
compress: true,
mangle: true,
},
loose: true,
},
};

export default function viteWranglerSpa(config?: CloudflareSpaConfig): PluginOption {
export default function viteWranglerSpa(config?: CloudflareSpaConfig): PluginOption[] {
const functionEntrypoint = config?.functionEntrypoint || 'functions/index.ts';
const wranglerConfig = config?.wranglerConfig || {
logLevel: 'log',
Expand All @@ -41,106 +47,109 @@ export default function viteWranglerSpa(config?: CloudflareSpaConfig): PluginOpt
const excludedApiPaths = config?.excludedApiPaths || [];
const functionExternals = config?.external || [];

return {
name: 'vite-wrangler-spa',

config(config) {
return {
ssr: {
external: functionExternals,
noExternal: true,
},
build: {
minify: config.build?.minify,
rollupOptions: {
external: [...builtinModules, /^node:/],
input: functionEntrypoint,
preserveEntrySignatures: 'allow-extension',
output: { entryFileNames: '_worker.js' },
return [
{
name: 'vite-wrangler-spa',

config(config) {
return {
ssr: {
external: functionExternals,
noExternal: true,
},
emptyOutDir: false,
ssr: true,
},
};
},
esbuild: false,
build: {
minify: config.build?.minify,
rollupOptions: {
external: [...builtinModules, /^node:/],
input: functionEntrypoint,
preserveEntrySignatures: 'allow-extension',
output: { entryFileNames: '_worker.js' },
},
emptyOutDir: false,
ssr: true,
},
};
},

transform(code) {
return transform(code, {
...defaults,
sourceMaps: true,
});
},
transform(code) {
return transform(code, {
...defaults,
sourceMaps: true,
});
},

/** Start the wrangler miniflare server */
configureServer: async (devServer) => {
if (!wranglerDevServer) {
wranglerDevServer = await unstable_dev(functionEntrypoint, wranglerConfig);
}
/** Start the wrangler miniflare server */
configureServer: async (devServer) => {
if (!wranglerDevServer) {
wranglerDevServer = await unstable_dev(functionEntrypoint, wranglerConfig);
}

//setup middleware to redirect requests to miniflare
devServer.middlewares.use(async (req, res, next) => {
const { url } = req;
if (url === undefined) throw new Error('url is undefined!');
//setup middleware to redirect requests to miniflare
devServer.middlewares.use(async (req, res, next) => {
const { url } = req;
if (url === undefined) throw new Error('url is undefined!');

if (excludedApiPaths.find((x) => new RegExp(x).test(url))) return next();
if (excludedApiPaths.find((x) => new RegExp(x).test(url))) return next();

/** only direct specific requests to the miniflare server so the SPA still renders correctly */
if (allowedApiPaths.find((x) => new RegExp(x).test(url))) {
console.log(url);
const resp = await makeWranglerFetch(req, wranglerDevServer);
/** only direct specific requests to the miniflare server so the SPA still renders correctly */
if (allowedApiPaths.find((x) => new RegExp(x).test(url))) {
console.log(url);
const resp = await makeWranglerFetch(req, wranglerDevServer);

convertWranglerResponse(resp, res);
return res;
}
convertWranglerResponse(resp, res);
return res;
}

// skip miniflare and serve requested URL from the SPA application
return next();
});
},

// /** Send HMR message to browser to reload page and emit message whenever Functions file changes */
async handleHotUpdate(ctx) {
if (ctx.file.includes(functionEntrypoint.split('/')[0]))
ctx.server.hot.send({
type: 'custom',
event: 'function-update',
data: { file: ctx.file },
// skip miniflare and serve requested URL from the SPA application
return next();
});
},

/** setup listener on dev mode page */
transformIndexHtml: {
order: 'pre',
handler: () => [
{
tag: 'script',
attrs: { type: 'module' },
children: `
},

// /** Send HMR message to browser to reload page and emit message whenever Functions file changes */
async handleHotUpdate(ctx) {
if (ctx.file.includes(functionEntrypoint.split('/')[0]))
ctx.server.hot.send({
type: 'custom',
event: 'function-update',
data: { file: ctx.file },
});
},

/** setup listener on dev mode page */
transformIndexHtml: {
order: 'pre',
handler: () => [
{
tag: 'script',
attrs: { type: 'module' },
children: `
if (import.meta.hot) {
let outputColor = "color:cyan; font-weight:bold;"
import.meta.hot.on('function-update', (data) => {
console.log(\`%c 🔥 Cloudflare Pages Function - update detected in file: '\${data.file}'\`, outputColor);
location.reload(true);
});
}`,
},
],
},

/** Create a _routes file to avoid functions from firing on all routes and intercepting SPA traffic */
writeBundle() {
writeFileSync(
'dist/_routes.json',
JSON.stringify(
{
version: 1,
include: allowedApiPaths,
exclude: excludedApiPaths,
},
null,
2
)
);
},
} as Plugin;
],
},

/** Create a _routes file to avoid functions from firing on all routes and intercepting SPA traffic */
writeBundle() {
writeFileSync(
'dist/_routes.json',
JSON.stringify(
{
version: 1,
include: allowedApiPaths,
exclude: excludedApiPaths,
},
null,
2
)
);
},
} as Plugin,
];
}

0 comments on commit 5fa905a

Please sign in to comment.