Deploying a Full Stack Node app npm / package.json architecture - javascript

I have a repository which contains a backend (Node/Express) and a Frontend client, as such:
├── build
├── config
├── coverage
│   └── lcov-report
├── dist
│   └── static
├── server (node/express server)
│   ├── coverage
│   ├── docs
| ├── src
│   ├── etc
│   └── package.json
|
├── src (Vue.js : client code)
│   ├── api
│   ├── assets
│   ├── components
│   ├── router
│   └── store
└── static
└── package.json
I have two package.json files, one for the client and one for the server.
I face issues deploying on services such as Heroku as they don't expect two different npm packages in one repository (I think). How is it possible to deploy to Heroku (or others) with this setup?
Would it be wiser to have 1 package.json file for both parts of the application?
Which would be the advantage and disadvantages of having both frontend and backend parts in the same package.json?

You can use heroku-postbuild and maintain separate package.json files for your client and server in a single git repo that you push to Heroku.
For example, in one of my projects, the directory structure looks like this:
|-- package.json (for node/express server)
|-- Procfile
|-- www
|--client
|-- package.json (for Ionic/Angular client app)
|-- ...
|--server
|--- ...
|-- server.js (top level node.js/express script for server)
In my top-level package.json, I have:
"scripts": {
"start": "node www/server.js",
"heroku-postbuild": "cd www/client && npm install && npm run build"
},
In my client package.json I have:
"scripts": {
"build": "ionic-app-scripts build",
...
},
And finally in my Procfile I have:
web: npm start
With this solution, Heroku runs my server and builds my client code on every Heroku build.
I think client and server package.jsons should be kept separate for several reasons. For one thing, you really don't want all your server-side code bundled into your client.

I had a similar problem deploying to heroku.
I use a package called concurrently to start client side and server side via just the start script in the server side package.json. I also use node's built in proxy feature to send any requests from the client to the server by adding a line to the client package.json.
By the way, I use create-react-app for the client side so thats why some stuff looks a little strange.
My folder structure is
Server folder
Server package.json
Client folder
Client package.json
Server package.json:
"scripts": {
"start": "concurrently \"npm run server\" \"npm run client\"",
"server": "cross-env NODE_ENV=production node server.js",
"server-dev": "nodemon --watch ./ --exec babel-node -- server.js",
"client": "node start-client.js",
"dev": "concurrently \"npm run server-dev\" \"npm run client\"",
"lint": "eslint ."
},
Client package.json:
"proxy": "http://localhost:3001",
I assume Heroku just looks for a start script and runs that.
I think having some degree of separation between your server and client is a good idea so I wouldn't recommend trying to fit it all in one package.json
If you want you could probably find a tutorial online by googling with keywords like: heroku concurrently server client
btw, you don't need CORS if you set up like this
Cheers

I have run into similar issues. I have found that the easiest solution is to have two separate Git repositories, one for the backend and one for the frontend. Then there is only one package.json in the root folder of each repository.
You could then create a third repository and use Git submodules to include the backend and frontend repositories. You would use the "combined" repository to do development work, but you would deploy the individual repositories. This offers the most compatibility with deployment tools while allowing you to still maintain a single repository for easy development.

Related

GitHub Pages User Page Showing Blank Screen

I recently created a barebones React.js website and deployed it to GitHub pages as a user page, meaning the page should have a url of propertycashflowapp.github.io. The GitHub repo is public and can be found here.
Here is the directory tree:
├── README.md
├── index.html (this index.html is a duplicate of the one in the public directory)
├── package-lock.json
├── package.json
├── public
│   ├── favicon.ico
│   ├── index.html
│   ├── logo192.png
│   ├── logo512.png
│   ├── manifest.json
│   └── robots.txt
└── src
├── App.css
├── App.js
├── App.test.js
├── index.css
├── index.js
├── logo.svg
├── reportWebVitals.js
└── setupTests.js
I followed all the steps in the GitHub Pages documentation. When I run npm start, the webpages shows up correctly. However after deployment when I type the url https://propertycashflowapp.github.io, I only see an empty screen.
I tried to move my index.html file to the root directory as was advised online, but it did not work. I also tried to change the line
"homepage": "https://propertycashflowapp.github.io/" many times to include the path to the index.html file, but this did not work either. I also added <BrowserRouter basename={process.env.PUBLIC_URL}> to my index.js that wrapped around my <App /> JSX tag, but this did not fix it either. I've looked at several other answers for similar questions but wasn't able to fix my issue.
All help would be greatly appreciated, thank you!
You are trying to deploy the react project with the devlopment code or the source code. This code typically contains unminified and uncompressed JavaScript and CSS files. It is not optimized or suited for production use.
You need to run npm run build command.
To know what the command does read
What is "npm run build" in create-react-app?
There are two options to deploy you code.
Option 1: use the build folder instead of the complete react project
Use this option if you want easy deployment and do not intend on changing your code.
In your local development environment, build your React application using the command npm run build. This will create a "build" folder with the optimized production version of your application.
The build folder is the folder which will contain index.html file.
Commit and push the build folder to the GitHub repository.(should be the root folder)
cd build
git init
git add .
git commit -m "message"
git branch -M
git remote add origin https://github.com/propertycashflowapp/propertycashflowapp.github.io.git
git push origin main
Enable GitHub Pages for your repository by going to the repository settings and selecting the "main" branch option under "GitHub Pages" section.
Option 2: using gh-pages
Use this option if you intend to write new code regularly. (needs setup)
Please read this article first: https://www.c-sharpcorner.com/article/how-to-deploy-react-application-on-github-pages/
Install the gh-pages package in your React app by running npm install gh-pages --save-dev in the command line.
Add a homepage field in your package.json file. This field should contain the URL of your GitHub Pages repository, which will be in the format https://propertycashflowapp.github.io.
Create a new script in your package.json file for deploying to GitHub Pages. For example, you can add the following script:
"scripts": {
"predeploy": "npm run build",
"deploy": "gh-pages -d build",
...
}
Sample package.json file can be found here
Run the deploy script by executing npm run deploy in the command line. (If you change any code run npm run deploy for deploying the changes.)
Wait for the deployment to complete and then visit the URL of your GitHub Pages repository to see your app live.
If you encounter any issue in the process, you can check the logs for troubleshooting.
Hope this helps.

Is it possible to use #here/maps-api-for-javascript with latest react-scripts 5.0.0? (ReactJS, Here Maps)

I'm trying to upgrade packages in my project and getting a problem with the use of #here/maps-api-for-javascript. When I use react-scripts 4.0.3, everything is fine and I can interact with the map.
But when I use react-scripts 5.0.0, I only see the empty map with the Here Maps logo. Also, I see webpack errors in the console that are related to the map
I need to understand why this happening and how can it be fixed to use Here Maps with react-scripts 5.0
My code with the described problem: https://codesandbox.io/s/modest-margulis-ugp8mw?file=/README.md
As discussed in comment please refer below react guide .
Working with React
This article describes how to use the HERE Maps API for JavaScript with React. The target is to demonstrate how to build a React component that displays the map and responds to the actions of the user, be it direct interaction with the map or the other components.
Setup
For the fast setup of the new React application we will use the Create React App environment. It provides a fast way to get started building a new single-page application. Execute the npx runner as below (it requires Node >= 8.10 and npm >= 5.6):
npx create-react-app jsapi-react && cd jsapi-react
The call above produces the scaffolding needed to start the application. The directory structure in the jsapi-react directory looks as follows. The React components reside in the src directory:
my-app
├── README.md
├── node_modules
├── package.json
├── .gitignore
├── public
│ ├── ...
└── src
├── App.css
├── App.js
├── App.test.js
├── index.css
├── index.js
├── logo.svg
└── serviceWorker.js
└── setupTests.js
The recommended way to use HERE Maps API for JavaScript within this environment is to install maps-api-for-javascript NPM package which is hosted at https://repo.platform.here.com/. Add a registry entry to the NPM configuration by executing the following command:
npm config set #here:registry https://repo.platform.here.com/artifactory/api/npm/maps-api-for-javascript/
After that the package from the #here namespace can be installed as usual:
npm install #here/maps-api-for-javascript --save
At this step the environment setup is complete, all packages needed to build a sample application are installed, and it is possible to start the development server by executing:
npm start
The command above launches the development server with the "hot reload" functionality and opens the application in the browser.
For more details please refer below guide.
https://developer.here.com/documentation/maps/3.1.30.15/dev_guide/topics/react-practices.html

Sharing a typescript library in a monorepo

I'm trying to setup a monorepo with 3 services sharing some library code.
This is the current situation:
repo: web
pdf/
package.json
reference to shared-ts using github url
tsconfig.json
frontend/
package.json
reference to shared-ts using github url
tsconfig.json
repo: mobile (react-native)
package.json
reference to shared-ts using github url
tsconfig.json
repo: shared-ts
package.json
tsconfig.json
This works but it's a pain to commit to shared-ts, build, change the hash in package.json and commit again.
This is what I'd like to achieve:
repo: monorepo
pdf/
package.json
reference to ../shared-ts
tsconfig.json
frontend/
package.json
reference to ../shared-ts
tsconfig.json
mobile/
package.json
reference to ../shared-ts
tsconfig.json
shared-ts/
package.json
tsconfig.json
So far I've tried:
TypeScript project references, but it seems like there is no way to have dependencies in the shared-ts project
"shared-ts": "../shared-ts" in package.json but it copies shared-ts into the node_modules of each package so I have to re-run yarn everytime I make a change
yarn link in postinstall: error TS2307: Cannot find module 'shared-ts' or its corresponding type declarations.
creating a symlink directly in postinstall with ln -s ../shared-ts/ node_modules/shared-ts/ but it seems TypeScript fails to find the module
npm link in postinstall seems like the most promising but it's really slow and I'm having trouble running it in CI because of some permissions issues.
Is there a good way of doing this? Any ideas on other things I could try?
Solution 1:
with Lerna
you can use workspace and Lerna
yarn workspace & lerna
├── README.md
├── lerna.json
├── package.json
├── packages
│ ├── pdf
│ │ ├── package.json /* "shared-ts": "^1.0.0" */
│ │ └── src
│ ├── frontend
│ │ ├── package.json
│ │ └── src
│ ├── mobile
│ │ ├── package.json
│ │ └── src
│ ├── shared-ts
│ │ ├── package.json
│ │ └── src
├── tsconfig.json
└── yarn.lock
here is an example repo
here you can see x-cli is getting shared x-core
Solution 2:
without Lerna
you can use mtsl package which enables us to make tangible symlinks. you can install this package globally
npm install -g mtsl
then you just need to start to separate these three commands in terminal.
mtsl startwithoutadd -s path_of_project/packages/shared-ts -d path_of_project/packages/pdf/node_modules/shared-ts
mtsl startwithoutadd -s path_of_project/packages/shared-ts -d path_of_project/packages/frontend/node_modules/shared-ts
mtsl startwithoutadd -s path_of_project/packages/shared-ts -d path_of_project/packages/mobile/node_modules/shared-ts
Note don't stop this three watcher. after testing, you can make single command from the package.json script
Your use-case can be handled using the npm7 workspaces. In short your new monorepo structure should look like below:
repo: monorepo
package.json // <- here you define the workspaces
pdf/
package.json
reference to shared-ts
tsconfig.json
frontend/
package.json
reference to shared-ts
tsconfig.json
mobile/
package.json
reference to shared-ts
tsconfig.json
shared-ts/
package.json
tsconfig.json
You need to list the workspaces in the root package.json which might look something like below:
{
"name": "awesome-monorepo",
"workspaces": [
"pdf",
"frontend",
"mobile",
"shared-ts"
]
}
After doing that, wherever in the monorepo you decide to use the shared-ts you can add that to dependencies or devDependencies simply referring by the version number instead of relative path.
All the node modules inclusive the workspaces gets hoisted to the root node_modules which is why the module resolution should work without friction.
You can use NX to maintain your repos, wherein your web and mobile repos will be your apps, and the shared-ts will be a lib such that, web and mobile depends on shared-ts lib.
You have a common package.json, or a separate package.json for each repo individually. NX provides dependencyGraph and affected features, wherein if you change the common libs, it figures out which modules/app to build without having to build the complete thing.
Your code structure would look like:
apps:
web:
src
package.json
mobile:
src
package.json
libs:
shared-ts:
src
package.json
workspace.json
It'll probably be best to lookup the official docs for the best setup and options, but I believe it provides what you're looking for.
using yarn workspace & lerna
here is an example monorepo-template
I have done the things you are curious about in a recent project.
Desired results can be achieved by monorepo using lerna and yarn workspace. For details, please go to this link
With the above, we will be creating a package of types.
In other packages, we will be just importing types from packages like below:
import { Post } from "#types";
Things are much easier this way than linking packages ourslef.

How to get Mocha to execute unit tests in multiple subfolders in Node.js

I'm integrating tests into my Node server and am having some trouble with unit testing. When I run npm test in my root directory, Mocha automatically runs all tests inside of my test folder. However, the unit tests which are dispersed throughout the project do not run. How can I ensure that Mocha automatically runs them?
You could modify the npm test command to find your test files and run mocha against them.
Assuming a directory structure like:
project/
src/
test/
main-tests.test.js
things/
test/
thing.test.js
more_things/
more-things.test.js
You would change your package.json like this:
scripts: {
...
"test": "mocha $(find . -name '*.test.js')"
...
}
There are probably other ways to do this, like specifying the expected glob patterns of the locations of your test files.
Both of these methods require a plain pattern to the names of your test files.
I don't see why you would want to have your tests "dispersed throughout the project". I think you would be much better off keeping all of them in a dedicated test folder. You can mirror the folder structure of your src folder, if your concern is that you want to easily find the test for a specific source file. Example:
project/
├── src/
│ ├── one/
│ │ └── foo.js
│ └── two/
│ └── bar.js
└── test/
├── one/
│ └── foo.test.js
└── two/
└── bar.test.js
Regardless of whether you decide to reorganise your project, the way to get mocha to execute all test files recursively is with the following:
scripts: {
"test": "mocha \"./**/*.test.js\""
}
You can replace the . with test or src (or any other folder) if you don't want to search the whole project folder.
You can read more about it here: How do I get mocha to execute tests in all subfolders recursively?

Deploying react app with webpack

I am doing a tutorial on React and I have made a youtube clone based on react. Now I wanted to upload this to my domain (hosted at one.com) but it doesn't work because bundle.js can't be found. Rather obvious since the app requires to run "npm start".
I've been googling and found that I somehow need to deploy the app by writing a deploy configuration for webpack, but I can't get it to work.
I've never understood this and I'd like to ask: how do I deploy a javascript/nodejs/webpack website to a server? Am I on the right track?
My project is based on this starter: https://github.com/StephenGrider/ReduxSimpleStarter
EDIT: So I've managed to get a bundle.js file by typing the following in cmd:
webpack ./src/index.js bundle.js
Uploaded that to the server
Now the problem is that it's looking for bundle and style in the root of the website.
Try bundling your application before running any deployment script. A package.json might have a script like this:
{
"name": "youtube-clone",
"scripts": {
"package": "webpack --config webpack.config.production.js --progress --colors",
"deploy": "npm run package && [your deployment script]"
}
}
So then you would have a file structure like this:
.
├── src/
├── .gitignore <= make sure your build files are ignored on source
├── package.json
├── webpack.config.development.js
└── webpack.config.production.js
Where one of your configs would be created for production and one for development

Categories

Resources