1

** See EDIT below **

I have created a simple MERN (Mongo, Express, React, NodeJS) application to form the base of a project. I am exploring the possible ways of creating executable files for deployment once the application is completed. The executables should be created for multiple operating systems and architectures.

The application conforms of a NodeJS backend which is running an Express web server with access to a MongoDB instance (it is actually NeDB but I've just called it Mongo for simplicity) and the front end is created with React.

I have tried using PKG and have had a brief look at nexe and it looks like either of these tools should provide me with a solution.

However, due to my project's file structure, I am having some issues. My folder structure for my application is as follows:

/
/server
....<express files>
....package.json
/client
....<react files>
....package.json
package.json

The reason for this folder structure is to allow my application to run both server and client applications by running npm start from the root directory. This is done by using the root folder's package.json file which has the following contents:

{
  "name": "MyApplication",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "client": "cd client && npm start",
    "server": "cd server && npm start",
    "start": "concurrently \"npm run server\" \"npm run client\" --kill-others"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "concurrently": "3.5.1"
  },
  "pkg": {
    "assets": [
      "client/*",
      "server/*"
    ]
  }
}

Essentially I am trying to create an executable file that mimics the behaviour of when I run npm start at the root. The executable should start the backend services in the server directory and also should execute the React code within the client directory.

As you can see, I have tried to add some parameters to pkg but this does not seem to work.

Is there a way to configure PKG or any other similar tool to produce what I am looking for? Or will I have to have a separate executable file for both server and client? Ideally I would just want the one file.

Thanks in advance.

** EDIT **

I have come across the following boilerplate application that essentially achieves what I am looking for: https://github.com/crsandeep/simple-react-full-stack

However, I am struggling to make it work with PKG. I have been able to successfully generate a .exe file but sadly when I load the root page in a browser (localhost:8080) it presents the error message Cannot GET / but the example API call works fine.

I'm guessing this is due to something missing in my package.json file but I can't seem to work it out. Without running the application using PKG it works fine.

Here are the additions to the package.json file that I have made:

"pkg": {
    "scripts": "./dist/bundle.js",
    "assets": [
      "./dist/index.html",
      "./dist/favicon.ico"
    ]
  },
  "bin": "src/server/index.js"

Which I then run PKG with the following statement (from the same directory as the package.json)

pkg . --target node10-win-x64 --out-dir ../

I have tried many different combinations of items in the package.json but I can't seem to get it right.

Does anyone have a solution for this?

Weagertron
  • 161
  • 2
  • 12
  • I think you are getting a bit confused here. For production you want your server to serve your assets to the browser which will execute the Javascript automatically. So you need some kind of bundled artefact for your front-end code, and then have the server code running on the back end. There should be no need to run the React application separately. – Marcus Apr 23 '19 at 10:16
  • Thanks for your input @Marcus. In the time since I posted this question I have been looking into this and I think the best solution for my project will be to go into server side rendering to enable a single entry point into my application – Weagertron Apr 23 '19 at 11:37
  • Hi @Marcus , I have been looking into potential solutions to my problem and I seem to be having difficulty finding a solution that will work with PKG. I am by no means a NodeJS expert so could use some help finding a solution. Any chance you could point me in the direction of a way to implement your suggestion that will work with PKG? Thanks. – Weagertron Apr 24 '19 at 08:21
  • I really think the best thing would be for you to go back to basics and learn about client/server relationships and what is involved in publishing a website. Take a look at the MDN docs: https://developer.mozilla.org/en-US/docs/Learn/Getting_started_with_the_web/Publishing_your_website – Marcus Apr 24 '19 at 08:35
  • Thanks @Marcus , I will brush up on that stuff. I have created web applications before and I am pretty familiar with the general process of publishing websites. It is more the case of working out a way to have Express and React in a single application with a single entry point so that it can be packaged into an executable which can be deployed. Whether that be using SSR or a different architecture. That is the main area where I am struggling – Weagertron Apr 24 '19 at 08:43

1 Answers1

0

I managed to make it so the boiler plate code I got from https://github.com/crsandeep/simple-react-full-stack can now be generated as an executable file using PKG.

I was very close to getting it working in my edit to the question but here is the full solution:

Ensure that the package.json contains the following:

"pkg": {
  "scripts": "./dist/bundle.js",
  "assets": [
    "./dist/index.html",
    "./dist/favicon.ico"
  ]
},
"bin": "src/server/index.js"

Then, in the src/server/index.js file change the line that reads:

app.use(express.static('dist'));

to:

const path = require('path');
app.use(express.static(path.join(__dirname, '../../dist')));

This will then place the necessary files into the dist directory using the package.json file and then using path.join(__dirname ensures that it looks for them in the right place.

Weagertron
  • 161
  • 2
  • 12