fengari-lua / fengari

🌙 φεγγάρι - The Lua VM written in JS ES6 for Node and the browser
MIT License
1.8k stars 64 forks source link

fengari doesn't work with webpack when targetting browser - dependency on fs #156

Open roddypratt opened 5 years ago

roddypratt commented 5 years ago

I'm using fengari-web without problems in a browser-side app bundled with webpack 3. When I try pulling in fengari API calls directly, I get these kind of errors.

ERROR in ./node_modules/fengari/src/lauxlib.js
Module not found: Error: Can't resolve 'fs' in 'C:\rascular\WebCentre2\node_modules\fengari\src'
 @ ./node_modules/fengari/src/lauxlib.js 901:15-28
 @ ./node_modules/fengari/src/fengari.js

It seems to be because the conditional if (typeof process !== "undefined") require()s aren't handled by webpack, and the recommended solution seems to be to use __non_webpack_require__

https://hackernoon.com/building-isomorphic-javascript-packages-1ba1c7e558c5

daurnimator commented 5 years ago

Are you using the distributed bundle?

roddypratt commented 5 years ago

It looks like not. I was importing fengari separately (which has no distributed bundles?) rather than using the API calls exposed by fengariweb etc. So probably due to my Typescript typing files...

roddypratt commented 5 years ago

OK, I have it working now, as long as I always import {lua} from "fengari-web" rather than from "fengari"., for example. ( I hadn't previously made the fengari-web typings re-export the fengari libraries, which prevented this)

However, I think this is still an issue, as code running in the browser should still be able to require just the "fengari" module.

daurnimator commented 5 years ago

However, I think this is still an issue, as code running in the browser should still be able to require just the "fengari" module.

Doesn't webpack do this for you?

roddypratt commented 5 years ago

If I explicitly import * from "fengari" (which AFAICT has no distributed bundle) then webpack scans the fengari code for "require"d modules and attempts to add them to the bundle. Webpack's not smart enough to ignore conditionally required modules (like lines 485 on of loslib.js). If I import from fengari-web instead it's all OK, as I believe I get the distributed bundle (which somehow avoids this problem?)

timkurvers commented 5 years ago

A potential workaround here is to force webpack into the browser-compatible branch, using the DefinePlugin:

new webpack.DefinePlugin({
  'typeof process':  JSON.stringify('undefined'),
}),

We're currently using this successfully (https://github.com/wowserhq/client/commit/8c61884f1c0575e15a63d9bcb5b8a1bad3810d62) but it's worth noting that it may break other parts of the build that actually do rely on process using a typeof-check.

hmans commented 5 years ago

I wasn't feeling terribly comfortable with the workaround suggested by @timkurvers, so I had a go at trying to fix it within Fengari itself. I'm a bit of a Node/Webpack newbie, so I really hope I chose a sane approach -- if I didn't, please let me know.

PR: https://github.com/fengari-lua/fengari/pull/166

timkurvers commented 5 years ago

Agreed @hmans, definitely safer to fix from within. Like your approach 👍