Skip to content

Commit

Permalink
Add enforcement of .js extensions for require() (#1586)
Browse files Browse the repository at this point in the history
DEFRA/water-abstraction-team#115

Recently, we [overhauled our project linting](#1476). We moved to ESLint v9 and its new flat file config, switched to Prettier to handle our 'style' conventions, and replaced StandardJS with Neostandard.

On that last point, the one rule we could not migrate at the time was the enforcement of `.js` extensions when requiring modules. We know Node.js will handle this for us and that the extension is not required. Eventually, we intend to migrate to ESM modules, and from previous attempts, having the `.js` in place reduces the amount of work this requires.

We are now happy to report that in v0.12.0 [Neostandard](https://github.com/neostandard/neostandard) has adopted [eslint-plugin-import-x](https://github.com/un-ts/eslint-plugin-import-x) so we can add the rule back in, which is handy, as we've spotted new instances of folks forgetting to do this!
  • Loading branch information
Cruikshanks authored Dec 30, 2024
1 parent c45bd11 commit 73fa3db
Show file tree
Hide file tree
Showing 11 changed files with 531 additions and 180 deletions.
5 changes: 4 additions & 1 deletion .labrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ module.exports = {
// whilst avoiding having to pass it around
'GlobalNotifier',
// HapiServerMethods is added by us in a server plugin to allow us to access server methods globally.
'HapiServerMethods'
'HapiServerMethods',
// Caused by eslint-plugin-import-x which is a dependence of Neostandard we rely on to ensure the team adds the .js
// extension to files when requiring them
'__rewriteRelativeImportExtension'
].join(',')
}
2 changes: 1 addition & 1 deletion app/controllers/notifications-setup.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

const ReturnsPeriodService = require('../services/notifications/setup/returns-period.service.js')
const SubmitReturnsPeriodService = require('../services/notifications/setup/submit-returns-period.service.js')
const InitiateSessionService = require('../services/notifications/setup/initiate-session.service')
const InitiateSessionService = require('../services/notifications/setup/initiate-session.service.js')

/**
* Controller for /notifications/setup endpoints
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
* @module ReturnsPeriodPresenter
*/

const { determineUpcomingReturnPeriods } = require('../../../lib/return-periods.lib')
const { formatLongDate } = require('../../base.presenter')
const { determineUpcomingReturnPeriods } = require('../../../lib/return-periods.lib.js')
const { formatLongDate } = require('../../base.presenter.js')

/**
* Formats data for the `/notifications/setup/returns-period` page
Expand Down
6 changes: 3 additions & 3 deletions app/services/jobs/import/process-import-licence.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
* @module ProcessImportLicence
*/

const DetermineLicenceEndDateChangedService = require('./determine-licence-end-date-changed.service')
const ProcessBillingFlagService = require('../../licences/supplementary/process-billing-flag.service')
const GenerateReturnLogsService = require('./generate-return-logs.service')
const DetermineLicenceEndDateChangedService = require('./determine-licence-end-date-changed.service.js')
const ProcessBillingFlagService = require('../../licences/supplementary/process-billing-flag.service.js')
const GenerateReturnLogsService = require('./generate-return-logs.service.js')

/**
* Process licence for the licences imported from NALD
Expand Down
2 changes: 1 addition & 1 deletion app/services/notifications/setup/returns-period.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*/

const NotificationsPresenter = require('../../../presenters/notifications/setup/returns-period.presenter.js')
const SessionModel = require('../../../models/session.model')
const SessionModel = require('../../../models/session.model.js')

/**
* Formats data for the `/notifications/setup/returns-period` page
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

const NotificationsPresenter = require('../../../presenters/notifications/setup/returns-period.presenter.js')
const ReturnsPeriodValidator = require('../../../validators/notifications/setup/returns-periods.validator.js')
const SessionModel = require('../../../models/session.model')
const SessionModel = require('../../../models/session.model.js')

/**
* Formats data for the `/notifications/setup/returns-period` page
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*/

const Joi = require('joi')
const { returnPeriodDates } = require('../../../lib/static-lookups.lib')
const { returnPeriodDates } = require('../../../lib/static-lookups.lib.js')

const errorMessage = 'Select the returns periods for the invitations'

Expand Down
16 changes: 14 additions & 2 deletions eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

const jsdocPlugin = require('eslint-plugin-jsdoc')
const eslintPluginPrettierRecommended = require('eslint-plugin-prettier/recommended')
const neostandard = require('neostandard')
const globals = require('globals')
const neostandard = require('neostandard')

module.exports = [
// Start with neostandard ESLint rules. neostandard is the successor to StandardJS (which has stalled due to a
Expand Down Expand Up @@ -36,11 +36,14 @@ module.exports = [
ignores: ['docs/**/*'],
plugins: {
// https://github.com/gajus/eslint-plugin-jsdoc
jsdoc: jsdocPlugin
jsdoc: jsdocPlugin,
import: neostandard.plugins['import-x']
},
rules: {
// Enforce braces around the function body of arrow functions
'arrow-body-style': ['error', 'always'],
// Enforce .js extension when requiring files
'import/extensions': ['error', 'always'],
// Enforce 'use strict' declarations in all modules
strict: ['error', 'global'],
'jsdoc/check-alignment': 'error',
Expand Down Expand Up @@ -71,6 +74,15 @@ module.exports = [
'jsdoc/require-jsdoc': 'off'
}
},
// This section adds another override to the configuration object above. It tells the import/extensions plugin to
// ignore this file. The plugin flags `eslint-plugin-prettier/recommended` as a violation, even though it is not and
// adding `.js` causes it to break
{
files: ['eslint.config.js'],
rules: {
'import/extensions': 'off'
}
},
// Adds prettier ESLint rules. It automatically sets up eslint-config-prettier, which turns off any rules declared
// above that conflict with prettier. That shouldn't be any, as we tell neostandard not to include any style rules
// and the ones we've declared we've done as per eslint-config-prettier docs on special rules. As recommended by
Expand Down
Loading

0 comments on commit 73fa3db

Please sign in to comment.