crxjs / chrome-extension-tools

Bundling Chrome Extensions can be pretty complex. It doesn't have to be.
https://crxjs.dev/vite-plugin
2.75k stars 182 forks source link

Web accessible resources inconsistencies between dev and build #578

Closed rbhalla closed 1 year ago

rbhalla commented 1 year ago

Build tool

Vite

Where do you see the problem?

Describe the bug

Sorry to bundle these errors into a single issue, let me know if you prefer them split.

I'm seeing some odd errors with web accessible resources. This is my current manifest:

"web_accessible_resources": [
    {
      "resources": [
        "src/pages/home-page/index.html",
        "src/pages/home-page/index.js",
        "src/pages/options/index.html",
        "src/pages/options/index.js"
      ],
      "matches": [
        "*://*/*"
      ]
    }
  ]

I can then access these resources by going to chrome-extension://<my-extension-id>/src/pages/options/index.html, for example.

The issues I'm seeing: 1) I can't reference javascript files that resolve correctly in dev and build In dev, the index.html files need to reference the full relative path, i.e. src/pages/options/index.js. In the build, index.html needs to reference just the file, index.js. Ideally the script tag should reference the full url, but the chrome extension id isn't necessarily known here to be able to do that.

I think this is because in dev, the javascript file is evaluated using @crx/inline-script/src/pages/options/index. In the final build, the script tag is not touched and the browser resolves the file relative to the currently loaded html file. To put it in another way:

2) Environment variables aren't resolving in build I am using import.meta.env to access VITE_ prefixed environment variables.

I can understand why this would work in dev (since it goes through @crx/inline-script), I don't understand why it doesn't work in build. I am getting a warning in the console when I try and do a build:

transforming (1) ../crx-manifest<script src="index.js"> in "/src/pages/options/index.html" can't be bundled without type="module" attribute

If I add type="module" to the script tag, I get a rollup error, even though I'm using vite. I'm guessing rollup is involved somewhere in the background?

[vite]: Rollup failed to resolve import "index.js" from "src/pages/options/index.html".
This is most likely unintended because it can break your application at runtime.
If you do want to externalize this module explicitly add it to
`build.rollupOptions.external`
error during build:
Error: [vite]: Rollup failed to resolve import "index.js" from "src/pages/options/index.html".
This is most likely unintended because it can break your application at runtime.
If you do want to externalize this module explicitly add it to
`build.rollupOptions.external`
    at onRollupWarning (/srv/node_modules/vite/dist/node/chunks/dep-689425f3.js:41797:19)
    at onwarn (/srv/node_modules/vite/dist/node/chunks/dep-689425f3.js:41613:13)
    at Object.onwarn (/srv/node_modules/rollup/dist/shared/rollup.js:23216:13)
    at ModuleLoader.handleResolveId (/srv/node_modules/rollup/dist/shared/rollup.js:22466:26)
    at /srv/node_modules/rollup/dist/shared/rollup.js:22427:26

I am not sure how to begin address this error.

System Info

System:
    OS: macOS 12.6
    Shell: 5.8.1 - /bin/zsh
  Binaries:
    Node: 15.10.0 - ~/.nvm/versions/node/v15.10.0/bin/node
    npm: 7.5.3 - ~/.nvm/versions/node/v15.10.0/bin/npm
  Browsers:
    Chrome: 107.0.5304.110
    Safari: 16.0

Severity

blocking all usage of RPCE

jacksteamdev commented 1 year ago

Hi @rbhalla, thanks for taking the time to submit this issue! There's a lot of good information here, but I need a little more to identify the issue. Can you provide a link to a minimal reproduction repo?

jacksteamdev commented 1 year ago

I'm guessing rollup is involved somewhere in the background?

That's right! Vite uses Rollup under the hood for production builds.

rbhalla commented 1 year ago

Hey @jacksteamdev!

Apologies, I should have done this in the initial post. Here is an example repo: https://github.com/rbhalla/crxjs-bug-repro/tree/pages-js-problems

This is from a vite starter with the @crxjs/vite-plugin installed. You can compare the branch to master to see what it took to introduce.

When you do npm run dev and access the options page (right click on the icon and press options). Everything works fine. When you do npm run build, the javascript stops loading (it is not found). If you inspect the file at dist/src/pages/options.index.js you'll also notice the environment variable isn't swapped out. Likely because now we're using rollup, not vite(?).

The fix to the index.js 404 is to actually change the reference in src/pages/options/index.html to load the js from index.js. This fixes npm run build, but then breaks npm run dev.

jacksteamdev commented 1 year ago

@rbhalla Awesome, thanks for the example! It works if you use type="module" and add a slash to the front of the path.

<script src="/src/pages/options/index.js" type="module"></script>

Vite only supports absolute or relative paths (paths that start with ./ or /). 🤷

rbhalla commented 1 year ago

Oh wow! Thank you so much!

Looking at the dist folder, this also seems to mean I don't need to reference the javascript file as an accessible resource in my manifest file.