Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to exclude JS script from the bundle when building app with vite?

Due to another issue, I have to import a JS dependency statically in HTML in my vue3 application.

/index.html

<head>
    <!-- ... -->
    <script type="module" src="node_modules/@telekom/scale-components-neutral/dist/scale-components/scale-components.esm.js"></script>
</head>

As Vite cannot properly bundle this dependency (due to an issue, see the post mentioned above), I would like the bundling to ignore it. In the production build, I want the JS module to be imported as-is in the root index.html.

I tried pretty much everything in optimizeDeps.exclude config property, but Vite still tries to analyze and pre-bundle it.

vite.config.ts

export default defineConfig({
  optimizeDeps: {
    exclude: [
      // I tried pretty much everything here: no way to force vite pre-bundling to ignore it...
      'scale-components-neutral'
      '@telekom/scale-components-neutral'
      '@telekom/scale-components-neutral/**/*'
      '@telekom/scale-components-neutral/**/*.js'
      'node_modules/@telekom/scale-components-neutral/**/*.js'
    ],
  },
  // ...
});

In every case, after running npm run build, the import has been removed from dist/index.html.

What does optimizeDeps.exclude config expect?


Edit

Following this note, found in https://vitejs.dev/guide/dep-pre-bundling.html:

Dependency pre-bundling only applies in development mode, and uses esbuild to convert dependencies to ESM. In production builds, @rollup/plugin-commonjs is used instead.

I tried to specify build.commonjsOptions.exclude config.

vite.config.js

export default defineConfig({
  build: {
    commonjsOptions: {
      exclude: [
        'scale-components-neutral',
        'node_modules/@telekom/scale-components-neutral',
        'node_modules/@telekom/scale-components-neutral/**/*',
        'node_modules/@telekom/scale-components-neutral/**/*.js',
        '/node_modules/@telekom/scale-components-neutral',
        '/node_modules/@telekom/scale-components-neutral/**/*',
        '/node_modules/@telekom/scale-components-neutral/**/*.js',
        '**/node_modules/@telekom/scale-components-neutral',
        '**/node_modules/@telekom/scale-components-neutral/**/*',
        '**/node_modules/@telekom/scale-components-neutral/**/*.js',
        '@telekom/scale-components-neutral',
        '@telekom/scale-components-neutral/**/*',
        '@telekom/scale-components-neutral/**/*.js',
        '**/node_modules/@telekom/scale-components-neutral/dist/scale-components/scale-components.esm.js',
      ],
    },
  },
  // ...

No more success: the import stills disappears from dist/index.html.


Edit 2

build.rollupOptions.external and build.dynamicImportVarsOptions.exclude were promising (as the initial issue concerns dynamic imports...).

But no more luck there: the JS dependency is still ill-bundled. It works in local dev but not on a deployed app built with npm run build.

like image 812
Eria Avatar asked Jan 18 '26 07:01

Eria


2 Answers

In my case, I needed to exclude some assets that were nested within a node_modules dependency which otherwise was ok to be bundled. This config worked:

import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

// https://vitejs.dev/config/
export default defineConfig({
  build: {
    rollupOptions: {
      external: /@patternfly\/elements\/pf-icon\/icons\/.*/,
    },
  },
  plugins: [
    react(),
  ],
});

The key difference here was that I needed to use a RegExp object, not a glob string, to specify the children of the package which I wanted to exclude.

like image 58
Benny Powers Avatar answered Jan 20 '26 23:01

Benny Powers


Sounds from your comment of how you eventually resolved the issue that it wasn't actually in the bundling itself, but in the transform that Vite was performing on the plugin.

To separate a dependency from the bundle, you can use rollup's output.manualChunks. Rollup docs

Example:

//vite.config.js
...
export default defineConfig({
...
  build: {
    rollupOptions: {
      output: {
        manualChunks: { lodash: ['lodash'] }
      }
    }
  }
})
like image 40
Guy Passy Avatar answered Jan 21 '26 01:01

Guy Passy