vite
vite copied to clipboard
Support external in dev
Clear and concise description of the problem
When I have external dependencies that are not a npm package, vite dev server throws an error in vite:import-analysis
stage. vite build
command just works fine but vite
command tries to resolve all of the external dependencies in the import-analysis stage.
Suggested solution
Skip resolving the external dependencies in import-analysis.
Alternative
No response
Additional context
No response
Validations
- [X] Follow our Code of Conduct
- [X] Read the Contributing Guidelines.
- [X] Read the docs.
- [X] Check that there isn't already an issue that request the same feature to avoid creating a duplicate.
As noted in https://github.com/vitejs/vite/pull/6583#issuecomment-1024148754, it would be great if you can explain how you encountered the issue and what error it gives. That would help us evaluate the correct fix for it.
I created an example repo to demonstrate the error: https://github.com/hasangenc0/vite-externaldep-error
Thanks for the example @hasangenc0. I tried implementing this at https://github.com/bluwy/vite/tree/rollup-options-external. Turns out there's a lot more to be done to fully support externalizing deps.
I think I got it nearly done, except that we can't just leave import 'external-dep
in the browser as it has the import has to start with .
or `'/', that means implementing https://rollupjs.org/guide/en/#makeabsoluteexternalsrelative. That might be an endeavor for another day.
If you'd like you can build on top of my changes, or update #6583 with it. I think #6583 at its current state isn't sufficient.
A workaround mentioned in https://github.com/vitejs/vite/issues/6393#issuecomment-1006819717 might help for now.
Any updates?
dev external
is very useful to build third party libs only privide .d.ts.
Besides the implementation not being done yet, in a recent team meeting we discussed to have the new option at resolve.external
to support both dev and build. I haven't got time to follow-up on my changes, so un-assigning myself in case someone is interested in implementing it.
I think I got it nearly done, except that we can't just leave
import 'external-dep'
in the browser as it has the import has to start with . or `'/', that means implementing rollupjs.org/guide/en/#makeabsoluteexternalsrelative. That might be an endeavor for another day.
@bluwy do you have a good example of this one? I think import 'external-dep'
may only work if the user defines an import map for it. In that case, we don't need to add something extra (except maybe a warning, but that could be hard to implement if there are multiple HTML entry points or a framework is used).
I saw that #12711 was closed in favor of keeping this issue open. Is there any plan to resolve this?
In my digging it seems like the dev server uses ESBuild for module resolution. Why is there no built in support for ESBuild's external API?
I'm not sure if this is related or not but I see the exported interface for the ESBuild plugin references exclude
instead of internal on this line: https://github.com/vitejs/vite/blob/main/packages/vite/src/node/plugins/esbuild.ts#L42
I could not find an exclude
option in ESBuild's API.
@bluwy do you have a good example of this one? I think
import 'external-dep'
may only work if the user defines an import map for it. In that case, we don't need to add something extra (except maybe a warning, but that could be hard to implement if there are multiple HTML entry points or a framework is used).
I implemented the stuff before I was familiar about importmaps, so yeah I think importmaps could be a good reason that we can leave that as-is for now. Supporting makeAbsoluteExternalsRelative
could still be nice but can be implemented later.
@Djfaucette I don't have any plans for now so I added the "contributions welcome" label. Maybe one day I'll revisit if I can get the motivation 😬 This shouldn't meddle with esbuild at all, except for Vite's optimizer that uses esbuild, which we need to pass the external
there. We don't use esbuild for module resolution.
hello, I am trying to create a lib, that externalize Firebase, but it does not works. rollupOptions: { // make sure to externalize deps that shouldn't be bundled // into your library external: ['firebase'] } I have used this code in vite.config.js, but, but the rollup-plugin-visualizer, I can observe that the firebase dependency is included in my library. Is that normal ? tks
I have created a plugin to solve this issue during development, until official support is implemented:
https://github.com/MilanKovacic/vite-plugin-externalize-dependencies
Another use case here: we have a custom browser-like JS runtime that provides built-in modules similar to Node's node:*
. That would be great to have an option to externalize by glob, regexp, or a resolver function (similar to rollupOptions.external
)
plz notice me once the issue is resolved.
plz notice me once the issue is resolved.
Hi @thjjames please use the Subscribe button instead of leaving a comment in the future: https://docs.github.com/en/account-and-profile/managing-subscriptions-and-notifications-on-github/viewing-and-triaging-notifications/triaging-a-single-notification#customizing-when-to-receive-future-updates-for-an-issue-or-pull-request
As it took me some time to figure out a simple workaround without needing some plugin, I want to share my solution here.
As it is possible to ignore dynamic imports with /* @vite-ignore */
we can make us of this:
const moduleName = '@code/some-module';
const module = await import(/* @vite-ignore */ moduleName);
module.someExportedFunction()
Using the string directly in the import
function does not work. My guess is that vite only ignores it if the import is using a variable and not a static string.
The error Pre-transform error: Failed to load url XXX
when using the workaround proposed in https://github.com/vitejs/vite/issues/6393#issuecomment-1006819717 can be fixed by adding the following method after the resolveId
method:
load( id ) {
if ( dependencies.includes( id ) ) {
return '';
}
}
Alternatively, you can disable pre-transformation like so:
// vite.config.js
export default {
server: {
preTransformRequests: false
}
};
In addition to the fix in https://github.com/vitejs/vite/issues/6582#issuecomment-1988662224, the linked code also doesn't handle base url, so here's a fix:
// 2. push a plugin to rewrite the 'vite:import-analysis' prefix
configResolved(resolvedConfig) {
const VALID_ID_PREFIX = '@id/'
const base = escapeRegExp(resolvedConfig.base ?? '/')
const externalsString = externals.map(external => escapeRegExp(external)).join('|')
const reg = new RegExp(
`${base}${VALID_ID_PREFIX}(${externalsString})`,
'g',
)
resolvedConfig.plugins.push({
name: 'vite-plugin-ignore-static-import-replace-idprefix',
transform: (code) => {
return reg.test(code) ? code.replace(reg, (m, s1) => s1) : code
},
})
},
escapeRegExp if from lodash
FWIW, I was able to get vite to load from CDN in debug mode without any plugins by using the resolve.alias
option. See
Once the proper alias is defined vite seems to load the bundles from the url specified in the alias rathe then .vite/deps
.
Hope this helps someone!