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:
parent
3f1cb6b1a0
commit
d67ae84610
5 changed files with 94 additions and 4 deletions
5
.changeset/modern-lobsters-sparkle.md
Normal file
5
.changeset/modern-lobsters-sparkle.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
'@astrojs/deno': minor
|
||||||
|
---
|
||||||
|
|
||||||
|
The deno adapter now supports npm package that require built-in node modules.
|
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
|
@ -148,7 +148,7 @@ jobs:
|
||||||
- name: Use Deno
|
- name: Use Deno
|
||||||
uses: denoland/setup-deno@v1
|
uses: denoland/setup-deno@v1
|
||||||
with:
|
with:
|
||||||
deno-version: v1.26.1
|
deno-version: v1.34.1
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: pnpm install
|
run: pnpm install
|
||||||
|
|
|
@ -21,6 +21,59 @@ const SHIM = `globalThis.process = {
|
||||||
};`;
|
};`;
|
||||||
|
|
||||||
const DENO_VERSION = `0.177.0`;
|
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
|
// We shim deno-specific imports so we can run the code in Node
|
||||||
// to prerender pages. In the final Deno build, this import is
|
// 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 {
|
export default function createIntegration(args?: Options): AstroIntegration {
|
||||||
let _buildConfig: BuildConfig;
|
let _buildConfig: BuildConfig;
|
||||||
let _vite: any;
|
let _vite: any;
|
||||||
|
@ -89,7 +150,7 @@ export default function createIntegration(args?: Options): AstroIntegration {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
vite.ssr = {
|
vite.ssr = {
|
||||||
noExternal: true,
|
noExternal: COMPATIBLE_NODE_MODULES,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (Array.isArray(vite.build.rollupOptions.external)) {
|
if (Array.isArray(vite.build.rollupOptions.external)) {
|
||||||
|
@ -114,8 +175,11 @@ export default function createIntegration(args?: Options): AstroIntegration {
|
||||||
allowOverwrite: true,
|
allowOverwrite: true,
|
||||||
format: 'esm',
|
format: 'esm',
|
||||||
bundle: true,
|
bundle: true,
|
||||||
external: ['@astrojs/markdown-remark'],
|
external: [
|
||||||
plugins: [denoImportsShimPlugin],
|
...COMPATIBLE_NODE_MODULES.map((mod) => `node:${mod}`),
|
||||||
|
'@astrojs/markdown-remark',
|
||||||
|
],
|
||||||
|
plugins: [denoImportsShimPlugin, denoRenameNodeModulesPlugin],
|
||||||
banner: {
|
banner: {
|
||||||
js: SHIM,
|
js: SHIM,
|
||||||
},
|
},
|
||||||
|
|
|
@ -104,6 +104,12 @@ Deno.test({
|
||||||
assertEquals(h1!.innerText, '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();
|
app.stop();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
15
packages/integrations/deno/test/fixtures/basics/src/pages/nodecompat.astro
vendored
Normal file
15
packages/integrations/deno/test/fixtures/basics/src/pages/nodecompat.astro
vendored
Normal 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>
|
Loading…
Reference in a new issue