Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch from CommonJS to ES6 modules #9

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

Jozzey
Copy link
Contributor

@Jozzey Jozzey commented Oct 21, 2022

Currently, when one file references another in the project we use the following

const { InvoiceRebillingPresenter } = require('../presenters')
const InvoiceRebillingInitialiseService = require('./invoice_rebilling_initialise.service')
const InvoiceRebillingCopyService = require('./invoice_rebilling_copy.service')

This is known as CommonJS modules and up until the current LTS version of Node.js was the only type supported. In the meantime, the JavaScript language adopted ES6 modules as its standard. With native support for them now in Node.js v14, we have the option to switch to them.

By switching we are keeping the code up to date with modern practices. We have also confirmed ES6 modules resolve an issue we have sometimes had to work around (circular dependencies). Finally, they are a bit more performant than CommonJS ones.

So, this change updates the whole project to switch over (our testing found that everything has to go at once; we can't just do a file at a time).

Currently, when one file references another in the project we use the following

```javascript
const { InvoiceRebillingPresenter } = require('../presenters')
const InvoiceRebillingInitialiseService = require('./invoice_rebilling_initialise.service')
const InvoiceRebillingCopyService = require('./invoice_rebilling_copy.service')
```

This is known as *CommonJS* modules and up until the current LTS version of Node.js was the only type supported. In the meantime, the JavaScript language adopted *ES6* modules as its standard. With native support for them now in Node.js v14, we have the option to switch to them.

By switching we are keeping the code up to date with modern practices. We have also confirmed ES6 modules resolve an issue we have sometimes had to work around (circular dependencies). Finally, they are a bit more performant than CommonJS ones.

So, this change updates the whole project to switch over (our testing found that everything has to go at once; we can't just do a file at a time).
@Jozzey Jozzey added the do not merge Used for spikes and experiments label Oct 21, 2022
@Jozzey Jozzey self-assigned this Oct 21, 2022
@Cruikshanks
Copy link
Member

Myself and @Jozzey pulled this together based on what I learnt in SROC Charging Module API Switch from CommonJS to ES6 modules.

As with that attempt, we got the app running grand but were blocked by the test framework. We found it was Lab that stopped us and not Sinon.

Looking into solutions the only one (and we had to dig hard) was to use gulp to transpile the app code to CommonJS and then have Lab test the transpiled code.

It wasn't much better when we looked at alternates. Jest comes with a big warning that ESM modules are experimental. It also is doing the same thing as the Lab workaround, only using Babel to do the transpiling.

A comparison of test frameworks highlights AVA as the only one with Native ESM support. We'd be on our own trying to get it to work with tools like Sinon, and it'd mean a complete rewrite of our tests. As the report highlights, it is the new kid on the block.

So, our conclusion at this point is using ESM modules rather than CommonJS feels like we'd be on the fringe of things, which for a small team with a lot to do is just too much risk to carry at this time.

Cruikshanks added a commit that referenced this pull request Nov 23, 2022
In this change we're just getting on top of some basic things we've either ommitted when making changes or because we have made a concious decision about a way forward.

- Using kebab-case rather than snake_case for filenames
  - Though there is no standard or rule, it's our opinion that most javascript projects use kebab-case
- Ensuring all require statements include the extension
  - We know it's not needed. But as [Switch from CommonJS to ES6 modules](#9) shows, we really want to switch to imports one day and this will set us up for that
- Including module JSDoc comments at the top of each file
  - We use JSDoc to comment our methods. I also reccommends CommonJS modules should include a standalone comment. When you do, VSCode will display the info when you hover over a `require()`
@Cruikshanks Cruikshanks mentioned this pull request Nov 23, 2022
Cruikshanks added a commit that referenced this pull request Nov 23, 2022
In this change, we're just getting on top of some basic things we've either omitted when making changes or because we have made a conscious decision about a way forward.

- Using kebab-case rather than snake_case for filenames
  - Though there is no standard or rule, it's our opinion that most javascript projects use kebab-case
- Ensuring all `require()` statements include the extension
  - We know it's not needed. But as [Switch from CommonJS to ES6 modules](#9) shows, we really want to switch to imports one day and this will set us up for that
- Including module JSDoc comments at the top of each file
  - We use JSDoc to comment our methods. It also recommends CommonJS modules should include a standalone comment. When you do, VSCode will display the info when you hover over a `require()`
- Ensuring the top of our files, where we do our requiring etc is consistent throughout
  - Sometimes its good to have a set structure, as it removes any hesitation or stress from deciding things that don't _actually_ matter, so you can focus on the things that do

For reference, our convention at the top of files is

- `use strict`
- `@module` tag
- external dependencies
- internal modules
- config
- constants

With a new line between each section
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
do not merge Used for spikes and experiments
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants