Skip to content
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

Support external in dev #6582

Open
4 tasks done
hasangenc0 opened this issue Jan 21, 2022 · 20 comments
Open
4 tasks done

Support external in dev #6582

hasangenc0 opened this issue Jan 21, 2022 · 20 comments
Labels
contribution welcome enhancement New feature or request p2-edge-case Bug, but has workaround or limited in scope (priority)

Comments

@hasangenc0
Copy link

hasangenc0 commented Jan 21, 2022

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

@bluwy
Copy link
Member

bluwy commented Apr 3, 2022

As noted in #6583 (comment), 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.

@hasangenc0
Copy link
Author

I created an example repo to demonstrate the error:
https://github.com/hasangenc0/vite-externaldep-error

@bluwy
Copy link
Member

bluwy commented Jun 12, 2022

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.

@bluwy
Copy link
Member

bluwy commented Jun 23, 2022

A workaround mentioned in #6393 (comment) might help for now.

@bluwy bluwy changed the title Don't include external dependencies to import-analysis Support external in dev Jun 26, 2022
@bluwy bluwy self-assigned this Jun 26, 2022
@terwer
Copy link

terwer commented May 13, 2023

Any updates?

dev external is very useful to build third party libs only privide .d.ts.

@bluwy
Copy link
Member

bluwy commented May 14, 2023

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.

@patak-dev
Copy link
Member

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).

@Djfaucette
Copy link

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?

@Djfaucette
Copy link

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
Copy link
Member

bluwy commented May 16, 2023

@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.

@AxeloLabs
Copy link

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

@MilanKovacic
Copy link

I have created a plugin to solve this issue during development, until official support is implemented:

https://github.com/MilanKovacic/vite-plugin-externalize-dependencies

@chicoxyzzy
Copy link

chicoxyzzy commented Oct 31, 2023

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)

@thjjames
Copy link

thjjames commented Dec 5, 2023

plz notice me once the issue is resolved.

@rdela
Copy link

rdela commented Dec 9, 2023

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

@AckermannJan
Copy link

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.

@filipsobol
Copy link

The error Pre-transform error: Failed to load url XXX when using the workaround proposed in #6393 (comment) 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
  }
};

@unshame
Copy link

unshame commented May 15, 2024

In addition to the fix in #6582 (comment), 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

@juliusfriedman
Copy link

juliusfriedman commented Jun 20, 2024

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!

@bluwy
Copy link
Member

bluwy commented Oct 28, 2024

With the environment API here, there's now the resolve.external option that should lay the foundation for shared behaviour between dev and build. However, we haven't quite figure out the dev behaviour and client-side behaviour yet. Most of the logic now is based on ssr.external.

Moving this off the milestone, but this maybe something we'd investigate more post v6.

@bluwy bluwy removed this from the 6.0 milestone Oct 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
contribution welcome enhancement New feature or request p2-edge-case Bug, but has workaround or limited in scope (priority)
Projects
None yet
Development

Successfully merging a pull request may close this issue.