agent-js icon indicating copy to clipboard operation
agent-js copied to clipboard

Cannot use 'import.meta' outside a module when building a ServiceWorker script

Open zensh opened this issue 1 year ago • 15 comments

https://github.com/dfinity/agent-js/blob/main/packages/agent/src/agent/http/index.ts#L1106

await import is incompatible with the ServiceWorker script. This can cause the error: "Uncaught SyntaxError: Cannot use 'import.meta' outside a module."

We encountered this issue while building the ICPanda frontend application. Removing the await import here resolved the ServiceWorker script build.

https://github.com/ldclabs/ic-panda/blob/main/src/ic_panda_frontend/src/service-worker.ts#L11

zensh avatar Sep 16 '24 07:09 zensh

await import is incompatible with the ServiceWorker script.

I randomly had a look at the line of code you are referencing. Are you bundling your SW using ES modules?

peterpeterparker avatar Sep 16 '24 08:09 peterpeterparker

await import is incompatible with the ServiceWorker script.

I randomly had a look at the line of code you are referencing. Are you bundling your SW using ES modules?

Yes, I used the ES module for packaging. I spent half a day resolving the issue and was only able to package successfully after modifying the agent file in node_modules. https://github.com/ldclabs/ic-panda/blob/main/src/ic_panda_frontend/vite.config.js#L99

zensh avatar Sep 16 '24 11:09 zensh

Yes, I used the ES module for packaging.

Maybe it's specific to service worker? We do use the agent in web workers in Oisy for example and we do not have issue. That's why I was asking about ES modules.

peterpeterparker avatar Sep 16 '24 11:09 peterpeterparker

Thank you for following up.
I created a test project using pnpm create @vite-pwa/pwa agent-sw --template svelte-ts and didn't encounter any issues. The generated sw file has slight differences from my previous project, but I haven't yet identified the cause. I tried using the same tsconfig and package versions. Currently, the key difference is that the test project doesn't use SvelteKitPWA.

from template project: iShot_2024-09-16_22 04 55

from ICPanda, import.meta.url appears: iShot_2024-09-16_22 04 23

zensh avatar Sep 16 '24 14:09 zensh

It's clear that if the await import in the agent-js source code is removed, there won't be any issues.

zensh avatar Sep 16 '24 14:09 zensh

import.meta.url

Oh yeah we had that issue in Oisy too - i.e. import.meta is incompatible with web workers. To overcome the issue we pass the variable to the web worker (UI -> web worker through postMessage) and then pay attention to use those values instead of import.meta in any piece of code used by the workers.

Did you check if import.meta.url is injected by agent-js or your code?

peterpeterparker avatar Sep 16 '24 14:09 peterpeterparker

import.meta.url

Oh yeah we had that issue in Oisy too - i.e. import.meta is incompatible with web workers. To overcome the issue we pass the variable to the web worker (UI -> web worker through postMessage) and then pay attention to use those values instead of import.meta in any piece of code used by the workers.

Did you check if import.meta.url is injected by agent-js or your code?

It is injected by agent-js:

image image

zensh avatar Sep 16 '24 14:09 zensh

Are you using use-auth-client? The only reference in src I find about import.meta is in its demo.

That would explain why we do not face the issue in Oisy.

peterpeterparker avatar Sep 16 '24 15:09 peterpeterparker

We use agent-js in service worker to fetch latest data for notifications, some code like this:

/// <reference lib="webworker" />
import { cleanupOutdatedCaches, createHandlerBoundToURL, precacheAndRoute } from 'workbox-precaching'
import { NavigationRoute, registerRoute } from 'workbox-routing'
import {
  HttpAgent,
} from '@dfinity/agent'

declare let self: ServiceWorkerGlobalScope

self.addEventListener('message', (event) => {
  if (event.data && event.data.type === 'SKIP_WAITING')
    self.skipWaiting()
})

// self.__WB_MANIFEST is the default injection point
precacheAndRoute(self.__WB_MANIFEST)

// clean old assets
cleanupOutdatedCaches()

let allowlist: RegExp[] | undefined
// in dev mode, we disable precaching to avoid caching issues
if (import.meta.env.DEV)
  allowlist = [/^\/$/]

// to allow work offline
registerRoute(new NavigationRoute(
  createHandlerBoundToURL('index.html'),
  { allowlist },
))

console.log('Service worker is active.')

const agent = new HttpAgent({ host: 'https://ic0.app' })

async function testLoop() {
  while (true) {
    await agent.syncTime()
    console.log('@dfinity/agent', 'syncTime')
    await new Promise((resolve) => setTimeout(resolve, 10000))
  }
}

testLoop()

zensh avatar Sep 16 '24 15:09 zensh

Weird, I’m a bit out of ideas...

peterpeterparker avatar Sep 16 '24 15:09 peterpeterparker

In which of your repo are you facing the issue? Can I give it a try?

peterpeterparker avatar Sep 16 '24 16:09 peterpeterparker

I spent last hour trying to reproduce the issue with your repo, but I'm having trouble loading the SW. I try to mock and remove some data to achieve the goal but, always ends facing some issue with bundling. I'll stop here for now, but if you're able to reproduce the issue with a sample repo, I'd be happy to give it another try.

peterpeterparker avatar Sep 16 '24 18:09 peterpeterparker

Sorry to take up your time @peterpeterparker

I’ve created a test project that can reproduce the issue. It’s confirmed that after introducing SvelteKit, the service-worker.js generated during the build contains the import.meta.url snippet from agent-js.

I’m not sure what configuration causes this issue. My current workaround is to delete the await import line in @dfinity/agent within the local node_modules before building.

This seems to be a specific issue and it’s probably not worth taking more of your time to diagnose it. Merging #931 should fully resolve it.

Working branch:

git clone https://github.com/zensh/agent-sw
cd agent-sw
pnpm i
pnpm build
pnpm preview

Branch with the issue after introducing SvelteKit:

git checkout feat/kit
pnpm i
pnpm dev // and then stop to generate the .svelte-kit directory
pnpm build
pnpm preview

zensh avatar Sep 17 '24 01:09 zensh

Thanks, @zensh, for the repo. I can reproduce the issue as well and couldn't find any configuration option to resolve it.

While the issue is not addressed yet, I may have a workaround to suggest. Instead of letting the bundler pick the appropriate module, you can try forcing the import to point to cjs. Based on my quick test, this seems to avoid the issue. Of course, it's not a clean solution, and the worker might be too heavy because of this, but I thought I'd share it in case it helps unblock you.

import { HttpAgent } from '@dfinity/agent/lib/cjs'

As for your PR, I can't say for sure and still unsure about the root cause. I also don't collaborate to agent-js, just jumped in because I use worker in Oisy Wallet or Juno. I guess @krpeacock, who's currently on PTO, will take a look when they return.

peterpeterparker avatar Sep 17 '24 04:09 peterpeterparker

I think this will be addressed when we fix #843

krpeacock avatar Apr 09 '25 17:04 krpeacock

Fixed in #1026

ilbertt avatar Jul 01 '25 20:07 ilbertt