Node built-in modules support for Deno adapter (#7288)

* feature(deno adapter): allow built-in node modules

* Add changeset

* format
This commit is contained in:
Arsh 2023-06-15 19:50:35 +05:30 committed by GitHub
parent 3f1cb6b1a0
commit d67ae84610
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 94 additions and 4 deletions

View file

@ -0,0 +1,5 @@
---
'@astrojs/deno': minor
---
The deno adapter now supports npm package that require built-in node modules.

View file

@ -148,7 +148,7 @@ jobs:
- name: Use Deno
uses: denoland/setup-deno@v1
with:
deno-version: v1.26.1
deno-version: v1.34.1
- name: Install dependencies
run: pnpm install

View file

@ -21,6 +21,59 @@ const SHIM = `globalThis.process = {
};`;
const DENO_VERSION = `0.177.0`;
// REF: https://github.com/denoland/deno/tree/main/ext/node/polyfills
const COMPATIBLE_NODE_MODULES = [
'assert',
'assert/strict',
'async_hooks',
'buffer',
'child_process',
'cluster',
'console',
'constants',
'crypto',
'dgram',
'diagnostics_channel',
'dns',
'events',
'fs',
'fs/promises',
'http',
// 'http2',
'https',
'inspector',
'module',
'net',
'os',
'path',
'path/posix',
'path/win32',
'perf_hooks',
'process',
'punycode',
'querystring',
'readline',
'repl',
'stream',
'stream/promises',
'stream/web',
'string_decoder',
'sys',
'timers',
'timers/promises',
// 'tls',
'trace_events',
'tty',
'url',
'util',
'util/types',
// 'v8',
// 'vm',
// 'wasi',
// 'webcrypto',
'worker_threads',
'zlib',
];
// We shim deno-specific imports so we can run the code in Node
// to prerender pages. In the final Deno build, this import is
@ -51,6 +104,14 @@ const denoImportsShimPlugin = {
},
};
const denoRenameNodeModulesPlugin = {
name: '@astrojs/esbuild-rename-node-modules',
setup(build: esbuild.PluginBuild) {
const filter = new RegExp(COMPATIBLE_NODE_MODULES.map((mod) => `(^${mod}$)`).join('|'));
build.onResolve({ filter }, (args) => ({ path: 'node:' + args.path, external: true }));
},
};
export default function createIntegration(args?: Options): AstroIntegration {
let _buildConfig: BuildConfig;
let _vite: any;
@ -89,7 +150,7 @@ export default function createIntegration(args?: Options): AstroIntegration {
}
}
vite.ssr = {
noExternal: true,
noExternal: COMPATIBLE_NODE_MODULES,
};
if (Array.isArray(vite.build.rollupOptions.external)) {
@ -114,8 +175,11 @@ export default function createIntegration(args?: Options): AstroIntegration {
allowOverwrite: true,
format: 'esm',
bundle: true,
external: ['@astrojs/markdown-remark'],
plugins: [denoImportsShimPlugin],
external: [
...COMPATIBLE_NODE_MODULES.map((mod) => `node:${mod}`),
'@astrojs/markdown-remark',
],
plugins: [denoImportsShimPlugin, denoRenameNodeModulesPlugin],
banner: {
js: SHIM,
},

View file

@ -104,6 +104,12 @@ Deno.test({
assertEquals(h1!.innerText, 'test');
});
await t.step('node compatibility', async () => {
const resp = await fetch(new URL('/nodecompat', app.url));
assertEquals(resp.status, 200);
await resp.text();
});
app.stop();
},
});

View file

@ -0,0 +1,15 @@
---
// unprefixed node built-in module
import path from 'path'
// prefixed node built-in module
import os from 'node:os'
---
<body>
<a href={path.posix.basename('/public/myfile.html')}>Go to my file</a>
<details>
<summary>CPU Architecture</summary>
<code>{os.arch()}</code>
</details>
<p>Everything went fine.</p>
</body>