This is a detailed process template for transitioning grunt tasks into npm scripts based on lessons learned from the MMV project. The exact steps might vary between projects.
Purpose: removing Grunt from the build pipeline. The basic steps follow established patterns, the 'fix' and 'install' scripts are new. Feel free to discuss and propose alternatives.
Parent task tracking the individual projects: T246321: [EPIC] Transition Gruntfile.js tasks to NPM scripts in some projects
Basic steps
- grunt eslint -> npm -s lint:scripts
- create .eslintignore (sample)
- grunt stylelint -> npm -s lint:styles
- create .stylelintignore (sample)
- grunt banana -> npm -s lint:i18n
- grunt svgmin -> npm -s run svgmin
- create .svgminrc.json from Gruntfile.js (sample)
- npm run build : run scripts test, minify, doc (as applicable)
- npm test : run lint
- npm run lint : run all lint steps in chain
- npm run lint:fix : run all lint steps in chain with --fix argument to fix trivial style errors:
- npm -s run lint:scripts -- --fix, etc. Note the extra -- that separates the task argument.
- npm minify : run svgmin script
Developer productivity
Optional scripts to help set up the dev environment.
- install:global : install the necessary node_modules globally
- install:link : symlink the node_modules that must be present locally for eslint to work
- Add DEVELOPERS.md (sample)
Cleanup devDependencies
- Uninstall grunt and its plugins, except the MediaWiki specific grunt-banana-checker
- Update and commit package-lock.json for CI
Uninstall grunt:
npm -s un grunt npm -s un grunt-eslint npm -s un grunt-stylelint npm -s un grunt-svgmin
Update and commit package-lock.json:
npm install [--package-lock-only]
Before commit test:
npm -s ci npm -s test
Sample package.json
{ "private": true, "scripts": { "build": "npm -s test && npm -s run doc", "test": "npm -s run lint", "lint": "npm -s run lint:scripts && npm -s run lint:styles && npm -s run lint:i18n", "lint:fix": "npm -s run lint:scripts -- --fix && npm -s run lint:styles -- --fix", "lint:scripts": "eslint --cache --max-warnings 0 **/*.{js,json}", "lint:styles" : "stylelint resources/**/*.{less,css}", "lint:i18n": "banana-checker --requireLowerCase=0 i18n/", "svgmin" : "npx svgo --config=.svgminrc.json -q -r -f resources/", "doc" : "jsdoc", "install:svgmin" : "npm i -s -g svgo", "install:doc" : "npm i -s -g jsdoc", "install:global" : "npm i --link --no-save eslint-plugin-json@1.4.0 eslint-plugin-no-jquery eslint-plugin-qunit stylelint", "uninstall:global": "npm un -s -g eslint eslint-config-wikimedia eslint-plugin-json eslint-plugin-no-jquery eslint-plugin-qunit grunt-banana-checker stylelint stylelint-config-wikimedia svgo" }, "devDependencies": { "eslint": "6.8.0", "eslint-config-wikimedia": "0.15.0", "grunt-banana-checker": "0.8.1", "stylelint-config-wikimedia": "0.9.0" } }
Note: eslint-config-wikimedia depends on
- eslint-plugin-json@1.4.0, it hasn't been updated to v2.1.0
- eslint-plugin-mediawiki@0.1.0, it hasn't been updated to v0.2.1
Previous related tasks
T204176: Decide how to configure ESLint rules and ignores
T204260: Consolidate svgmin config and svg / grunt-svgmin checker
T179195: Replace use of .eslintignore with ignore in Gruntfile.js in all repos, for consistency
T56218: Jenkins: Use node-jscs as checkstyle for javascript coding style