Skip to content

Instantly share code, notes, and snippets.

@addyosmani
Last active May 21, 2024 19:56
Show Gist options
  • Save addyosmani/9f10c555e32a8d06ddb0 to your computer and use it in GitHub Desktop.
Save addyosmani/9f10c555e32a8d06ddb0 to your computer and use it in GitHub Desktop.
npm run-scripts boilerplate
{
"name": "my-app",
"version": "1.0.0",
"description": "My test app",
"main": "src/js/index.js",
"scripts": {
"jshint:dist": "jshint src/js/*.js",
"jshint": "npm run jshint:dist",
"jscs": "jscs src/*.js",
"browserify": "browserify -s Validating -o ./dist/js/build.js ./lib/index.js",
"browsersync": "browser-sync start --server --files 'src/*'",
"uglify:dist": "uglify src/js/**/*.js > dist/js/script.min.js",
"uglify": "npm run uglify:dist",
"test": "mocha",
"clean:dist": "rm -rf dist",
"clean:tmp": "rm -rf tmp",
"clean": "npm run clean:dist && npm run clean:tmp",
"copy:dist": "cp src/*.{js,css,html} dist/",
"copy": "npm run copy:dist",
"sass:dist": "sass src/css/style.scss > dist/css/style.min.css",
"sass": "npm run sass:dist",
"htmlmin:dist": "htmlmin -cs dist/index.html tmp/index.html",
"imagemin": "imagemin src/images/* dist/images/* -p",
"build:html": "npm run htmlmin",
"build:js": "npm run jshint && npm run uglify",
"build:css": "npm run sass",
"build:images": "npm run imagemin",
"build": "npm run clean && npm run build:html && npm run build:js && npm run build:css && npm run build:imagemin",
"watch": "watch 'npm run build' ."
},
"dependencies": {
"jshint": "latest",
"imagemin": "latest",
"browser-sync": "latest",
"uglifyjs": "latest",
"watch": "latest",
"cssmin": "latest",
"jscs": "latest",
"uglify-js": "latest",
"browserify": "latest",
"expect.js": "latest",
"should": "latest",
"mocha": "latest",
"istanbul": "latest"
}
}
@misterbrownlee
Copy link

misterbrownlee commented Jan 6, 2017

I found copy src/*.txt dist was creating dist/src/robots.txt. I didn't find it clear how to make copy behave more like cp would in creating the output dist/robots.txt. The cpx module was a little less confusing, but it's still not ideal. For any heavy copying or resource shuffling I tend to write tasks/copy-stuff.js as an script file and just map "copy-foo" to "./tasks/copy-stuff.js" in my scripts block. Then I can create promise based tasks with whatever complexity I need. 👍

@felixdorner
Copy link

Sometimes you need to concat scripts within a folder in the right order. For me uglifyjs seems not to take care about the order of scripts. Did anyone find a solution on how to concat and uglify all scripts in a folder ordered by name? I refer to this line:

"uglify:dist": "uglify src/js/**/*.js > dist/js/script.min.js"

Cheers and thanks for sharing this gist!

@robsonsobral
Copy link

npm-run-all is great to run parallel or sequential scripts.

@jasonhulbert
Copy link

jasonhulbert commented Aug 15, 2017

This is nothing new or ground-breaking but worth pointing out here for others that find this.

Instead of running the entire build when a change occurs on any file, prefer to run only the script/task related to the changed file. Personally, I like chokidar-cli for this purpose.

In the command that you want chokidar to run on file change (passed via the -c argument) you can use grep to check for a pattern in the changed file path and respond accordingly.

...
"watch": "chokidar './src/**/*' -c 'if grep -q \".scss\" \"{path}\"; then npm run sass; elif grep -q \".html\" \"{path}\"; then npm run html; fi;'",
"sass": "node-sass ./src/scss/main.scss -o ./dist/css/",
"html": "cpx './src/**/*.html' ./dist"
...

In the above example, if the file path contains .scss the sass script runs. If the path contains .html the html script runs.

Furthermore, you can combine this with npm script arguments to pass the file path along to the given script. For example...

...
"watch": "chokidar './src/**/*' -c 'if grep -q \".scss\" \"{path}\"; then npm run sass; elif grep -q \".html\" \"{path}\"; then npm run html -- \"{path}\" ./dist; fi;'",
"sass": "node-sass ./src/scss/main.scss -o ./dist/css/",
"html": "cpx"
...

So, in this example we're passing the {path} variable provided by chokidar to the html script so only the single, changed file is processed. Benefits are speed and fewer browser reloads when using lite-server or browser-sync. And it's freakin' sweet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment