Webpack add watch mode without compiling - node.js

I have the following npm scripts:
"build:server:dev": "webpack --config ./webpack.server.dev.config.js --watch",
"build:client:dev": "webpack --config ./webpack.client.dev.config.js --watch",
"build:server:prod": "webpack --config ./webpack.server.prod.config.js",
"build:client:prod": "webpack --config ./webpack.client.prod.config.js",
"start:server:prod": "export NODE_ENV=production && node ./dist/server.*.js",
"start:iso:dev": "export NODE_ENV=development && npm run build:client:dev & npm run build:server:dev",
"start:iso:dev:win": "set NODE_ENV=development && concurrently --kill-others \"npm run build:client:dev\" \"npm run build:server:dev\"",
"start:iso:prod": "npm run build:client:prod && npm run build:server:prod && npm run start:server:prod"
The problem I'm facing is that the server compilation depends on the client compilation (I generate an html template where I inject the scripts with webpack on the client, and I use this template for server rendering in the server script).
In nearly all of the cases, the client finishes compiling before the server, but while running these scripts concurrently, there is no way to ensure that this will always be true.
When running webpack watch mode, it is not possible to run these scripts in sequence, as watch mode will block the second script from running.
The most obvious solution in my mind is to compile them without watch mode once, and then attach watch mode on the fly after the initial compilation.
I'm not sure how to achieve this though, and I would not like to compile them twice, just for the sake of attaching watch mode.
The second alternative I have in mind is to fiddle with webpack progress plugin, and somehow compile the server script after the client script has finished.
I dislike this solution, because I don't want to hard couple one script to another.
So is there a way to run client and server compilation sequentially from an npm script while using webpack --watch mode?

Maybe this will help you parallel-webpack although I didn't try it it has watch mode and would probably just require connecting your configs for both server and client side someway along this way:
// some script for running parallel builds
module.exports = [
require('./webpack.server.dev.config.js'),
require('./webpack.client.dev.config.js'),
];
then check running in watch mode

I found a nice solution using the npm package wait-on:
https://github.com/jeffbski/wait-on
The npm script I used (Unix & Windows):
"start:iso:dev": "export NODE_ENV=development && npm run clean:build && npm run build:client:dev & wait-on public/build/index-dev.html && npm run build:server:dev --inspect",
"start:iso:dev:win": "npm run clean:build:win && set NODE_ENV=development&& concurrently \"npm run build:client:dev\" \"wait-on public\\build\\index-dev.html && npm run build:server:dev\"",
This works like a charm.

Related

how does cross-env command works in nodejs?

I have the following line in my package.json
"scripts": {
"start": "cross-env NODE_ENV=development node index.js"
}
I can see that "yarn start" command is running fine, but when I run
"cross-env NODE_ENV=development node index.js" command directly in the terminal, I am getting the following error:
zsh: command not found: cross-env
If cross-env is not registered in the terminal, how does "yarn start" command works?
https://docs.npmjs.com/cli/v7/configuring-npm/folders#executables
When in local mode, executables are linked into ./node_modules/.bin so that they can be made available to scripts run through npm. (For example, so that a test runner will be in the path when you run npm test.)
It's simply a feature to make things easier. It also means if you're working a project with multiple people, you only have to npm install --save a module--you don't have to worry about everyone in your project manually installing it globally. If you wish to run it yourself on the command line, you can either:
Install the module globally
Manually type in the command line ./node_modules/.bin/cross-env

How to run few npm scripts in one-line shell command?

I have three scripts in package.json:
Watch server TypeScript
Nodemon
Webpack
"scripts": {
"watch-server": "tsc --watch --project ./server/tsconfig.json",
"watch-node": "nodemon --watch ./server/build/ --watch ./server/templates -e js,json,pug",
"watch-client": "webpack --config ./webpack/webpack.dev.conf.js --watch"
}
Everytime I start my computer and open VS Code I need to open three separate PowerShell terminals and type in those commands one-by-one. Is there any way to launch these three separate terminals with their own commands in one shell command? Maybe via tasks.json?
On linux or any bash terminal, you can use && to combine multiple commands, i
You can do as
npm run watch-server && npm run watch-node && npm run watch-client
A quick google search for powershell suggested using semicolon
so on powershell you can do something like below if using && does not work
npm run watch-server;npm run watch-node ; npm run watch-client
Also keep in mind, you can additionally add fourth command in your npm scripts in package.json where you can use one of these combined commands which works for you, like
start-all: npm run watch-server && npm run watch-node && npm run watch-client
and then run
npm run start-all

package.json scripts failing on heroku

So I have a series of scripts that are set up to either dev servers for a React/Node Express application OR a production server on heroku. The structure of the app is as follows:
client/package.json //pckg for react app
package.json //pckg for the node server
these are the scripts in the clients package:
"scripts": {
"start": "if-env NODE_ENV=production && npm run start:prod || npm run start:dev",
"start:prod": "node server.js",
"start:dev": "set NODE_ENV=development&& concurrently \"nodemon --ignore 'client/*'\" \"npm run client\"",
"client": "cd client && npm run start",
"seed": "node scripts/seedDB.js",
"install": "cd client && npm install",
"build": "cd client && npm run build",
"heroku-postbuild": "npm run build"
}
and the only difference between the react apps package.json and the one that is automatically generated with create-react-app is as follows:
"proxy": "http://localhost:3001/",
the way its supposed to run is, install scripts at root folder, run install script to cd into client and install react apps dependencies, then heroku's post-build script should kick in to run the build script which cds into client and builds a production ready react app. finally the start script should see a NODE_ENV of production and run start:prod.
my problem is that for some reason when i push to heroku, it seems to get stuck on an infinite loop on the install script. I have NO clue why, as the exact same scripts work on other projects PERFECTLY.
https://github.com/LordKriegan/reactdbdemo
https://github.com/LordKriegan/reactdbdemo2/ if anyone wants to look at it. (doing a full stack demo for my students :/ not much of a demo if i cant get it deployed)
I got it working. Forgot create-react-app also initializes a git repo...? either that or somewhere along the way i did an extra git init. anyways i had a .git folder in my client folder, which was preventing my client folder from being pushed up. i ended up creating a new repo and pushing everything to that one and now it works. so incase anyone comes here with a similar problem... make sure you didnt end up in some kind of gitception trap. :/

Transpiling ES6 and launching Express app upon file change

I'm developing an Express app. The code uses ES6 import statements, so it needs to be transpiled by Babel in ES5 code so it can be run with Node. The ES6 source code is stored in my src directory, and the compiled code is placed in my dest directory.
I would like an npm command that I can run that will watch for any changes in my src directory, transpile the project into dest, and then restart the Express app.
Below is my solution so far (I run npm run server:watch). It uses chokidar-cli to execute the server:build and server:run scripts whenever any js file changes within my src directory. This works perfectly except that the Express app does not die when the code is transpiled again, so I get a 'port in use' exception when I try to run server:watch again.
// package.json
"scripts": {
"server:clean": "rm -f dist/*",
"server:build": "npm run server:clean && ./node_modules/.bin/babel ./src --experimental --source-maps-inline -d ./dist",
"server:run": "nodemon dist/app.js --watch",
"server:watch": "chokidar 'src/*.js' -c 'npm run server:build && npm run server:run'"
}
Am I on the right track here? What is the best solution to this sort of problem?
(For clarification, I am talking about transpiling server-side code, so webpack or any other module bundler would be inappropriate here)
nodemon is watching your dist files, and is never terminating. With your watch script, you're launching a second instance of nodemon every time there's a file change, hence the "port in use" error.
You need to launch nodemon once, and keep in running in the background while your watch script is running. This is most easily done with https://github.com/mysticatea/npm-run-all.
Install it by running:
npm install npm-run-all --save-dev
on the command line.
Then you'd edit your scripts to:
// package.json
"scripts": {
"server:clean": "rm -f dist/*",
"server:build": "npm run server:clean && ./node_modules/.bin/babel ./src --experimental --source-maps-inline -d ./dist",
"server:run": "nodemon dist/app.js --watch",
"server:watch": "chokidar 'src/*.js' -c 'npm run server:build'",
"server:dev": "run-p server:run server:watch"
}
Then, you simply run npm run server:dev on the command line to start up your server via nodemon, and start the watch/rebuild process, all in one command.
Side note: If you're developing on Windows, you won't be able to use single quotes in your scripts, you have to use double-quotes, escaped with \" in the JSON.

keep webpack dev-server running even after terminal closes

Hi is there a way i can keep webpack devserver running even after closing terminal.
"scripts": {
"dev-server": "npm run templates && webpack-dev-server -d --https --port 28443",
}
when i run npm run dev-server it starts but after closing terminal webpack devserver also closes is there any way to keep it running with pm2 or any other method.
use nohup
So if the script command is "dev-server" (according to your snippet), then go to your project root directory (where the package.json file is, which has your "scripts" section):
If on unix environment, just run nohup npm run dev-server &
If on windows, install git bash - it's sort of a mini unix environment for windows. And then run the nohup npm run dev-server &
This will start the webpack dev server and keep it running on the background
For me, my script section is
"scripts": {
"dev": "webpack-dev-server --open"
}
and the above command that I mentioned works fine
nohup did somehow not work for me, but i was able to make it work with forever.
sudo npm install -g forever
forever start -c "webpack serve" ./

Resources