skip to Main Content

Here’s my sceario:

I have an NodeJS application that connects to a PostgreSQL database, make use of a lot of Azure libs for Storage Account, WebPubSub, DataFactory… it’s hosted on a Windows server.

My current pipeline process builds this application, then copies the node_modules from the install process into the dist folder, along with other files, then package it. So, the target host doesn’t need to run npm install again. Currently this all happens on a Windows Agent.

But now, I need to implement a self-hosted agent with Ubuntu. So, supposing the process keeps the same, will I have any problems if I ship the node_modules from the Linux agent to a Windows host?

I’ve searched on the web but couldn’t find anything about running a "cross" built application. I’m worried about the binary libraries, like the PG. Isn’t it going to have problems when I download it on a Linux, but host it on a Windows?

Example:
Create a project on a Linux machine, with pg library. Run npm i on this project, then copy the project, including node_modules, and paste it on a Windows. Will this face problems to run?

2

Answers


  1. The scenario you mention would have issues, yes.

    Depending on what you use to build/package your executable, you can sometimes pass a platform argument

    i.e.
    for pkg you would tell it pkg -t node16-win-x64 index.js or ‘pkg -t node16-linux-x64`

    This way, the packager will make sure everything is cross-compiled, downloaded for the right platform…

    Login or Signup to reply.
  2. Short is yes, you will have issues.

    Long answer is…maybe. There are a few things I can quickly think off the top of my head that’s relevant when running Node apps on different architectures/OSs (and I’m sure there are more):

    • binary Node modules built for a specific OS/Node version
    • passing environment variables in npm scripts, wrapped in double quotes etc
    • path separators (backslash on Windows vs forward slash on Linux)
    • path case sensitivity (case sensitive on Linux).

    Your issue is the first one: moving the node_modules folder between Windows and Linux. This might work if you don’t have any binaries and just modules that are required in Node. However if you do have binaries, then as you rightly point out they’ll fail if they were built for one architecture and you try to run them on another.

    A real-world example: the old Node Sass package (before Dart Sass) was copiled into a binary. If you swap environment you’d see errors like:

    Error: Missing binding C:…node_modulesnode-sassvendorwin32-x64-83binding.node. Node Sass could not find a binding for your current environment: Windows 64-bit with Node.js 14.x

    How to fix

    You’ve got a few ways to get round this:

    • build and host on the same OS
    • build on Linux and host in Linux in a container (e.g. docker) on Windows via WSL, if you have permissions
    • run npm rebuild after deploying onto the Windows box.

    The npm rebuild (or the npm rb alias) rebuilds binaries, useful for after you’ve changed Node version or, as in your case, operating system.

    An additional recommendation

    I’d recommend double checking your dependencies are correctly installed as either devDependencies when required at build time and dependencies if required at runtime (or both build and run time). You can then run your build commands on linux to generate your website/artifacts, and then run npm prune --production to strip out the devDependencies. This means your package will just include the runtime dependencies.

    In my experience the runtime dependencies will likely not be binaries and you won’t have your original issue, and a smaller bundle size.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search