How can I expose a global variable with Vite library mode?

5.7k Views Asked by At

I'm trying to use Vite to build a script file that can load a global variable into a web page. I'm using library mode: https://vitejs.dev/guide/build.html#library-mode.

This is my entry file. I'm trying to expose a global with init/destroy methods to render/unmount a React application on the page:

const root = createRoot(document.getElementById('root')!);

const init = () =>
  root.render(
    <React.StrictMode>
      <App />
    </React.StrictMode>
  );

const destroy = () => root.unmount();

// eslint-disable-next-line import/prefer-default-export
export const bugkit = {
  init,
  destroy,
};

My Vite config is as follows:

export default defineConfig({
  build: {
    lib: {
      entry: path.resolve(__dirname, 'src/main.tsx'),
      name: 'bugkit',
      formats: ['umd'],
      fileName: () => 'bugkit.js',
    },
  },
  plugins: [react()],
});

It doesn't seem to expose the global variable like I'd expect, here's the build output:

https://gist.github.com/bugkitio/4fbed14536bd8cca57bef59c47f22161

Any ideas how I can make bugkit.init() globally available when the script is loaded into the page?

2

There are 2 best solutions below

0
On

I think I've found a solution.

There is a vite.config.ts example that insert declaration of expected var in global scope:

export default defineConfig(() => {
  return {
    ... // rest of your config
    build: {
      ...
      rollupOptions: {
        external: ['react'],
        output: {
          name: YOUR_LIB_GLOBAL_ENTRY_NAME,
          globals: { 'react': 'react' }
        }
      }
    }
  }
})
0
On

While working on a custom library that should be used on another website I've managed to achieve this disabling minification In vite.config.js file :

export default defineConfig({
  build: {
    minify: false, // <-- this is the important part
    lib: {
      entry: path.resolve(__dirname, 'src/main.tsx'),
      name: 'bugkit',
      formats: ['umd'],
      fileName: () => 'bugkit.js',
    },
  },
  plugins: [react()],
});

And by adding a variable to window :

const root = createRoot(document.getElementById('root')!);

const init = () =>
  root.render(
    <React.StrictMode>
      <App />
    </React.StrictMode>
  );

const destroy = () => root.unmount();

// eslint-disable-next-line import/prefer-default-export
window.bugkit = { // <-- add it directly to window
  init,
  destroy,
};