npm package.json: How to wrap long single function scripts? - npm

I have created an npm package script for npx depcheck and one of its parameters, --ignore, its value is getting very long and I expect will get longer.
"audit:depcheck": "npx depcheck --specials=bin --ignore-dirs=dist,node_modules --ignores=tslint,gts,ts-node,ts-node-dev,typescript,mocha,winston,passport-springcm,passport-box,passport-dropbox-oauth2,passport-google-oauth20,passport-microsoft,mocha,nyc",
Tried: I have tried just simply breaking the very long script into new lines but this approach is not JSON compliant.
Goal: Do the same thing, but readable within 110 character width editor.

You can write a shell script, like (do not copy-paste it exactly, just to get the idea):
#!/usr/bin/env bash
npx depcheck --specials=bin --ignore-dirs=dist,node_modules --ignores=tslint,gts,ts-node,ts-node-dev,typescript,mocha,winston,passport-springcm,passport-box,passport-dropbox-oauth2,passport-google-oauth20,passport-microsoft,mocha,nyc
Name it something descriptive, for example npx_depcheck.sh or something else you want. Then call the shell script from package.json:
"audit:depcheck": "./npx_depcheck.sh",
Note: make sure your script can run: chmod u+x ./npx_depcheck.sh
Edit: as #RobC wrote, this solution expects that the system has a shell. The point is, you can attach any kind of scripts, just keep in mind that different environments have different runtimes and tools (a Node.js script makes sense, since the environment where you want to run your application most likely has Node.JS installed).

Related

Sanity not starting anymore, even though I'm in the right file

I'm making sure to type in sanity start in the right file pathway (for me its the Website folder). Its been working for me fine the past week and up till today, but not anymore. I'm worried I've messed with my Sanity files somehow, its my first time trying to use a backend so its possible I've done something I shouldn't have (I was having confusions around sanity client last night, and that my current sanity version didn't support my current react version). I think I remember trying to upgrade sanity through the terminal, but otherwise I don't remember making any other changes. I'm currently having a big issue trying to fetch data from the backend, so that's been a whole thing too.
This is the whole message I'm getting in the command prompt:
#sanity/core not installed in current project
Project-specific commands not available until you run `sanity install`
Error: Command "start" is not available outside of a Sanity project context.
Run the command again within a Sanity project directory, where "#sanity/core"
is installed as a dependency.
at _.runCommand (C:/Users/kiras/AppData/Roaming/npm/node_modules/#sanity/cli/bin/sanity-cli.js:3608:1340)
at t.exports (C:/Users/kiras/AppData/Roaming/npm/node_modules/#sanity/cli/bin/sanity-cli.js:1980:2422)
This is my first comment so I apologize if I'm not following some standard that StackOverFlow-culture has.
I got the same error as you, as shown below.
Error: Command "start" is not available outside of a Sanity project context.
Run the command again within a Sanity project directory, where "sanity"
is installed as a dependency.
at CommandRunner.runCommand (~/.nvm/versions/node/v18.12.1/lib/node_modules/#sanity/cli/lib/_chunks/cli-3984b311.js:17742:33333)
at Object.runCli (~/.nvm/versions/node/v18.12.1/lib/node_modules/#sanity/cli/lib/_chunks/cli-3984b311.js:17745:2460)
Yesterday everything was fine but today, Sanity was not working. I was in the right file and directory, and my JSON package was formatted properly as well. I tried installing and deleting many things but nothing worked. I ran this command in the studio directory:
sanity install
After that prompt, I got the following:
The `#sanity/core` module is not installed in current project
Project-specific commands not available until you run `npm install`
? Package manager to use for installing dependencies? npm
Then... I got a ton of "npm WARN deprecated" warnings but then I tried:
sanity start
and it worked? I hope this helps, goodluck!
If this doesn't work, make sure you have the following:
Scripts are Correct in studio/package.JSON
"scripts": {
"start": "sanity start",
"build": "sanity build"
},
If you accidentally deleted some JSON file, you can use:
npm i
to get it back, I made that mistake but make sure you're in the proper directory (web or studio).
Apologies for the long response, but this should work, a lot of the responces gave the same repetitive answer ("cd into sanity folder by writing cd sanity and then sanity start") and it frustrated me seeing the same thing 715,143,763 times lol
Good luck!

How to get the version of a remote npm package using a bin script

I'm trying to set up an npx script to create a template project.
In package.json I have:
"bin": {
"init": "bin/init"
}
In the init script I'm using tag='v'$(npm pkg get version | tr -d '"') to get the version of the package. I then use git clone --depth 1 --branch $tag https://github.com/matriarx/typescript.git to clone that specific repository for that specific tag.
When I do yarn link and try use it locally, from within that specific project, it works because it's able to correctly pick up the package.json version. So the above only works if it's run inside an existing project. However that's not what I want to do.
I want to enable someone to run it even if they have nothing locally, by simply doing npx #matriarx/typescript init and it should create the new project by cloning it. More than that I want them to be able to clone any specific version by using npx #matriarx/typescript#0.0.1 init in order to clone a specific version.
However it seems that anything I try is only able to get the version from a local package.json that already exists.
I could just clone the current existing repository without specifying any tag, but that would defeat the point of having releases, then it would just clone any current code completely disregarding the release. So it has to clone the tagged release.
How can I get the remote package version stored on npm from the bin script without having anything locally before hand?
Alternatively is there a better way to do what I'm trying to do?
EDIT: I ended up just hardcoding the version in the script, which works but it sucks because it's tedious to have to update it every time I bump the version. Though for now I still don't know a better way to do it.
After some more time messing around I figured out there is a standard way of doing it, at least since npm 7.
If you have a project like example then you can create a completely separate project called create-example with a bin script.
When you use npm init example, npm will automatically search for a package prefixed with "create-" and execute its main bin script. So when running npm init example it will search for that create-example package and execute the bin script, which will install the example package.
This is how most of the bigger packages like react and next do it.
This approach comes with some disadvantages that I really don't like, for example it will show the incorrect dependencies on npm and it will cause you to have to maintain multiple projects and semvers on different projects. However it will also allow you to create a clean separation between the actual project and the installation of that project.
For some projects it might also make a lot more sense. For example if you have a project that doesn't have a package.json at all and you want to create a setup for it, it wouldn't make sense to create an npm package inside that project just for that. Instead you can create a separate "create-project" package just to set it up and keep npm out of the actual project. In other words it gives you a neat way to create bin scripts for a completely separate project that doesn't have anything to do with npm.
You could also just have created a normal shell script and execute it using curl but I guess npm just gives you another way to do it.
You still have to hardcode the version in that "create-project" package, I still have not seen a way to automatically determine the version from a remote package. The only way I've managed to do that is to completely download the package, get the version, then delete it, but that would be terrible for people with a slower internet connection or limited data.

Can I write an npm run script to automate an ftp load to my server?

In VSCode I'm using ftp-simple to upload a directory of static files from a Svelte site.
I would like to automate this, presumably using npm, so that when I run npm run build it also uploads the build folder to the specified ftp.
What can I use for this? ftp-deploy seems likely, but I'm not sure how to configure package.json etc.
Any help would be appreciated.
The documentation for npm scripts explains. Briefly, though:
In package.json, find (or create) the scripts property. Find or add a build property to that. The value should be the command required to upload. That can be a script that you write (using ftp-deploy or something else) or it can be a CLI tool that is installed as a dev dependency or a regular command or set of commands available to your shell.
So you might end up with something like this (but it probably won't be this exactly):
{
"scripts": {
"build": "myAwesomeFtpDeployScript.js"
}
}

How to provide usage information for npm scripts

Is there an easy way to provide usage information for npm scripts?
Ideally, when I run npm run, I would get output like this (note the description at bottom of each task):
Lifecycle scripts included in product-discovery-service:
start
node server.js
available via `npm run-script`:
watch
run-p watch:build watch:run
Run in development mode and rebuild/restart when changes are made
watch:build
npm run build:dev -- --watch
Probably don't need this (would be nice to be able to omit tasks like this)
watch:run
nodemon --watch build/ --inspect
Probably don't need this (would be nice to be able to omit tasks like this)
prewatch:run
wait-on --log build/server.js
Probably don't need this (would be nice to be able to omit tasks like this)
build
babel server.js --out-dir build/
Build the project
prebuild
rimraf build/
Probably don't need this (would be nice to be able to omit tasks like this)
build:dev
npm run build -- --source-maps
Probably don't need this (would be nice to be able to omit tasks like this)
It looks like npm doesn't support this, but maybe there's a third-party with a solution? I found npm-scripts-help, but it feels clunky.
Short Answer:
Yes you're correct, npm does not provide a built-in feature to include descriptions when running npm run. So, any solution you choose will have some level of "feels clunky" associated with it.
As you've mentioned
npm-scripts-help is a package which can achieve this. I'm not aware of other similar third-party solutions.
Alternative custom solution:
The following steps describe how to write a simple custom Nodejs utility script (without using another third-party package dependency). This script can then be invoked via npm-scripts.
Create a simple Nodejs utility script as follows. Lets name the file usage.js.
usage.js
const usage = `
Lifecycle scripts included in ${process.env.npm_package_name}:
start
node server.js
available via \`npm run-script\`:
watch
run-p watch:build watch:run
Run in development mode and rebuild/restart when changes are made
watch:build
npm run build:dev -- --watch
Probably don't need this (would be nice to be able to omit tasks like this)
watch:run
nodemon --watch build/ --inspect
...`
console.log('%s', usage);
Save usage.js in your projects root directory at the same level where package.json is stored.
Add the following usage script to the scripts section of your package.json:
...
"scripts": {
"usage": "node usage",
...
},
...
Run npm run usage to print the usage info to the console. A script name (i.e. usage) has to be provided with npm run. Unfortunately your ideal of just running npm run will only log npm's simple log - which doesn't include descriptions.
Notes:
On line two in usage.js we reference the package name variable via the part which reads: ${process.env.npm_package_name}
If you change the location of where usage.json is stored in your project directory you'll need to redifine the path to it in your npm-script as required. For example, if you choose to store it in a folder named scripts, which resides in your projects root directory, then your usage script should be defined as follows:
...
"scripts": {
"usage": "node scripts/usage",
...
},
...
Adding ANSI/VT100 Control sequences
You can utilize ANSI/VT100 Control sequences in usage.js to add colors and formatting to the usage log.
For example, in the following usage.js, the codes:
\x1b[1m
\x1b[0m
...are utilized to embolden code snippets and reset the formatting back to default respectively.
Tip: If cross-platform is a requirement I suggest using the ANSI 8/16 Colors (listed at the previous link) only. The formatting codes for bold (\x1b[1m) do not work in Windows cmd.exe using terminals such as Windows Command Prompt or PowerShell.
usage.js (with formatting)
const BOLD = '\x1b[1m';
const NORM = '\x1b[0m';
const formattedUsage = `
Lifecycle scripts included in ${BOLD}${process.env.npm_package_name}:${NORM}
${BOLD}start
node server.js${NORM}
available via ${BOLD}npm run-script${NORM}
${BOLD}watch
run-p watch:build watch:run${NORM}
Run in development mode and rebuild/restart when changes are made
${BOLD}watch:build
npm run build:dev -- --watch${NORM}
...`
console.log('%s', formattedUsage);
You could also consider combining ES6 Template Literals with process.env and package.json vars to reference the values of each npm-script. For example:
`${BOLD}${process.env.npm_package_scripts_watch}:${NORM}`

Automate Sass execution thru terminal (os x) via script

I started using Haml/Sass thru Rubygems recently, and I'm really liking it (although that doesn't have much to do with my question)...
I would like to create a simple script I can throw in the root directory of each of my projects that will launch terminal, cd to my CSS folder, and run sass. so essentially a script that:
cd ~/path_to_here/css/
sass --watch style.scss:style.css --style compact
I'm not really sure the best way to go about this, anything involving the command line is always slightly out of my comfort zone. Many thanks.
This script won't open the Terminal for you; but it will give you a shortcut to do the repetitive task of changing to the project directory and calling the compass watch command. (I highly recommend you to use Compass which is a SASS compilation of Tools to make your life easier.)
Put this inside your ~/.profile file and restart your terminal:
alias watch=compass_watch_project
function compass_watch_project() {
cd ~/Dev/ruby/$1;
compass watch
}
Remember to change the ~/Dev/ruby/ to your directory path.
After this you can easily do a watch myProject.
Hope it helps.
Consider using Compass for managing the building of your Sass files: It has a script for watching changes in all your project files and setting up all the output parameters.
You can create a simple text file with the extension .command which will make it a double-clickable script in OSX:
#!/bin/bash
compass watch
You could write a applescript that would launch terminal, and call a shell script.
Applescript
tell application "Terminal"
do script "pushd /blash/sassstup.sh"
end tell
shell script:
cd cssfolder
/bin/sass --watch style.scss:style.css --style compact