awesome-webextension / webpack-target-webextension

WebExtension Target for Webpack 5. Supports code-splitting and HMR.
MIT License
44 stars 5 forks source link

Running content scripts in the main JavaScript world throws an error #44

Closed cezaraugusto closed 3 months ago

cezaraugusto commented 3 months ago

Hello there! First off, thanks for such a great plugin! I'm using it as a dependency for my project and had a user report that it errors when running scripts in the main world (ref: https://github.com/cezaraugusto/extension.js/issues/66). While investigating it seems that the root cause is a check for chrome.* and browser.* namespaces in https://github.com/awesome-webextension/webpack-target-webextension/blob/master/lib/webpack5/BrowserRuntime.js#L8.

Client error:

Screenshot 2024-06-05 at 16 27 06

Referenced file:

Screenshot 2024-06-05 at 16 27 15

I created a repo with a reproducible sample at https://github.com/cezaraugusto/main-world-extension, but seems that just adding the field to the manifest file is enough to repro.

// manifest.json
{
  "manifest_version": 3,
  "version": "1.0",
  "name": "main-world-extension",
  "description": "An extension running in the main world.",
  "background": {
    "service_worker": "./dist/background.js"
  },
  "content_scripts": [
    {
+      "world": "MAIN",
      "matches": [
        "https://extension.js.org/*"
      ],
      "js": [
        "./dist/content.js"
      ]
    }
  ]
}
Jack-Works commented 3 months ago

hi @cezaraugusto, can you try to enable ES Module loader and disable runtime check? For a MAIN world script, only ESM Module loader can share code with the main chunk.

Let me know if you need help!

cezaraugusto commented 3 months ago

I've tried setting weakRuntimeCheck to false and set "type": "module" to package.json. Here's my webpack config so far, couldn't make it work unfortunately.

Also updated the sample repo: https://github.com/cezaraugusto/main-world-extension:

import WebExtension from "webpack-target-webextension";
import webpack from "webpack";
import { join } from "path";
import { fileURLToPath } from "url";
import {dirname} from "path";

// Get the file path from the URL
const __filename = fileURLToPath(import.meta.url);

// Get the directory name from the file path
const __dirname = dirname(__filename);

/** @returns {webpack.Configuration} */
const config = (a, env) => ({
  devtool: "cheap-source-map",
  devtool: env.mode === "production" ? undefined : "cheap-source-map",
  resolve: {
    extensions: [".js"],
  },
  entry: {
    background: join(__dirname, "./background.js"),
    content: join(__dirname, "./content.js"),
  },
  output: {
    environment: {
      dynamicImport: true,
    },
  },
  plugins: [
    new WebExtension({
      background: {
        serviceWorkerEntry: "background",
        classicLoader: true,
      },
      weakRuntimeCheck: false,
    }),
  ],
  devServer: {
    hot: "only",
  },
});

export default config;
Jack-Works commented 3 months ago

I've tried setting weakRuntimeCheck to false

Try weakRuntimeCheck: true, not false

cezaraugusto commented 3 months ago

No luck, same result

Jack-Works commented 3 months ago

thanks, I'll investigate this

Jack-Works commented 3 months ago

I have updated webpack-target-webextension@1.1.2 and the guide for the main world content script. Unluckily, the setup required for the main world content script is unpleasant, it requires you to set your output.publicPath to something like chrome-extension://jknoiechepeohmcaoeehjaecapdplcia/dist/.