How can I write multiline scripts in npm scripts?

JavascriptNpm

Javascript Problem Overview


My package.json looks like the following:

{
  "name": "project",
  "version": "1.0.0",
  "description": "",
  "main": "server.js",
  "scripts": {
    "lint": "./node_modules/eslint/bin/eslint.js --format \"./node_modules/eslint-friendly-formatter/index.js\" .",
    "build:server": "./node_modules/babel-cli/bin/babel.js . -d dist/server --ignore node_modules,dist,client,public,webpack*"
  }
}

As you can see, the lint and build:server command are hard to read, so I want to break them into multiple lines.

I've tried to use \, but it throws errors like:

npm ERR! Failed to parse json
npm ERR! Unexpected token ' ' at 11:80
npm ERR! :server": "./node_modules/babel-cli/bin/babel.js . -d dist/server \
npm ERR!                                                                   ^

How can I do this?

Only to write another bash file like build.sh and use it in npm scripts like ./build.sh server ?

Javascript Solutions


Solution 1 - Javascript

You can chain independent tasks.

Here is an example:

"scripts": {
	"lint-jshint": "jshint --verbose --show-non-errors ./src/main/js",
	"lint-eslint": "eslint ./src/main/js ./src/test/js",
	"lint-csslint": "csslint ./src/main/js",

	"lint": "npm run -s lint-jshint & npm run -s lint-eslint & npm run -s lint-csslint",

	"pretest": "rimraf ./build/reports/tests && mkdirp ./build/reports/tests && npm run -s lint",
	"test": "karma start ./src/test/resources/conf/karma.conf.js",
	...

Here is a nice blog which I used at that time: https://www.keithcirkel.co.uk/how-to-use-npm-as-a-build-tool/

Solution 2 - Javascript

You can't do that.

The following code is in read-json.js which is in package node_modules/npm/node_modules/read-package-json which is used in run-script.js to execute $ npm run-script ~~ or $ npm run ~~ which is its alias.

function scriptpath (file, data, cb) {
  if (!data.scripts) return cb(null, data)
  var k = Object.keys(data.scripts)
  k.forEach(scriptpath_, data.scripts)
  cb(null, data)
}

function scriptpath_ (key) {
  var s = this[key]
  // This is never allowed, and only causes problems
  if (typeof s !== 'string') return delete this[key]

  var spre = /^(\.[\/\\])?node_modules[\/\\].bin[\\\/]/
  if (s.match(spre)) {
    this[key] = this[key].replace(spre, '')
  }
}

The key in scriptpath_ is like "build:server" in your code.

The this[key] is like "./node_modules/babel-cli/bin/babel.js . -d dist/server --ignore node_modules,dist,client,public,webpack*" in your code.

So, if you write the code which is not string type, in other words, if you don't write the string text in package.json, it will be an error unless you contribute to the package npm/read-package-json.

Solution 3 - Javascript

Another common alternative is to write an npm command that references a local bash script (where you have more power to do what you want).

i.e.

# package.json
{
  "name": "project",
  "version": "1.0.0",
  "description": "",
  "main": "server.js",
  "scripts": {
    "lint": "./node_modules/eslint/bin/eslint.js --format \"./node_modules/eslint-friendly-formatter/index.js\" .",
    "build:server": "./build-server.sh"
  }
}
# build-server.sh
#!/bin/bash

./node_modules/babel-cli/bin/babel.js . \
  -d dist/server \
  --ignore \
    node_modules,\
    dist,\
    client,\
    public,\
    webpack*

NOTE: make sure you give yourself permission to run the file; otherwise you'll run into permission issues

sudo chmod 755 'build-server.sh'

See: https://stackoverflow.com/questions/12276507/run-script-on-mac-prompt-permission-denied

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser2331095View Question on Stackoverflow
Solution 1 - JavascriptasaView Answer on Stackoverflow
Solution 2 - JavascripthaͣrͬukaͣreͤrͬuView Answer on Stackoverflow
Solution 3 - JavascriptFrostyDogView Answer on Stackoverflow