nodejs / single-executable

This team aims to advance the state of the art in packaging Node.js applications as single standalone executables (SEAs) on all supported operating systems.
306 stars 6 forks source link

"Cannot GET /" error when moving executable to a separate directory #102

Open rmr-code opened 4 months ago

rmr-code commented 4 months ago

I have a simple node js application using a combination of static html files and api paths. I find that after I generate the executable, it works in the current directory that contains the source code but does not work when moved to another directory.

The error I get on loading 'https://localhost:3000' from a different directory is: Cannot GET /

The following is the server.js

// server.js

// Import required modules
const express = require('express');
const path = require('path');

// Create an Express application
const app = express();

app.use(express.static('public'))

// api calls

app.get('/api/test', (req, res) => {
    res.send('test)
  });
})

// Start the server
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`Server is running on port ${PORT}`);
});

The following is: config.js

{
    "compilerOptions": {
      "target": "es2022",
      "lib": ["es2022"],
      "module": "commonjs",
      "esModuleInterop": true,
      "forceConsistentCasingInFileNames": true,
      "strict": true,
      "skipLibCheck": true
    }
 }

The following is: sea-config.json

{
    "main": "server-out.js",
    "output": "sea-prep.blob"
 }

And the following are the commands I used to create the server executable

1 Build using esbuild

npm run build

3 create blob

node --experimental-sea-config sea-config.json

4 create copy of exe

cp $(command -v node) server

5 inject experimental node

npx postject server NODE_SEA_BLOB sea-prep.blob --sentinel-fuse NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2

When I run ./server from the created directory, it works. However, when I move the exe to a separate directory and run it, it gives the Cannot GET / error.

What am I doing wrong? Thanks

rmr-code commented 4 months ago

It seems to be that the public directory too needs to be copied. Hmm ... makes sense, I guess. I wonder if there is a way to have its content included too in the executable?

kerwenzhang commented 1 week ago

@rmr-code Do you have a solution? I met similar problem. I tried to add the html, css, js files which front UI need to assets:

{ 
    "main": "out.js", 
    "output": "sea-prep.blob",
    "assets": {
        "favicon.ico":"./../client/dist/client/browser/favicon.ico",
        "index.html":"./../client/dist/client/browser/index.html",
        "main.js":"./../client/dist/client/browser/main.js",
        "polyfills.js":"./../client/dist/client/browser/polyfills.js",
        "styles.css":"./../client/dist/client/browser/styles.css"
    }
}

Although I could get these files content by getAsset(), but I could not use app.use(express.static('public')) anymore.

kerwenzhang commented 1 week ago

@RaisinTen @jviotti @arcanis @Trott @ghoullier May I know how Node.SEA support the routing for static files? PKG could package all necessary files (including front UI files) into one single exe, and extract them to temp folders during application running. When these files is requested, we could use express.static() to get them by auto. How should I implement this in Node SEA?

rmr-code commented 1 week ago

@kerwenzhang: I could not figure this out. It was something I was experimenting with and not in a production environment. So shelved it for now.

Trott commented 1 week ago

@nodejs/single-executable