Skip to content

Instantly share code, notes, and snippets.

@dungsaga
Forked from noraj/gulp-cjs-to-esm.md
Created July 1, 2023 09:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dungsaga/cf304a4d24cc689b692b2eae4cd1e8a5 to your computer and use it in GitHub Desktop.
Save dungsaga/cf304a4d24cc689b692b2eae4cd1e8a5 to your computer and use it in GitHub Desktop.
Moving gulpfile from CommonJS (CJS) to ECMAScript Modules (ESM)

Moving gulpfile from CommonJS (CJS) to ECMAScript Modules (ESM)

Context

del v7.0.0 moved to pure ESM (no dual support), which forced me to move my gulpfile to ESM to be able to continue to use del.

The author sindresorhus maintains a lot of npm packages and does not want to provides an upgrade guide for each package so he provided a generic guide. But this guide is a bit vague because it's generic and not helping for gulp, hence this guide.

Guide

  1. Rename gulpfile.js to gulpfile.mjs

The first step is easy, since v2.3.0 (#214) gulp-cli supports ESM. So we can just rename gulpfile.js to gulpfile.mjs.

This avoid having to add "type": "module" to package.json which makes no sense if you are not providing a package but rather just use gulp to automate deployment tasks for example.

  1. Change gulp import

Gulp doesn't support all module.exports as named exports yet (#2634) but CJS modules can always be imported via the default export:

-const { series, parallel, src, dest, task } = require('gulp');
+import gulp from 'gulp';
+const { series, parallel, src, dest, task } = gulp;
  1. Change gulp plugins import

Most gulp plugin can be changed easily, eg.

-const pug = require('gulp-pug');
+import pug from 'gulp-pug';
-const replace = require('gulp-replace');
+import replace from 'gulp-replace';
  1. Change gulp-sass

gulp-sass is a tricky one but hopefuly the project README explains how to do it.

-const sass = require('gulp-sass')(require('sass'));
+import dartSass from 'sass';
+import gulpSass from 'gulp-sass';
+const sass = gulpSass(dartSass);

Update: since sass 1.63.0 undocumented breaking change (sass/dart-sass#2011), an import syntax change is reaquired.

-import dartSass from 'sass';
+import * as dartSass from 'sass';
  1. Change del

I could have done import { deleteAsync as del } from 'del'; to keep this named del but it's advised to keep descriptive names to avoid namespace conflicts so I moved it to deleteAsync as recommended and renamed all call to del to deleteAsync in gulpfile.mjs.

-const del = require('del');
+import { deleteAsync } from 'del';
  1. Use node: URL scheme

It's recommanded to use node: URL scheme to import Node.js builtin modules so they are referenced by valid absolute URL strings.

-const { exec } = require('child_process');
+import { exec } from 'node:child_process';

Example

Example of migration for my project:

Lexicon

  • ESM = ES Modules = ECMAScript Modules
  • CSJ = CommonJS

Extensions

System Extension
ESM .mjs
CJS .cjs
Default module system .js

More

More about ESM in:

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