2

I've got a project (written in Reason, but compiling to JS) that uses the module https://www.npmjs.com/package/bs-express. When the code is compiled, the require statement for that module looks like this:

var Express = require("bs-express/src/Express.js");

I've definitely added the bs-express dependency to the package.json file inside of my functions folder, and I've verified by hand that the file exists on my dev box.

When I use the command firebase deploy, the deployment of any functions that use that file fails with this error:

Function load error: Code in file index.js can't be loaded.
Did you list all required modules in the package.json dependencies?
Detailed stack trace: Error: Cannot find module 'bs-express/src/Express.js'
    at Function.Module._resolveFilename (module.js:469:15)
    at Function.Module._load (module.js:417:25)
    at Module.require (module.js:497:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (/user_code/src/Endpoints.bs.js:10:15)
    at Module._compile (module.js:570:32)
    at Object.Module._extensions..js (module.js:579:10)
    at Module.load (module.js:487:32)
    at tryModuleLoad (module.js:446:12)
    at Function.Module._load (module.js:438:3)

But, like I said before, firebase serve --only functions on my developer box works just fine.

firebase --version: 3.17.4

Mac OS 10.13.3

Is there any way to get shell access or something on the container being deployed to so that I can see what exists in the node_modules folder there?

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
Murphy Randle
  • 816
  • 10
  • 19
  • This seems to be specific to bucklescript, whatever it's doing to compile. – Doug Stevenson Mar 13 '18 at 21:50
  • I'm not familiar with firebase, but it sounds like `deploy` will install the dependencies rather than just copy `node_modules` (which also seems very sensible). Since BuckleScript packages usually don't come with the compiled js artifacts, they have to be compiled before being used. So I'm guessing you either have to compile them after the install phase of the deploy, or compile and bundle up the dependencies _before_ deploying. – glennsl Mar 13 '18 at 22:10
  • Y'all are right. Looks like the Bucklescript compile phase leaves the compiled assets for Bucklescript modules living in `node_modules` inside of the `node_modules` folder, and those don't get copied in the deployment process. – Murphy Randle Mar 14 '18 at 16:54

1 Answers1

1

Here's what was happening:

  • bs-express only includes the .re files in its NPM package, not the compiled js artifacts.
  • firebase deploy does a fresh npm install on the container, it doesn't copy the node_modules folder from the development computer.
  • bsb -make-world leaves the compiled assets for a library in node_modules inside of the node_modules directory. It doesn't copy them into lib, even if in_source is disabled in bs-config.json

That's why the compiled JS file is missing at runtime.

The possible solutions:

  • Run bsb on the container and compile the code up there in the postInstall npm hook. (But this doesn't work, because bsb is large and exceeds the container's data size limit of 200MB. Also it takes a loooooooooooooong time to install dependencies during deployment.
  • Add some bundling step to the javascript code before deploying (Webpack or Rollup). At the moment the way the Bucklescript compiler works has some conflicts with Rollup's standards (https://github.com/BuckleScript/bucklescript/issues/2456#issuecomment-372900255), so Webpack might be a better option.
Murphy Randle
  • 816
  • 10
  • 19