Skip to content

Instantly share code, notes, and snippets.

@michaelwhyte
Forked from noraj/gulp-cjs-to-esm.md
Last active November 8, 2022 22:47
Show Gist options
  • Save michaelwhyte/bea67b84173f6e36f73de8f39a7153a6 to your computer and use it in GitHub Desktop.
Save michaelwhyte/bea67b84173f6e36f73de8f39a7153a6 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)

Credit to Original Author

This gist is modified from a gist by Alexandre Zanni, which can be found at: https://gist.github.com/noraj/007a943dc781dc8dd3198a29205bae04

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

Edit: The original gulp-sass code from the original gist that this gist is based on is not required if you use gulp-dart-sass. Use the standard modified ES Module import statement if using gulp-dart-sass.

import {default as sass} from 'gulp-dart-sass';

The following is from the original gist and is not required if using gulp-dart-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);
  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';
  1. Change Task Exports
-exports.default = series(parallel(sassTask, jsTask), watchTask);
+const defaultTask = series(parallel(sassTask, jsTask), watchTask);
+export default defaultTask;

-exports.build = series(setBuildState, cleanTask, parallel(sassBuildTask, jsBuildTask, jQueryTask), parallel(imagesTask, mediaTask, fontsTask), htmlTask, cacheBustTask);
+const buildTask = series(setBuildState, cleanTask, parallel(sassBuildTask, jsBuildTask, jQueryTask), parallel(imagesTask, mediaTask, fontsTask), htmlTask, cacheBustTask);
+export { buildTask as build};

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