npm wait for port/command before executing next (concurrently) - node.js

So in my npm package I currently have this script:
"start": "concurrently --kill-others \"npm run dev\" \"electron .\""
The problem is that since the server wouldn't be up yet when electron runs its command, it shows up as blank. This is resolved by reloading the app once the server starts.
So I was wondering if there was a way to wait for the server to start by detecting the port or some other method so that I don't have to do the reload myself.
Here's how I'm setting up the url (trying to implement Vue into it).
let format = live ?
url.format({
pathname: path.join(__dirname, 'dist/index.html'),
protocol: 'file:',
slashes: true
})
:
'http://localhost:8080'
// Specify entry point to default entry point of vue.js
win.loadURL(format);

The key here is to get your dev server up immediately and then implement auto reload or hot module replacement.
Have you looked at electron-webpack? Then your start script would look like:
"dev": "electron-webpack dev"
And your main.js:
const url = process.env.NODE_ENV !== 'production'
? `http://localhost:${process.env.ELECTRON_WEBPACK_WDS_PORT}`
: `file://${__dirname}/index.html`
window.loadURL(url)
I'll recommend you to checkout electron-webpack-quick-start for an example of implementation.

You can use readyator if you want to wait for ports (or URLs) to be ready before starting your script.
Installation: npm i readyator
Waiting for port 80 to be ready before starting Electron with readyator:
readyator 80 "electron ."
It also comes with a handy Node.js API:
import {runWhenReady} from 'readyator';
await runWhenReady([80], 'electron .');

Related

express server starting react client

Until now, I have been using create-react-app for my projects, with the express-server and the react client each in their own folders.
However, I am now trying to avoid create-react-app in order to really understand how everything work under the hood. I am reading an Hacker Noon article that explains how to setup react with typescript and webpack. In this article they also have the express server at the root of the client which compiles everything itself:
const path = require('path'),
express = require('express'),
webpack = require('webpack'),
webpackConfig = require('./webpack.config.js'),
app = express(),
port = process.env.PORT || 3000;
app.listen(port, () => { console.log(`App is listening on port ${port}`) });
app.get('/', (req, res) => {
res.sendFile(path.resolve(__dirname, 'dist', 'index.html'));
});
let compiler = webpack(webpackConfig);
app.use(require('webpack-dev-middleware')(compiler, {
noInfo: true, publicPath: webpackConfig.output.publicPath, stats: { colors: true }
}));
app.use(require('webpack-hot-middleware')(compiler));
app.use(express.static(path.resolve(__dirname, 'dist')));
In the end, the start command looks like it:
"start": "npm run build && node server.js"
So I assume the client and the server start on the same port.
Why would you do such a thing? Are there any pros and cons?
It is true that this will allow your development to happen using the same server as express and that web pack will continuously update your dist/index.html file with whatever updates you make to your file. There's not too much of a disadvantage to this as this is just for development. But typically on prod you'll have a single built file that you will serve. And it will not web pack-dev-middleware to be running. Once you've built your server. For the purposes of production it might be possible that you'll only need static assets. But typically, even the server which serves mostly client files will potentially need a server if you want to do server side rendering and/or code splitting.
The command: "npm run build && node server.js" will run the bash/cmd commands into the terminal. npm run build is one step because of the use of && it will if that command succeeds, run the next command which is node server.js which is a strange command I would probably run node ./ (and put the server as index.js) or at least just write node server.
What I'd prefer to see in your package.json:
"start": "yarn build && node ./"
That would be possible if you mv server.js index.js (and npm i -g yarn).
Another thing to note, and look into is what the build step does.
Further Explanation:
The command runs the build step so check what your "build": key runs in your package.json.
This command will probably not exit with the code 1 (any exit code of a terminal process that is above 0 will result in an error and will not pass the &&).
Presumably, the build process described in the package.json will take all the javascript and CSS files and put them into the index.html file which will then be sent to the client side whenever someone access the '/' path.
After that succeeds, it will start the server that you put the code to above.
res.sendFile(path.resolve(__dirname, 'dist', 'index.html'));
will happen if anybody comes across the '/' path.

How can I pass configuration options to yarn/npm

I have a react app and server that provides REST services to the react app. In development the react app runs on port 3000 and the server on port 3001.
To support this the package.json file has proxy statement "proxy": "http://localhost:3001"
However in production this isn't wanted so I like a means of controlling this from "yarn start" so that I need only one package.json that uses the proxy in development but not in production. Thanks in advance
so that I need only one package.json
you should only have one package.json...
You probably have something that looks like
"scripts": {
"start": "webpack-dev-server --host 0.0.0.0 ..."
...
}
in your package.json - when you run yarn start, ^ that is what is actually being run. That's not something you would run in production though. If you want something else to run in production, add another item to scripts that runs your express (?) app directly (something like node /path/to/index.js is probably close).

How to set up dev and API server from create-react-app?

I've started a new app with create-react-app, and ejected from that. I made a small express server as follows:
const express = require('express');
const app = express();
if(process.env.NODE_ENV === 'production') {
app.use(express.static('build'));
}
const port = process.env.PORT || 3000;
app.listen(port, () => {
console.log(`Server started at: http://localhost:${port}/`);
});
In package.json I've added a line, "proxy": http://localhost:3000", as well as switching the commands:
"scripts": {
"run": "npm-run-all -p watch-css start-js",
"start": "node server.js",
},
run used to be start.
However now of course when I run npm start and go to localhost:3000, I get Cannot GET /. I need this server to receive and return local API calls I'll be making from my app, but I also want it to run a hot-reloading dev server just like the old npm start (now npm run) command did. How do I do this?
Some time ago I made a fork of the create-react-app repository adding webpack watch option because of this same reason. It might help you.
Just to add more info, I really invested time looking on how to get webpackdevserver to build the "bundle.js", and found that it is not possible because it loads the bundle into memory but doesn't persist it, so the file is never created. The only way available is the webpack watch option but, I don't understand why the create-react-app team can't add it to the repo, it's a really requested feature, and there are more forks than mine that solves this issue. So, you have three options:
Use the proxy server in package.json (if it works)
Make your own fork and add the watch option, or use an existing one
Don't use create-react-app

How can I run sails console without a webserver (using any ports)?

I have a Sails server running, and I want to execute some commands from inside of lifted Sails.
The problem is, then I run sails console - it bootstraps another instance of Sails, and trying to load another webserver next to existing, by default using the same ports.
By some environment limits, I can use only one port at the time. So I cannot load another webserver on the same machine.
Is there a way how to run sails console without using any ports?
Thank you.
There is an option. Use sails console --dontLift
Running console without port is I belive not possible at all.
Add inside package json npm script to run console on another port (or if you have sails installed globally just run sails console --port xxxx).
Part of my package json:
"scripts": {
"start": "node app.js",
"console": "sails console --port 1338",
"test": "mocha",
"docs": "rimraf public/docs && apidoc -i config/routes -o public/docs"
},
As you can see... npm run console will run sails console on port 1338 while deafult port of my app is 1337...

How to make the webpack dev server run on port 80 and on 0.0.0.0 to make it publicly accessible?

I am new to the whole nodejs/reactjs world so apologies if my question sounds silly. So I am playing around with reactabular.js.
Whenever I do a npm start it always runs on localhost:8080.
How do I change it to run on 0.0.0.0:8080 to make it publicly accessible? I have been trying to read the source code in the above repo but failed to find the file which does this setting.
Also, to add to that - how do I make it run on port 80 if that is at all possible?
Something like this worked for me. I am guessing this should work for you.
Run webpack-dev using this
webpack-dev-server --host 0.0.0.0 --port 80
And set this in webpack.config.js
entry: [
'webpack-dev-server/client?http://0.0.0.0:80',
config.paths.demo
]
Note If you are using hot loading, you will have to do this.
Run webpack-dev using this
webpack-dev-server --host 0.0.0.0 --port 80
And set this in webpack.config.js
entry: [
'webpack-dev-server/client?http://0.0.0.0:80',
'webpack/hot/only-dev-server',
config.paths.demo
],
....
plugins:[new webpack.HotModuleReplacementPlugin()]
This is how I did it and it seems to work pretty well.
In you webpack.config.js file add the following:
devServer: {
inline:true,
port: 8008
},
Obviously you can use any port that is not conflicting with another. I mention the conflict issue only because I spent about 4 hrs. fighting an issue only to discover that my services were running on the same port.
Configure webpack (in webpack.config.js) with:
devServer: {
// ...
host: '0.0.0.0',
port: 80,
// ...
}
I am new to JavaScript development and ReactJS. I was unable to find an answer that works for me, until figuring it out by viewing the react-scripts code. Using ReactJS 15.4.1+ using react-scripts you can start with a custom host and/or port by using environment variables:
HOST='0.0.0.0' PORT=8080 npm start
Hopefully this helps newcomers like me.
Following worked for me -
1) In Package.json add this:
"scripts": {
"dev": "webpack-dev-server --progress --colors"
}
2) In webpack.config.js add this under config object that you export:
devServer: {
host: "GACDTL001SS369k", // Your Computer Name
port: 8080
}
3) Now on terminal type: npm run dev
4) After #3 compiles and ready just head over to your browser and key in address as http://GACDTL001SS369k:8080/
Your app should hopefully be working now with an external URL which others can access on the same network.
PS: GACDTL001SS369k was my Computer Name so do replace with whatever is yours on your machine.
I struggled with some of the other answers. (My setup is: I'm running npm run dev, with webpack 3.12.0, after creating my project using vue init webpack on an Ubuntu 18.04 virtualbox under Windows. I have vagrant configured to forward port 3000 to the host.)
Unfortunately putting npm run dev --host 0.0.0.0 --port 3000 didn't work---it still ran on localhost:8080.
Furthermore, the file webpack.config.js didn't exist and creating it didn't help either.
Then I found the configuration files are now located in build/webpack.dev.conf.js (and build/webpack.base.conf.js and build/webpack.prod.conf.js). However, it didn't look like a good idea to modify these files, because they actually read the HOST and PORT from process.env.
So I searched about how to set process.env variables and achieved success by running the command:
HOST=0.0.0.0 PORT=3000 npm run dev
After doing this, I finally get "Your application is running here: http://0.0.0.0:3000" and I'm finally able to see it by browsing to localhost:3000 from the host machine.
EDIT: Found another way to do it is by editing the dev host and port in config/index.js.
If you're in a React Application created with 'create-react-app' go to your package.json and change
"start": "react-scripts start",
to ... (unix)
"start": "PORT=80 react-scripts start",
or to ... (win)
"start": "set PORT=3005 && react-scripts start"
Following worked for me in JSON config file:
"scripts": {
"start": "webpack-dev-server --host 127.0.0.1 --port 80 ./js/index.js"
},
I feel dirty for telling you this b/c of the security implications of what you're trying to do, but here you go.
npm run dev -- -h 0.0.0.0 -p 80
For me: changing the listen host worked:
.listen(3000, 'localhost', function (err, result) {
if (err) {
console.log(err);
}
console.log('Listening at localhost:3000');
});
was changed to :
.listen(3000, '0.0.0.0', function (err, result) {
if (err) {
console.log(err);
}
console.log('Listening at localhost:3000');
});
and the server started listening on 0.0.0.0
I tried the solutions above, but had no luck. I noticed this line in my project's package.json:
"bin": {
"webpack-dev-server": "bin/webpack-dev-server.js"
},
I looked at bin/webpack-dev-server.js and found this line:
.describe("port", "The port").default("port", 8080)
I changed the port to 3000. A bit of a brute force approach, but it worked for me.
For me, this code worked. Just add it on your package.json file :
"scripts": {
"dev-server": "encore dev-server",
"dev": "webpack-dev-server --progress --colors",
"watch": "encore dev --watch",
"build": "encore production --progress"
},
And run the script "build" by running npm run build
For windows create file runMobile.bat
set PORT=8081
set HOST=192.168.3.20
npm run dev
I tried this to easily use another port:
PORT=80 npm run dev

Resources