fengari-lua / fengari-web

Provides everything you need to run Fengari in the browser.
MIT License
250 stars 19 forks source link

Cannot `importScripts` from Web Worker #44

Open Castux opened 4 years ago

Castux commented 4 years ago

Is it possible to run Fengari from a Web Worker? Naively trying importScripts("fengari-web.js"); gives the following error:

fengari-web.js:1 Uncaught ReferenceError: window is not defined
    at fengari-web.js:1
    at worker.js:1

Since the library is minified, it's hard to know what's going on, although the source for fengari-web.js seems to have a section that detects if there is a document, which suggests it might work without one?

daurnimator commented 4 years ago

It should be possible.... are you able to try again with an unminified version?

I guess the if (window.dispatchEvent(e)) { line is causing the reference error? Is that happening at load time or is it actually reaching that code at runtime? If it is reaching it at runtime, then you must have a document object in the web worker: is that normal/expected?

Castux commented 4 years ago

I'm afraid I'm not very proficient in JS (hence my interest in running Lua in the browser ;) ). I couldn't find a non minified release, and npm build minifies automatically.

My test is a barebones HTML document with the following script:

var w = new Worker("worker.js");

And worker.js is:

importScripts("fengari-web.js")
const L = fengari.lauxlib.luaL_newstate();

At page load, the error mentioned above is thrown:

fengari-web.js:1 Uncaught ReferenceError: window is not defined
    at fengari-web.js:1
    at worker.js:1

(Google Chrome Version 80.0.3987.163 (Official Build) (64-bit) on Windows 10, if that's relevant)

Castux commented 4 years ago

Ha! I've no idea what I'm doing, but in webpack.config.js I changed the first target to webworker, and the fengari-web.js that was produced with npm run build now seems to load properly inside a WebWorker. I only tested with console.log(fengari.load('return 1+1')()) but that did what it should, so it sounds promising.

Castux commented 4 years ago

Ok, this new way to build works (at least for my use: https://snake-eyes.io/), so the issue can be closed as far as I'm concerned. You can be the judge of whether there's a bug to fix, or a new target to add to the build system, etc.

d0sboots commented 3 years ago

I have the same issue. Same line numbers in the backtrace, etc., except I'm not using webpack or anything - just a raw download of fengari-web.js that I'm loading with importScripts().

The line that's failing is the following:

!function(t, e) {
    "object" == typeof exports && "object" == typeof module ? module.exports = e() : "function" == typeof define && define.amd ? define([], e) : "object" == typeof exports ? exports.fengari = e() : t.fengari = e()
}(window, function() {

It chokes on the "window". I don't see how it could ever work in a WebWorker, because there's no conditional there - the symbol will always be evaluated. Also, none of this appears in the original code - it appears to be coming from whatever minifier you're using.

daurnimator commented 3 years ago

hmm, indeed the pre-compiled script contains the same thing. I guess we need to change some minifier setting

d0sboots commented 3 years ago

I did the same thing as Castux: changed the webpack config target from "web" to "webworker", and that fixed it for me too. Looking at the compiled output, the only diff, across the entire bundle, is literally changing the single "window" that it's choking on to "self".

I'm attaching the result for anyone else who has the same issue. However, judging from the result, I'd say it should be safe to change the main config to "webworker" for everyone. ("self" works portably in both contexts, because that's what it was designed for.)

fengari-web.zip