NPM Failing on Trying to Find Shell Script - javascript

Console output on npm run build failure:
'.' is not recognized as an internal or external command, operable
program or batch file.
And the relevant npm file:
"scripts": {
"postinstall": "jspm install && npm run build",
"start": "http-server",
"build": "./bin/build-code",
"build-home": "./bin/build-home -dw",
"build-common-deps": "./bin/build-common-deps -dw",
"build-navbar": "./bin/build-navbar -dw",
"build-root": "./bin/build-root -dw",
"build-angular1": "./bin/build-angular1 -dw",
"build-react": "./bin/build-react -w",
"build-preact": "./bin/build-preact -dw",
"build-vanilla": "./bin/build-vanillajs",
"build-angular2": "./bin/build-angular2 -dw"
}
Looks like it's not understanding the pathing to the ./bin/build-code script location. From what I understand, it looks for files from the package.json's location? So, if the app has a bin folder in the same dir as package.json, then this is the correct pathing to the build-code script, which is within the bin folder. What gives? Using PowerShell to run npm run build if it matters.
P.S. I tried with basic Command Prompt - no changes. Someone running the same build (both of us just pulled from repo) on Cygwin said they had to "Change dos endings to unix", which doesn't tell me much and doesn't seem to be the issue.

Looks to me like npm is invoking batch scripts. Batch files are run in CMD.exe (even when invoked from PowerShell), which doesn't recognize / as a path separator. That's where the error message comes from.
Replace the forward slashes with \ (or \\ if they require escaping).

Related

Regex command line argument changing value between node and npm script

Working with node.js, I stumbled upon a behavior I cannot explain regarding command line arguments :
I've got a program which takes a regex to detect test files. This regex is passed via a command line argument :
node index.js --require src/**/*.js
When I do that, I obtain what I imagined. Let's say for the example I got the following files detected in my src folder (I log with a simple console.log(process.argv)) :
a.js
b.js
shared/c.js
shared/d.js
Now if I configure a npm script which launch the same command :
"test": "node index.js --require src/**/*.js
and launch it :
npm test
The result is :
a.js
b.js
Can someone explain to me why this is happening 😅 ? Thanks
I created a mini repo to reproduce for those interested (I run node 16.19.0)
you need to execute the command using bash to make use of its filename wildcard extensions.
"test": "bash -c 'node index.js --require src/**/*.js'"
npm uses /bin/sh by default to execute your scripts. Unlike bash or zsh (which you are probably using on the command line), sh does not understand **.
You can change the shell used by npm with:
npm config set script-shell bash

Hugo can not find created files by node when using concurrently

I have a node project which I build with concurrently with the following build pipe:
"scripts": {
"build": "concurrently -g npm:build:*",
"build:generate-db": "ts-node ./converter/main.ts",
"build:tailwind": "npx tailwindcss -i ./src/input.css -o ./static/css/build.css --minify",
"build:hugo": "hugo --minify",
},
build: Call's all commands with prefix build in synchron order.
build:generate-db: Create .md files for hugo application from a database.
build:tailwind: Generates tailwind file and puts it in correct folder
build:hugo: Creates hugo website with .md files and tailwind file.
When I run the script hugo is not finding the .md files. When I run the script a second time hugo finds the .md files and create the website correct.
What I tried:
First I thought the problem is the time the file write requires (so hugo is trying to find the files before they got written). This is not the case: Even when I sleep 10 seconds after build:generate-db hugo is not able to find the files as well.
When I run build:generate-db and than build:hugo it's working.
The tailwind file is created correctly. (it's also file write so why is this one working?)
When you run the following config it's working:
"build": "concurrently -g npm:build:* & hugo --minify",
"build:generate-db": "npm run converter",
"build:tailwind": "npx tailwindcss -i ./src/input.css -o ./static/css/build.css --minify",
The Converter writes like this:
writeFileSync(`${resultPath}/${data[titleKey]}.md`, JSON.stringify(resultDto, null, 2))
How can I fix this problem?

How to bundle a nodejs server application and prepare it for distribution?

First of all, I'm not after a technique to package my application into a single executable.
I'm curious to find out what is the approach to create a copy of the app within the current project that is ready to be moved to server-enabled location.
Right now my server app is a git repo and it has all the usual files in there, together with the source folder:
./src/server/index.js
Do we simply copy everything that is in the ./src/server folder to ./dist/ then also copy the package.json into ./dist?
Then we copy the contents of the ./dist folder to a location that will be able to serve the application, like /www/app2/ and inside that location, we make sure that we have NODE_ENV=production in the environment and run npm install to pull the production dependencies?
But then, our package.json file would still have the development related scripts and other things we don't need in production?
What is a best-practices way to deploy a NodeJs app?
--- UPDATE ---
This is what I have prototyped so far and it is working:
"scripts": {
"clean:dist": "./node_modules/.bin/rimraf dist",
"prep:dist": "./node_modules/.bin/mkdirp ./dist",
"copy:server": "./node_modules/.bin/ycopy ./src/server/ ./dist/ -r '^((?!tests$).)*$' -i",
"copy:package": "./node_modules/.bin/copyfiles package-production.json ./dist/",
"build": "npm run clean:dist && npm run prep:dist && npm run copy:server",
"start:dev": "nodemon src/server/index.js",
"start:server": "node dist/server/index.js",
"prompt": "echo 'No prompt functionality available'",
"greet": "echo 'Welcome to my project.'"
},
So the idea is to selectively move bits from the dev/src folder to a production ready dist folder. The idea behind having a simple package.json file is that we will not be needing the dev dependencies in there also we will not be needing most of the dev scripts as well. So probably something like the following will be enough:
"scripts": {
"setup:server": "NODE_ENV='production' && npm install"
"start:server": "pm2 start index.js"
}
... or maybe we would like to have some csh/bash scripts inside ./dist/bin that will streamline the start process.
"scripts": {
"start:server": "./bin/launcher"
}
I can definitely see a need for a custom project tree structure existing within the the ./dist folder and totally different to the ./src structure.
I am not sure why the "development" contents of your package.json are a problem, so perhaps I am not getting the crux of your problem. However, for our environment we deploy all of our node apps (primarily microservices) with ansible. The deployment package is just a tarball (could be a zip file). The ansible package includes templates for a config.js file and a pm2 startup.json file that are both customized based on the environment of the target (staging/test vs production).
Let me know if you want a few more details if you are interested in this approach.

Why to use "rimraf dist" command in build script

What is the reason for running "rimraf dist" command in the build script in package.json file?
"scripts": {
"build": "rimraf dist ..."
},
The rimraf package which you will probably find in the devDependencies section of the package.json you have, is used to safely remove files and folders on all platforms (Unix and Windows).
When you have a build system, you want to also make sure you remove the output files before re-emitting the build output content (especially in case you have removed some files which are not needed anymore). You could go ahead and do:
"scripts": {
"clean": "rm ./dist/* -Recurse -Force"
}
But that will work on Windows only, and sometimes will also give you problems due to issues around the use of *. On Unix the command would be different. In order to make things better, rimraf does the removal for you so you can simply invoke it in your scripts/clean section:
"scripts": {
"clean": "rimraf dist"
}
This will ensure your package.json (your build system) to be cross-platform.
rimraf
A rm -rf util for nodejs
$ rimraf dist removes the dist file or folder.
I guess the build script puts stuff inside the dist directory and wants to remove the old stuff from the last time you build it.
To be sure that all old files are deleted from the folder before the script will compile the files.
What actually needs to be known is what the script rimraf dist is doing, and that's simple it's cleaning out the dist folder to give you a clean start on what is assumed to be a web app or TypeScript app that requires some level compilation.
But, it isn't limited to that alone. Rimraf is a package that allows you the power of rm -rf ./dist which is specific to Linux OS. As suggested in the above comment this command will give you problems on Windows, especially when there is a directory that isn't empty or the file path becomes too long (very common with nested npm dependencies). Rimraf will bypass those exceptions as if you're running on Linux and this becomes a very powerful tool.

After npm reads package.json, what runs Electron?

I'm just starting to learn about how JavaScript, HTML, and Electron all work, and I want to know what runs electron . in the "scripts" -> "start" of package.json, because I can't tell what does and that kind of wizardry makes me nervous.
According to the man pages for npm, what npm start does is that it reads the package.json, looks at the script under "scripts" -> "start" -> some_script, and then runs some_script. Sometimes, some_script is something like node foobar.js, which makes sense to me, since I can run that from the command line. NodeJS is executing foobar.js. However, in the case of the electron-api-demos, some_script is electron .
You can download and run electron-api-demos via
git clone https://github.com/electron/electron-api-demos
cd electron-api-demos/
npm install && npm start
In order to try to figure out what is running electron ., I've run it in the node shell, and I've tried running node main.js. I've even tried opening up the node shell and running
electron-api-demos#2.0.2 start $DIR/electron-api-demos
electron .
(which is exactly the output of npm start). None of them worked, because none of them started up the Electron application. At this point I'm very puzzled at how, exactly, the start script gets executed at all.
So I guess my question is: does there exist a command (that I can use on the command line) to start up this Electron application, without using npm? If not, what is npm calling to start up this Electron app?
I apologize if this question has been asked before, but I all the sources I found didn't seem to go into any further detail about what, exactly, is done when npm start is run and how it executes electron . . Thank you for your time!
Command line interfaces installed with npm are put in the node_modules/.bin/ directory. You can't just run them from the command line because that directory isn't in your PATH (unless you put it there, or you installed it globally).
So, if you want to run electron without npm start, you can run ./node_modules/.bin/electron .. Since this is a bit verbose, newer versions of npm provide the command npx to run things without the ./node_modules/.bin/ part, so npx electron . also works.
Since npm scripts often use the packages you've installed, they automatically add node_modules/.bin/ to the PATH before running your command. As a result, the start script can just reference electron directly.
npx can do some other cool things too – npm has a blog post about it.
When you run npm start , it by default run command corresponding "start" key of script property of package.json like
"script":{
"start": "ng serve",
"launch":"electron main.js" or "electron ." // main.js located in the same dir
"test": " ng test"
}
same when you run npm run launch it will trigger the command corresponding of the "launch" key of script property of package.json file. like run electron main.js command and your application will launched.
so if you want to run the your electron application directly like electron main.js then install the electron module globally using command npm install electron -g then simply run the electron main.js command and your application will start.

Categories