justjake / quickjs-emscripten

Safely execute untrusted Javascript in your Javascript, and execute synchronous code that uses async functions
https://www.npmjs.com/package/quickjs-emscripten
Other
1.18k stars 94 forks source link

TypeError: Failed to construct 'URL': Invalid URL #151

Closed sradu closed 4 months ago

sradu commented 4 months ago

I'm trying to update to 0.27.0 and running into this error:

TypeError: Failed to construct 'URL': Invalid URL
    at emscripten-module.browser.mjs:11:445
Screenshot 2024-02-07 at 4 17 12 PM

with the code:

import { getQuickJS } from 'quickjs-emscripten'

export class UIVM  {
  async setupVM () {
    const QuickJS = await getQuickJS()
    console.log('never get here')
    const runtime = QuickJS.newRuntime()

    this.vm = runtime.newContext()
  }
}

My environment is Rails + esbuild + yarn. I'm unsure where to start debugging this, the integration is just yarn add and this code above.

exoego commented 4 months ago

I encountered this. It looks like an issue in ESBuild. It does not work with new URL(..., import.meta.url) as of today? https://github.com/evanw/esbuild/issues/795

sradu commented 4 months ago

Since that ticket is from 2021 it's likely they won't provide a fix. Have you found a workaround?

justjake commented 4 months ago

@sradu you can switch to a “singlefile” variant for your release build. See the instructions here: https://github.com/justjake/quickjs-emscripten/blob/main/doc/quickjs-emscripten-core/README.md

sradu commented 4 months ago

Thanks for the quick reply @justjake.

If I want to use two engines, one async, and one regular, and consequently include those 2 out of 4 engines in the payload, is that possible?

In one place I'm using getQuickJS and in another newQuickJSAsyncWASMModule.

sradu commented 4 months ago

I have this now:

import { newQuickJSWASMModuleFromVariant } from 'quickjs-emscripten-core'
import releaseVariant from '@jitl/quickjs-singlefile-cjs-release-asyncify'

async setupVM () {
    console.log('xx', releaseVariant)
    const module = await newQuickJSWASMModuleFromVariant(releaseVariant)
    const runtime = module.newRuntime()
    this.vm = runtime.newContext()

    console.log('here', this.vm.evalCodeAsync)
}

this.vm.evalCodeAsync is null.

Screenshot 2024-02-07 at 9 06 11 PM

Also, the main docs say

import { newQuickJSWASMModuleFromVariant } from "quickjs-emscripten-core"
import DEBUG_SYNC from "@jitl/quickjs-wasmfile-debug-sync"

const QuickJS = await newQuickJSWASMModuleFromVariant(DEBUG_SYNC)

whereas the other page says:

import releaseVariant from "@jitl/quickjs-singlefile-cjs-release-sync"

// 3. Create the "QuickJS" module that presents the quickjs-emscripten API.
//    Export and use in other files, or consume directly.
const QuickJS = await newQuickJSWASMModuleFromVariant(releaseVariant)
sradu commented 4 months ago

OK figured it out, had to read the docs carefully:

for async

import { newQuickJSAsyncWASMModuleFromVariant } from 'quickjs-emscripten-core'
import releaseVariant from '@jitl/quickjs-singlefile-cjs-release-asyncify'

async setupVM () {
   const module = await newQuickJSAsyncWASMModuleFromVariant(releaseVariant)
    const runtime = module.newRuntime()
    this.vm = runtime.newContext()
}

for sync

import { newQuickJSWASMModuleFromVariant } from 'quickjs-emscripten-core'
import releaseVariant from '@jitl/quickjs-singlefile-cjs-release-sync'

  async setupVM () {
    const module = await newQuickJSWASMModuleFromVariant(releaseVariant)
    const runtime = module.newRuntime()

    this.vm = runtime.newContext()
  }

Thank you @justjake. Apologies for the message spam.

The main docs could be a bit less confusing, but what you're doing is amazing and we should pay more attention.

justjake commented 4 months ago

Do you have any suggestions on how to improve the docs? I end up pretty blind to the issues because I’m too deep 😅