unenv
unenv copied to clipboard
Can this tool be used with esbuild?
I tried to use this tool with esbuild to build a Cloudflare worker. I need to use a library that has dependencies on node libs like fs.
I tried:
import buildAlias form 'esbuild-plugin-alias`
import { env, nodeless } from 'unenv'
const { alias } = env(nodeless)
async function main() {
...
const result = await build({
...
plugins[buildAlias(alias)],
...
})
}
main()
I ended up getting a bunch of warnings from esbuild b/c the esbuild requires absolute paths and the paths supplied in the nodeless presets are relative.
Any thoughts about how to get this to work?
It can be used by resolving it to an absolute path using require.resolve.
We currently use a plugin like this one. (ESM style. may need some rewrite for CJS)
import { createRequire } from 'module';
import { join } from 'path';
import { build } from 'esbuild';
import { nodeless } from 'unenv';
/** @type {(plugin: import('esbuild').Plugin) => import('esbuild').Plugin} */
const definePlugin = (plugin) => plugin;
const nodelessPlugin = definePlugin({
name: 'unenv-nodeless',
setup(build) {
const alias = nodeless.alias;
const re = new RegExp(`^(${Object.keys(alias).join('|')})$`); // this should be escaped
const require = createRequire(import.meta.url);
const aliasAbsolute = Object.fromEntries(
Object.entries(alias).map(([key, value]) => [
key,
require.resolve(value).replace(/\.cjs$/, '.mjs'),
])
);
build.onResolve(
{
filter: re,
},
(args) => {
const result = aliasAbsolute[args.path];
return result ? { path: result } : undefined;
}
);
},
});
build({
entryPoints: ['./src/index.ts'],
outfile: 'dist/index_dev.js',
platform: 'browser',
bundle: true,
format: 'esm',
logLevel: 'info',
plugins: [nodelessPlugin],
});
We plan to add an unplugin to unenv for easier integration. Lets track via #263