How to configure Vite to output single bundles for a Chrome DevTools Extension?

Viewed 567

I am trying to create a Chrome DevTools Extension with Vite.

There are a couple different entry points. The main two are src/background.ts and devtools.html (which references src/devtools.ts).

There are is some code that I want to shared between them in src/devtools-shared.ts.

After running the build, the entry points still contain import statements. Why and how do I get rid of them so they are self-contained bundles (Ideally not IIFE, just good old top level scripts)?

Here is what I have got:

vite.config.js:

const { resolve } = require('path')
const { defineConfig } = require('vite')

module.exports = defineConfig({
  resolve: {
    alias: {
      "root": resolve(__dirname),
      "@": resolve(__dirname, "src")
    }
  },
  esbuild: {
    keepNames: true
  },
  build: {
    rollupOptions: {
      input: {
        'background': "src/background.ts",
        'content-script': "src/content-script.ts",
        'devtools': "devtools.html",
        'panel': "panel.html",
      },
      output: {
        entryFileNames: chunkInfo => {
          return `${chunkInfo.name}.js`
        }
      },
      // No tree-shaking otherwise it removes functions from Content Scripts.
      treeshake: false
    },
    // TODO: How do we configured ESBuild to keep functions?
    minify: false
  }
})

src/devtools-shared.ts:

export const name = 'devtools'

export interface Message {
    tabId: number
}

src/background.ts:

import * as DevTools from './devtools-shared'

src/devtools.ts:

import * as DevTools from './devtools-shared'

And then in dist/background.js I still have:

import { n as name } from "./assets/devtools-shared.8a602051.js";

I have no idea what controls this. I thought there would not be any import statements.

Does the background.ts entry point need to be a lib or something?

For devtools.html is there some other option that controls this?


I know there is https://github.com/StarkShang/vite-plugin-chrome-extension but this doesn't work very well with Chrome DevTool Extensions. I prefer to configure Vite myself.

1 Answers

It turns out that this is not possible. Rollup enforces code-splitting when there are multiple entry-points. See https://github.com/rollup/rollup/issues/2756.

The only workaround that I can think of is to have multiple vite.config.js files such as:

  • vite.config.background.js
  • vite.config.content-script.js
  • vite.config.devtools.js

Then do something like this in package.json:

  "scripts": {
    "build": "npm-run-all clean build-background build-content-script build-devtools",
    "build-background": "vite build -c vite.config.background.js",
    "build-content-script": "vite build -c vite.config.content-script.js",
    "build-devtools": "vite build -c vite.config.devtools.js",
    "clean": "rm -rf dist"
  },

This is not very efficient as it repeats a lot of work between each build but that's a Rollup problem.

Related