Skip to content

Rework JS linting & support fixes#106

Open
agibson-godaddy wants to merge 66 commits intomasterfrom
mwc-19073
Open

Rework JS linting & support fixes#106
agibson-godaddy wants to merge 66 commits intomasterfrom
mwc-19073

Conversation

@agibson-godaddy
Copy link
Contributor

@agibson-godaddy agibson-godaddy commented Jan 21, 2026

Issue: https://godaddy-corp.atlassian.net/browse/MWC-19073

Summary

  • Removes gulp-eslint in favour of eslint directly
  • Includes an upgrade to eslint 9+
  • Reworks linting process
  • Old config got nuked because it wasn't compatible with latest eslint version. Current one committed pulls in most of the rules from the old config
  • Reworked config override logic slightly to match what we did in SCSS linting: new config option with null default
  • Added support for auto fixing linting errors via --fix flag (e.g. npx sake lint:js --fix)

Flags:

  • Use --fix flag to auto fix errors (note: some errors cannot be fixed automatically)
  • Use --show-files flag just to list out files that have errors, without listing the errors themselves (useful for debugging which files are being linted to sanity check you're not linting vendor files)
  • Use --fail-on-lint-errors to halt the entire process if errors are encountered (i.e. if you're running npx sake deploy and want to completely halt if there are lint errors)

Config Options

There are two new config options:

tasks.lint.eslint.configFile -- to override the entire config file; value is a path relative to root plugin directory
tasks.lint.eslint.excludeFiles -- array of files to exclude from linting. handy if you don't want to override the whole config but want to exclude some files

Example:

Exclude bundled jquery timepicker from linting:

module.exports = {
	framework: 'v5',
	autoload: true,
	tasks: {
		lint: {
			eslint: {
				excludeFiles: [
					'assets/js/jquery-timepicker/jquery.timepicker.js'
				]
			}
		}
	},
	paths: {
		exclude: [
			'CLAUDE.md'
		]
	}
}

QA

  1. Use a plugin that has JavaScript files, such as woocommerce-memberships
  2. Use this version of sake
  3. From the plugin directory, run sake lint:js --show-files
    • It outputs a list of files with errors, but not the errors themselves
  4. Run sake lint:js
    • You get lint errors outputted
  5. Run sake lint:js --fix
    • Errors are fixed (it probably won't fix all of them -- eslint won't fix certain errors)
  6. Run git diff to inspect changes
    • Changes look reasonable, as per defined rules
  7. Run sake decaffinate
    • Success without errors
    • You end up with converted js files
    • JS files retain same directory structure as coffee files

After merge

  • Document eslint config options

agibson-godaddy and others added 4 commits August 22, 2025 12:48
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Base automatically changed from mwc-17961 to master January 30, 2026 12:40
An error occurred while trying to automatically change base from mwc-17961 to master January 30, 2026 12:40
@agibson-godaddy agibson-godaddy self-assigned this Feb 5, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR modernizes the JavaScript linting infrastructure by replacing gulp-eslint with the native eslint library and upgrading to ESLint v9. It introduces a shared runESLint function that supports auto-fixing, customizable error handling, and file filtering.

Changes:

  • Upgraded from ESLint v6 to v9 and removed the deprecated gulp-eslint dependency
  • Implemented a reusable runESLint function with support for --fix, --fail-on-lint-errors, and --show-files flags
  • Added new config options for overriding ESLint config files and excluding specific files from linting

Reviewed changes

Copilot reviewed 7 out of 8 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tasks/lint.js Introduces runESLint function and refactors lintJsTask to use native ESLint API with flag support
tasks/decaffeinate.js Updates decaffeination task to use shared runESLint function instead of gulp-eslint
package.json Upgrades eslint to v9.39.2, adds @eslint/js and eslint-plugin-jsdoc, removes gulp-eslint
lib/lintfiles/.eslintrc.js Replaces old config with new ESLint v9 flat config format including JSDoc rules
lib/lintfiles/.eslintrc Removes deprecated ESLint config file that extended @skyverge/eslint-config
lib/config.js Adds eslint.configFile and eslint.excludeFiles configuration options
helpers/arguments.js New helper module providing functions to check for command-line flags

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 11 to 16
files: ["**/*.js"],
plugins: {
js,
jsdoc,
},
extends: ["js/recommended"],
Copy link

Copilot AI Feb 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The extends property is not supported in ESLint v9's flat config format. You should spread the recommended config instead: ...js.configs.recommended, at the top level of the config object.

Suggested change
files: ["**/*.js"],
plugins: {
js,
jsdoc,
},
extends: ["js/recommended"],
...js.configs.recommended,
files: ["**/*.js"],
plugins: {
js,
jsdoc,
},

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Docs indicate it works fine: https://www.npmjs.com/package/@eslint/js

Their example is exactly what we're doing here.

Copy link
Contributor

@nikolas4175-godaddy nikolas4175-godaddy Feb 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@agibson-godaddy yeah ESLint v9 docs confirm this use of extends key: https://eslint.org/docs/latest/use/configure/combine-configs

That said, v9 also migrates to a flat eslint.config.js file by default with .eslintrc being deprecated and scheduled for complete removal in v10

Would it make sense for us to make that switch while we're migrating here, or should that be an additional step?
Ah sorry, I was thrown off by the naming, but I see that we're explicitly passing the new flat config when initializing, which also allows us to account for plugin overrides - nice work 👍

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@agibson-godaddy agibson-godaddy marked this pull request as ready for review February 5, 2026 13:49
Copy link
Contributor

@nikolas4175-godaddy nikolas4175-godaddy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving with one minor note below. Ran QA on Memberships and also confirmed configFile and excludeFiles work as expected 🚀

✅ QA

  • From the plugin directory, run sake lint:js --show-files
    • It outputs a list of files with errors, but not the errors themselves
  • Run sake lint:js
    • You get lint errors outputted
  • Run sake lint:js --fix
    • Errors are fixed
  • Run git diff to inspect changes
    • Changes look reasonable, as per defined rules
  • Run sake decaffeinate
    • Success without errors
    • You end up with converted js files
    • JS files retain same directory structure as coffee files

if (errorCount > 0 && failOnErrors) {
throw new Error(`${taskName} found ${errorCount} error(s) and ${warningCount} warning(s). Build halted due to failOnErrors setting.`);
} else if (errorCount > 0) {
log.info(`ℹ ${taskName} found ${errorCount} error(s) and ${warningCount} warning(s), but continuing build. Use --fail-on-lint-errors to halt on errors.`);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bit of an odd output here: https://share.zight.com/geuX9K5k

This line logs at the end of linting even if that's the only task being run. Could we move this to the build task after linting is done and check for errors there?

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants