awesome-webextension / webpack-target-webextension

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

missing webpack/runtime/load script in background.js #34

Closed 0xBigBoss closed 9 months ago

0xBigBoss commented 2 years ago

We have a background script that is started like so.

// ./background.js
import { startApi } from "@sendnodes/pokt-wallet-background"

startApi()

However, this extension fails to add this runtime part in the webpack output. It never fetches all of the modules correctly and so our background script exits without executing the startApi logic.

/******/    /* webpack/runtime/load script */
/******/    (() => {
/******/        var isBrowser = !!(() => { try { return browser.runtime.getURL("/") } catch(e) {} })()
/******/        var isChrome = !!(() => { try { return chrome.runtime.getURL("/") } catch(e) {} })()
/******/        var runtime = isBrowser ? browser : isChrome ? chrome : (typeof self === 'object' && self.addEventListener) ? { get runtime() { throw new Error("No chrome or browser runtime found") } } : { runtime: { getURL: x => x } }
/******/        var __send__ = (msg) => {
/******/            if (isBrowser) return runtime.runtime.sendMessage(msg)
/******/            return new Promise(r => runtime.runtime.sendMessage(msg, r))
/******/        }
/******/        var classicLoader = (url, done, chunkId) => {
/******/            __send__({ type: 'WTW_INJECT', file: url }).then(done, (e) => done(Object.assign(e, { type: 'missing' })))
/******/        }
/******/        var scriptLoader = (url, done, chunkId) => {
/******/            var script = document.createElement('script')
/******/            script.src = url
/******/            script.onload = done
/******/            script.onerror = done
/******/            document.body.appendChild(script)
/******/        }
/******/        var workerLoader = (url, done, chunkId) => {
/******/            try { importScripts(url); done() } catch (e) { done(e) }
/******/        }
/******/        var isWorker = typeof importScripts === 'function'
/******/        if (location.protocol.includes('-extension:')) __webpack_require__.l = isWorker ? workerLoader : scriptLoader
/******/        else if (!isWorker) __webpack_require__.l = classicLoader
/******/        else { throw new TypeError('Unable to determinate the chunk loader: content script + Worker') }
/******/    })();

The only way to get this plugin to get this part added is to convert our background script is to use dynamic imports. Then, that runtime portion gets added.

setTimeout(async () => {
  const { startApi } = await import("@sendnodes/pokt-wallet-background")

  startApi()
}, 1);

I don't know enough about webpack compilation steps to be much more help than that, but maybe this has to do with our webpack setup. This is what our plugin looks like.

new WebExtension({
  background: {
    entry: 'background',
    // !! Add this to support manifest v3
    manifest: browser == 'chrome' ? 3 : 2,
    classicLoader: true
  },
  weakRuntimeCheck: true,
  hmrConfig: false
}),
Jack-Works commented 2 years ago
// ./background.js
import { startApi } from "@sendnodes/pokt-wallet-background"

startApi()

Is that module contains a Top-Level-Await or AsyncWebAssembly module?

0xBigBoss commented 2 years ago

startApi returns a promise. await-ing the result of startApi seemed to help chrome, but not firefox.

This didn't work on Firefox (v2) but worked on chrome(v3)


import { startApi } from "@sendnodes/pokt-wallet-background"
/**
 * Use a dynamic import so webpack-target-webextension compiles correctly
 */
(async () => {
  await startApi()
})()

This works on both

/**
 * Use a dynamic import so webpack-target-webextension compiles correctly
 */
(async () => {
  const { startApi } = await import("@sendnodes/pokt-wallet-background")
  await startApi()
})()
Jack-Works commented 2 years ago

Sorry, I can't help much. It looks like @sendnodes/pokt-wallet-background is not published on npm. If you can provide a minimal available reproduction, I may investigate this.

0xBigBoss commented 1 year ago

This is super old now, and the wallet is open source, using the workaround has been working flawlessly though!

For the interested: https://github.com/sendnodes-io/SendWallet

Gonna close. thx for at least hearing me out!

0xBigBoss commented 1 year ago

FWIW I was worked a bit on our webpack config and this issue cropped up again. I traced it down to the fact we are using optimization.splitChunks.chunks = 'all' . https://github.com/sendnodes-io/sendwallet/blob/a90728c9ed746f31c58950b029e35c24b34efc34/apps/webext-legacy/webpack.config.ts#L331

Not sure if that helps or now. The dynamic import still works though.

Jack-Works commented 9 months ago

I'll close this issue for now because there is no reproduction. If you have one, please ping me and I'll try to investigate this issue.