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.
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.
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'] }
}
}
}
})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With