Skip to content

Global namespace pollution when using rollupOptions.output.format umd #17608

@TomPradat

Description

@TomPradat

Describe the bug

I'm building a bundle with umd format as a target. When doing so I expect the result bundle to be wrapped in an iife function. The configuration looks like this :

  build: {
    rollupOptions: {
      output: {
        format: "umd",
        entryFileNames: "bundle.js",
      },
    },
  },

Instead, I have variables declared outside the iife :

image

This is a problem because the variables' declaration might override previous variables with the same name. This is how I encountered the issue.

Workaround :

So far, I have used a homemade plugin to wrap my final code in a iife :

import { defineConfig } from "vite";

// https://vitejs.dev/config/
export default defineConfig({
  build: {
    rollupOptions: {
      output: {
        format: "umd",
        entryFileNames: "bundle.js",
      },
    },
  },
  plugins: [viteWrapCodeInIIFE({ files: ["bundle.js"] })],
});

function viteWrapCodeInIIFE(options = {}) {
  return {
    name: "vite-wrap-code-in-iife",
    apply: "build",
    enforce: "post",
    generateBundle(outputOptions, bundle) {
      for (const [fileName, chunkOrAsset] of Object.entries(bundle)) {
        if (
          chunkOrAsset.type === "chunk" &&
          options.files &&
          options.files.includes(fileName)
        ) {
          chunkOrAsset.code = `(function () {${chunkOrAsset.code}})();`;
        }
      }
    },
  };
}

I'm willing to work on a PR. I believe the fix would be an extension of the #7948 so that is also applies when rollupOptions.output.format is umd or iife.

Reproduction

See steps

Steps to reproduce

  1. Bootstrap a vite project
npm init vite@latest test -- --template vanilla && cd test && npm install
  1. Install the "react-query" package that causes the build to have variables defined outside the iife
npm install @tanstack/react-query
  1. Create a vite.config.js with the umd format as a target
cat <<EOF > vite.config.js
import { defineConfig } from "vite";

// https://vitejs.dev/config/
export default defineConfig({
  build: {
    rollupOptions: {
      output: {
        format: "umd",
        entryFileNames: "bundle.js",
      },
    },
  },
});
EOF
  1. Change the main.js
cat <<EOF > main.js
import { QueryClient } from "@tanstack/react-query";

const queryClient = new QueryClient();
EOF
  1. Build the bundle
npm run build
  1. See the result in dist/bundle.js

System Info

System:
    OS: macOS 13.4.1
    CPU: (8) arm64 Apple M1 Pro
    Memory: 330.16 MB / 16.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 18.16.0 - ~/.nvm/versions/node/v18.16.0/bin/node
    Yarn: 3.5.1 - ~/.nvm/versions/node/v18.16.0/bin/yarn
    npm: 9.5.1 - ~/.nvm/versions/node/v18.16.0/bin/npm
    pnpm: 8.15.4 - ~/Library/pnpm/pnpm
    bun: 1.0.14 - ~/.bun/bin/bun
  Browsers:
    Brave Browser: 124.1.65.132
    Chrome: 126.0.6478.127
    Firefox Nightly: 121.0a1
    Safari: 16.5.2
  npmPackages:
    vite: ^5.3.1 => 5.3.3

Used Package Manager

npm

Logs

No response

Validations

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions