0

How to correctly bundle content scripts for a chrome extension using Vite.js? Content scripts do not support ES modules (compared to background service worker), so every content script javascript file should not have any import/export statements, all libraries and other external imports should be inlined in every content script as a single file.

I'm currently using the following vite configuration, where I programmatically pass all my content script paths as the entry.

vite.config.ts

export const extensionScriptsConfig = (
  entry: string[],
  outDir: string,
  mode: Env,
): InlineConfig => {
  const config = defineConfig({
    root: __dirname,
    mode,
    build: {
      outDir,
      emptyOutDir: false,
      minify: false,
      copyPublicDir: false,
      target: 'esnext',
      lib: {
        entry,
        formats: ['es'],
        fileName: (_, entry) => entry + '.js',
      },
    },
  });

  return { configFile: false, ...config };
};

entry contains the following paths

    Directory: C:\Users\code\extension\src\content-scripts

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a---          15/01/2023    14:11           1135 inject-iframe.ts
-a---          15/01/2023    14:11           2858 inject.ts
-a---          14/01/2023    17:49            223 tsconfig.json

The setup above works correctly - each content script is a separate file with no import. But when I try to import a node_module into inject-iframe.ts and inject.ts the following happens in the dist folder:

dist\src\content-scripts\inject.js

import { m as mitt } from './mitt-eb023923.mjs';
...

dist\src\content-scripts\inject-iframe.js

import { m as mitt } from './mitt-eb023923.mjs';
...

The dist:

    Directory: C:\Users\code\extension\dist\src\content-scripts

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a---          15/01/2023    14:44           1093 inject-iframe.js
-a---          15/01/2023    14:44           2300 inject.js
-a---          15/01/2023    14:44            334 mitt-eb023923.mjs

And since ES modules are not supported in the content script context the above doesn't work.

I am also not sure if it should be configured via vite, esbuild or rollup options and if I should use target: 'esnext', and formats: ['es'], for my content scripts vite config. I target manifest v3 extension and the recent chrome version, so older browsers support is not important. And as seen in the snippets above I also need to import some node_modules into my content scripts.

nikitakot
  • 75
  • 6
  • You need to inline the chunk inside each file, I don't know the exact config params, but IIRC it should be easy. The alternative is to use dynamic import as [shown here](https://stackoverflow.com/a/53033388). – wOxxOm Jan 15 '23 at 17:21

0 Answers0