-
-
Notifications
You must be signed in to change notification settings - Fork 6.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Node.js Core Module Support #7821
Comments
What about using |
I didn't know that was an option, thanks!
Understandable, I'll leave this issue open for future consideration. As a relevant topic, #7810 seems to suggest rather than adding an additional config key, it might be better to just use the It would make sense to determine if there are any other things that are Node-specific that Vite currently doesn't handle properly such as |
@bluwy As @DecliningLotus said is what I think. |
I think the same too, though the official way Vite is handling Node-stuff now is through the Would love to hear how y'all are using Vite (with examples?) so that we can be more opinionated and handle all them through the smallest set of config @DecliningLotus @alex8088 |
@bluwy I'll be happy to share what I'm working on in the near future here since it's library starter for everyone to use. Just held up with some other commitments. As for the SSR option, that might be ideal, I'll play around with it. Thanks! |
@bluwy , my usecase: I use Vite in my Electron project to bundle my code. In Electron projects, node.js and browser environments need to be handled at the same time. In a node.js environment (the main process), developers will only use Vite's build mode instead of serve mode. In this case, |
Note: I found another case where |
@bluwy, I'm not sure whether to bring this up in #6812, but I think SSR is a blocker for me as I need to offer an option to output both CJS and ES at the same time. Quite frankly the workarounds using the normal build config offer more flexibility than SSR. My formats: ["es", "cjs"],
fileName: (format) =>
`${name}.${format}.${format === "es" ? "mjs" : "js"}`, Creating two bundles of I could just run it twice to handle both formats, but that feels like a clunkier workaround than without SSR. |
Having the same issue here. Having a clear target as previously mentioned would be the most rational and elegant solution IMO. Here is the import { defineConfig } from "vite"
export const name = "node-polyfills"
export default defineConfig({
build: {
target: "ESNext",
lib: {
name,
entry: "src/index.ts",
fileName: (format) => `${name}.${format}.js`,
},
sourcemap: true,
rollupOptions: {
external: [
"node:util",
"node:buffer",
"node:stream",
"node:net",
"node:url",
"node:fs",
"node:path",
"perf_hooks",
],
output: {
globals: {
"node:stream": "stream",
"node:buffer": "buffer",
"node:util": "util",
"node:net": "net",
"node:url": "url",
perf_hooks: "perf_hooks",
},
inlineDynamicImports: true,
},
},
},
}) Best solution IMO: {
build: {
target: "node12"
}
}
require('esbuild').buildSync({
entryPoints: ['app.js'],
target: [
'es2020',
'chrome58',
'edge16',
'firefox57',
'ie11',
'ios10',
'node12',
'opera45',
'safari11',
],
outfile: 'out.js',
}) However if I try
|
Anyone seen this? https://esbuild.github.io/getting-started/#bundling-for-node Could this option be used for targeting the Keep wondering what responsibilities |
I could imagine that if |
I have a similar use case. I need to SSR my app and bundle dependencies as I'll deploy to a serverless environment. The SSR part uses core modules such as Unfortunately, providing
but I believe Is there any way to do this? |
For anyone struggling with this, I'm importing package.json and specifying the dependencies as If you need a list of built-in modules anyways, here's how to do it: import { builtinModules as builtin } from "node:module"; You can see an example here: stormkit-io/monorepo-template-react@01704b5#diff-78f8b638be47e5d535453248b4cbfa52bb6d9a306abf44ce2f5b167facb32ad5R11 Though, bear in mind that reading package.json may not be a viable solution because it lists only direct dependencies. You can also get the full list of dependencies from node_modules instead. |
Is there a full example anywhere of how to build a library for Node? I need to create some wrappers around my Nuxt server and would like my code for that bundled together, but it runs into problems with things like My working Webpack Config: export default {
mode: 'production',
entry: path.join(__dirname, 'index.js'),
output: {
path: path.join(__dirname, '../../.output/'),
filename: 'cloud-entry-webpack.cjs',
library: {
name: 'cloudEntry',
type: 'umd'
}
},
target: 'node16'
}; Broken Vite config: const builtins = builtinModules.filter(m => !m.startsWith('_')); builtins.push(...builtins.map(m => `node:${m}`));
export default defineConfig({
build: {
target: 'node12',
outDir: path.join(__dirname, '../../.output/'),
lib: {
entry: path.join(__dirname, 'index.js'),
fileName: 'cloud-entry',
name: 'cloudEntry',
formats: ['umd']
},
rollupOptions: {
external: [...builtins]
}
},
optimizeDeps: {
exclude: [...builtins]
}
}); |
https://www.npmjs.com/package/vite-plugin-node-polyfills seems to be the offical version, works fine for me. |
Hi, I'm struggling trying to bundle for a Node target and this thread seems to be related. I hope someone can point out where I'm going wrong. Here is my config: https://gist.github.com/0x80/586283af54ff2b8a436a01a4b62bcea6 I have tried the config with and without the globals declaration. I suspect that I shouldn't use the globals as these core modules are not available as a global, but in either case, when I execute the result like file:///something/something/dist/index.js:24680
const crypto$8 = crypto, isCryptoKey = (r) => r instanceof CryptoKey, digest = async (r, e) => {
^
ReferenceError: crypto is not defined What do I need to do to make Vite understand that "crypto" should be an imported core module? |
For anyone reading, I'm able to externalize node core libs with this config:
I'm building a boilerplate for a Typescript+Lambda monorepo and this would be placed in a function's folder. The idea is that common libs will be imported from a folder outside the function's folder, but be bundled during build time. The assumption is that the Lambda runtime will have node core lib's available. I haven't gotten to the CI/CD point yet, but I'm thinking issues might come up then, especially if your CI is trying to figure out if it should build a function and deploy it or not. If anyone's gone down this road, let me know, would love to get some pointers. |
Wouldn't this simply be enough? import { builtinModules } from 'module';
export default defineConfig({
/* ... */
build: {
rollupOptions: {
external: [...builtinModules, /^node:/]
}
}
} |
Library mode still seems to be trying to create a browser bundle even when 'node' is specified as the target. I've run into problems with libraries that have browser specific sources (eg. via tha 'browser' field in package.json) |
I was able to solve this using the external both, inside rollupConfig and inside ssr:
This will bundle absolutely everything while in production except the node built in modules. |
I found that using a glob array |
To get this working during development and in production for a React app I had to use the following config. import { builtinModules } from "node:module";
export default defineConfig({
...,
ssr: {
external: [...builtinModules, ...builtinModules.map((m) => `node:${m}`)],
noExternal: process.env.NODE_ENV === "production" ? [/.*/] : undefined
}
}); If i just had |
Also interested in this for using https://github.com/observablehq/framework for certain pages and vite / nuxt to enable SSR for these pages to be dynamically generated & routed. |
I just want to build a nodejs native package, hope vite provide option |
vitejs/vite#7821 import { builtinModules } from 'module'; export default defineConfig({ /* ... */ build: { rollupOptions: { external: [...builtinModules, /^node:/] } } }
Leaving a reference here for a related issue with resolve conditions from @cpojer #17531. For Vite 6, we're working on a new Environment API proposal https://deploy-preview-16471--vite-docs-main.netlify.app/guide/api-vite-environment.html. I would appreciate feedback from the folks involved in this issue. I'll add this one to the Vite 6 milestone so we can take into considerations during the next months. |
Hi there! I'm leaving this repository here as it seems to have an interesting approach on building Node.js apps: https://www.npmjs.com/package/@liuli-util/vite-plugin-node |
The gist of the discussion so far is that there's a need for:
no2 is currently out-of-scope for us as we intend library mode (for building libraries) to work for browsers only. It's possible to tweak and build for node, but we don't aim to have that usecase covered. This is currently documented at the bottom of this section. For no1, I believe this has been addressed by Vite 6's environment API. While perhaps requiring additional setup still, it provides the primitives and infrastructure to do so, which I think should suffice for more exploration in this area. The API is still experimental and malleable, so any feedback in improving that would be appreciated at #16358. For other requests, I think this discussion has become a little broad to keep track of. I'd suggest opening a discussion if there's something specific you'd like to see, and we can work something out from there. With the above, I'll close this issue for now. |
Clear and concise description of the problem
This might seem like a very weird use case for Vite, but I've been experimenting with developing a framework to develop normal Node.js libraries or even CLIs using Vite as the core. Hugely inspired by how Vitest works with vite-node, it aims to centralise all the previous build tools (tsc, rollup, testing etc.) into one convenient package using the same Vite config. Plain, simple and easy to setup a modern ESM-first TS project with far less dependencies to go around. So far, the watch mode uses the normal esbuild transforms, rollup for production etc. Essentially a modern TSDX replacement, I've been pleasantly surprised that Vite makes a good fit even if it isn't the original intended use case.
Which leads to one slight hiccup. Vite does not really support any libraries that call Node.js core modules since the intended target is browsers only.
For example, trying to develop a CLI using cac returns the following error when running
vite build
:A workaround is to update
rollupOptions.external
to include the"events"
library (and also"node:events"
). This isn't ideal considering there are many core Node.js modules, thus it'd be better to resolve this upstream.Suggested solution
My proposal is to add an additional option in the Vite config that allows the resolver to ignore any imports that call the Node.js built-in modules. It could probably be a boolean value with the key
node
?I feel an option like that could also let a different type of ecosystem to thrive and we may see more interesting Node-based projects using Vite, especially due to vite-node.
EDIT (@bluwy): We may also want to verify if the Environment API helps enable a flexible configuration for nodejs environments instead of relying on
build.ssr: true
.Alternative
#2694 (comment) is the most similar issue I've found, although the solution is not optimal in the above-given context as the libraries are not intended for the browser.
Additional context
No response
Validations
The text was updated successfully, but these errors were encountered: