Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
zensh opened this issue Sep 16, 2024 · 14 comments
Open

Comments

@zensh
Copy link

zensh commented Sep 16, 2024

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

@peterpeterparker
Copy link
Member

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?

@zensh
Copy link
Author

zensh commented Sep 16, 2024

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

@peterpeterparker
Copy link
Member

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.

@zensh
Copy link
Author

zensh commented Sep 16, 2024

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
Copy link
Author

zensh commented Sep 16, 2024

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

@peterpeterparker
Copy link
Member

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?

@zensh
Copy link
Author

zensh commented Sep 16, 2024

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

@peterpeterparker
Copy link
Member

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.

@zensh
Copy link
Author

zensh commented Sep 16, 2024

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()

@peterpeterparker
Copy link
Member

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

@peterpeterparker
Copy link
Member

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

@peterpeterparker
Copy link
Member

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.

@zensh
Copy link
Author

zensh commented Sep 17, 2024

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

@peterpeterparker
Copy link
Member

peterpeterparker commented Sep 17, 2024

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants