We have within a package.json build script a copy command (no we cant quickly change that).
Is there any solution we can make this work multiplatform with the same syntax easily?
I looked in several npm copy packages, but they don't transpile from windows to unix paths.
We basically need something like:
"build": "doStuff && cp -r ../folder/ /dist/"
working for windows.
Any ideas?
For a cross-platform solution consider utilizing the shx package.
Firstly cd to your project directory and run the following command to install it:
npm i -D shx
Then redefine your build script in the scripts section of your package.json as follows:
"scripts": {
"build": "doStuff && shx cp -r ../folder/ ./dist/"
}
Related
I want to run my app.js using "dev" : "nodemon app.js"
and I have also added "node-sass": "node-sass public/sass/main.scss public/css/style.css -w"
My goal is to run live server using nodemon app.js only once.
And compile sass to css everytime I edit my sass file and press ctrl + S without restarting my server.
I have tried it by adding "dev": " nodemon app.js && node-sass public/sass/main.scss public/css/style.css -w" .This command is running server successfully but its not compiling my sass to css whenever im trying Ctrl + s on sass file.
Use both commands on seperate terminals.
Click the plus sign to open the terminal in the same directory or use git bash.
You can also make another script merging both commands in your package.json.
"scripts": {
"dev":"nodemon app.js",
"node-sass":"node-sass public/sass/main.scss public/css/style.css -w",
"dev:sass":"npm-run-all --parallel node-sass dev"
}
By executing dev:sass, you will run both commands in parallel (note the --parallel flag).
Note: You have to install the "npm-run-all" devDependency to make the script work.
I am new to npm run scripts can I do the following tasks using only npm run scripts? (i.e without any task runner like gulp and grunt)
concat js
scss to css watch
get notified about succesful js concatenation and scss to css conversion
and moving only html, css, js to deployment directory
Any help would be greatly appreciated!
I don't see why not? To give you a little context:
npm run scripts allow you to easily run: any custom script you create, or any script provided from within your node_modules directory. This is exactly what any task runner is providing you with: i.e. custom scripts to accomplish common development tasks, they have just premade these scripts whereas with npm run scripts you're creating them yourself. These npm scripts are created by adding them to the "scripts" field within your package.json file and can be executed by typing the following: npm run <script-name>.
How are we able to just run the binaries of locally installed packages?
Well, the binaries of locally install packages are made available to you courtesy of your PATH environment variable. This is extremely convenient and allows you to run said binaries simply by typing the the name of said package instead of having to point to: node_modules/.bin/<node_module>. Furthermore, to see which scripts are available to you issue a: npm run
Ok back to your question.. Yes you'll will just have to create custom scripts utilizing various libraries to accomplish said task.
For example, scss to css watch, you could create a script like so:
"scripts": {
"buildscss": "sass --watch app/sass:public/stylesheets"
},
Alternatively, you could use node-sass to handle this task:
npm install --save-dev node-sass
"scripts": {
"buildscss": "node-sass --output-style compressed -o dist/css src/scss"
}
To serve and automatically inject changes you can utilize browser-sync. Something like the following:
npm i -D browser-sync
"scripts": {
"serve": "browser-sync start --server --files 'dist/css/*.css, dist/js/*.js'"
}
Alternatively if you only want to move html, css, js to a deployment directory, <dist> in this case, you could do the following:
"scripts": {
"copy": "cp <html_dir> dist/ && cp <css_dir> dist/ && cp <js> dist/",
}
As for your question about notifications: your custom script would run other custom scripts and print to the console the outcome of said script. There is much more that you can do with npm run scripts, such as: linting, watching, combining scripts, etc.. For a great tutorial check out this link as I am just scratching the surface.
Hopefully that helps!
The npm publish
command creates a tarball (with src dir) and publish it to registry.
is there a way to exclude the src dir avoiding use of .npmignore ?
npm provides no other built-in feature to achieve that, so a custom solution is required.
If you really don't want to use .npmignore to keep the src directory out of your published package, then consider utilizing pre and post hooks in your npm scripts instead.
The pertinent hooks are:
prepublishOnly: Run BEFORE the package is prepared and packed, ONLY on npm publish ...
postpublish: Run AFTER the package is published.
For *nix platforms
Add a prepublishOnly script to the scripts section of your package.json that moves the src directory to another location outside of your project directory prior to publishing.
Also, add a postpublish script that moves the src directory back to the project directory when publishing has completed.
Run npm publish (as per normal) to publish your package.
For instance:
package.json
...
"scripts": {
"prepublishOnly": "mv src/ ../",
"postpublish": "mv ../src .",
...
},
...
Note: You'll need to ensure that no other src folder/directory exists at the path location you choose to temporarily move the src directory to via your prepublish script.
Cross platform:
For a cross-platform solution consider utilizing shx. This package includes a portable mv command. In which case, configure your prepublish and postpublish scripts something like the following instead:
package.json
...
"scripts": {
"prepublishOnly": "shx mv src/ ../",
"postpublish": "shx mv ../src .",
...
},
...
You can use the files property in your package.json to explicitly include the files you want to publish.
{
"files": [
"dist",
"index.js"
]
}
As #RobC answer, there is no other way then a custom solution for avoid using .npmignore.
Since I’m using the publish command in a Jenkins pipeline, a solution is to create a temporary .npmignore while the publish step directly in the Jenkinsfile:
echo "src/" >> .npmignore
echo "*.js" >> .npmignore
echo "*.json" >> .npmignore
echo "Jenkinsfile" >> .npmignore
curl --insecure -u ${USERPASS} 'https://my-repo/api/npm/auth' >> /home/jenkins/.npmrc
npm publish --registry https:// my-repo/api/npm/npm-local/
I developed a npm package ("node_commons") which is included in my other project like this:
package.json (other project)
"node-commons": "git+ssh://git#stash.custom.domain.net:7999/npm/libs/node_commons.git"
The node_commons package is written in ES6 but this version is not supported later, therefore I use a postinstall script to transpile it with babel.
package.json (node_commons)
"postinstall": "babel src -d src"
This works fine. When the package is included as dependency in my project, the files are transpiled.
My problem: When I develop the node_commons package I use npm install to install the internal dependencies. But then I do not want to transpile it. I only want to transpile, when the package is installed as dependency (e.g. in my other project). Is there a way to do this?
Something like this:
package.json (node_commons)
"postinstall-as-dependency": "babel src -d src"
Create .no-postinstall file in module root.
Mac & Linux: Add following to package.json: "postinstall": "if [ ! -e .no-postinstall ]; then babel src -d src; fi"
Windows: Add following to package.json: "postinstall": if exist .no-postinstall () else (babel src -d src)"
Cross Platform (more work):
You can create a node script (i.e. ./my-script.js) and using fs module, check existence of .no-postinstall and execute babel src -d src using child_process.exec() as described in official doc here. Add your script to package.json: "postinstall": node my-script.js
Please note that I use Mac, so I can't verify Windows version.
Explanation
if [ ! -e .no-postinstall ] checks non-existence (with negation operator !) of given file. If file does not exist, it executes your script. Since you add .no-postinstall file to your module root, script does not get executed when you install your internal modules. On the other hand, modules installing your module as a dependency do not have .no-postinstall file in their root and your script get executed.
.no-postinstall is not a special name, you can use whatever name you choose.
In my case, I had a postinstall script that I only wanted to run when the package was NOT installed as a dependency.
Here is the package.json script I used:
{
[...]
"scripts": {
"#comment_postinstall": "Behavior of the node-js subscript below: if '.git' doesn't exist under my-lib, it's installed as a dep, so do nothing -- else, return error-code 1, causing patch-package to run.",
"postinstall": "node -e \"let myLibAsDep = !require('fs').existsSync('.git'); if (!myLibAsDep) process.exit(1);\" || patch-package"
},
[...]
}
You can of course just reverse the if (!myLibAsDep) if you want your script to run only when installed as a dependency.
If I understand correctly, you want your package to run a postinstall script only if user install it as a dependency (npm install node-common)?
When your postinstall script runs, it has the npm_config_save_dev available to it, which is 'true' when users install the package with the --save-dev flag:
"postinstall": "! [ $npm_config_save_dev ] && echo \"Installed as a dependency\" || \"Installed as a dev dependency\""
I had the same issue, I had a postinstall script which I wanted to run only when the package is installed as a dependency.
At the top of my postinstall script I added:
if (!process.cwd().includes('node_modules')) {
return;
}
and then it only ran when the module existed under a node_modules dir.
This should do the trick:
if (process.env.INIT_CWD === process.cwd())
process.exit()
Works with npm and pnpm. Don't know about yarn
https://docs.npmjs.com/cli/v8/using-npm/scripts#best-practices
I created a package to solve this problem, inspired by the answer from #venryx.
https://github.com/douglasjunior/ignore-dependency-scripts
Usage
Replace this:
// package.json
"name": "my-library",
"scripts:" {
// "start", "test", "build", etc
"postinstall/preinstall/prepare/etc": "your && scripts && here"
},
With this:
// package.json
"name": "my-library",
"scripts:" {
// "start", "test", "build", etc
"postinstall/preinstall/prepare/etc": "npx --yes ignore-dependency-scripts \"your && scripts && here\""
},
Replace your && scripts && here by any post/pre install script that you want, like husky install, npx pod-install or both.
Now, when you run yarn install or npm install in ./my-library the your && scripts && here will run normally.
But, when you install my-library as a dependency (aka yarn add url/to/my-library.git) in another repository, the your && scripts && here will be ignored.
Background:
We are using yarn in this project and we don't want to write our package.json scripts with a mix of npm/yarn commands.
I have a root directory which contains a few subfolders.
Each holds a different service.
I want to create a script in the root folder that npm install each of the services, one by one.
Question:
Do you know what would be the yarn alternative to npm install <folder>?
I'm looking for something like this psuedo command: yarn <folder>
You could use --cwd there is a git issue about this :
yarn --cwd "your/path" script
You can also use cd :
cd "your/path" && yarn script
To run yarn install on every subdirectory you can do something like:
"scripts": {
...
"install:all": "for D in */; do yarn --cwd \"${D}\"; done"
}
where
install:all is just the name of the script, you can name it whatever you please
D Is the name of the directory at the current iteration
*/ Specifies where you want to look for subdirectories. directory/*/ will list all directories inside directory/ and directory/*/*/ will list all directories two levels in.
yarn -cwd install all dependencies in the given folder
You could also run several commands, for example:
for D in */; do echo \"Installing stuff on ${D}\" && yarn --cwd \"${D}\"; done
will print "Installing stuff on your_subfolder/" on every iteration.
To run multiple commands in a single subfolder:
cd your/path && yarn && yarn some-script