Skip to content

Commit

Permalink
feat: Provide an ESM export (#2760)
Browse files Browse the repository at this point in the history
  • Loading branch information
phated authored Mar 25, 2024
1 parent 72668c6 commit b00de68
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 23 deletions.
32 changes: 9 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,26 +112,12 @@ exports.default = build;

## Use latest JavaScript version in your gulpfile

__Most new versions of node support most features that Babel provides, except the `import`/`export` syntax. When only that syntax is desired, rename to `gulpfile.esm.js`, install the [esm][esm-module] module, and skip the Babel portion below.__
Gulp provides a wrapper that will be loaded in your ESM code, so you can name your gulpfile as `gulpfile.mjs` or with `"type": "module"` specified in your `package.json` file.

Node already supports a lot of __ES2015+__ features, but to avoid compatibility problems we suggest to install Babel and rename your `gulpfile.js` to `gulpfile.babel.js`.

```sh
npm install --save-dev @babel/register @babel/core @babel/preset-env
```

Then create a **.babelrc** file with the preset configuration.

```js
{
"presets": [ "@babel/preset-env" ]
}
```

And here's the same sample from above written in **ES2015+**.
And here's the same sample from above written in **ESNext**.

```js
import gulp from 'gulp';
import { src, dest, watch } from 'gulp';
import less from 'gulp-less';
import babel from 'gulp-babel';
import concat from 'gulp-concat';
Expand Down Expand Up @@ -160,31 +146,31 @@ export const clean = () => del([ 'assets' ]);
* You can also declare named functions and export them as tasks
*/
export function styles() {
return gulp.src(paths.styles.src)
return src(paths.styles.src)
.pipe(less())
.pipe(cleanCSS())
// pass in options to the stream
.pipe(rename({
basename: 'main',
suffix: '.min'
}))
.pipe(gulp.dest(paths.styles.dest));
.pipe(dest(paths.styles.dest));
}

export function scripts() {
return gulp.src(paths.scripts.src, { sourcemaps: true })
return src(paths.scripts.src, { sourcemaps: true })
.pipe(babel())
.pipe(uglify())
.pipe(concat('main.min.js'))
.pipe(gulp.dest(paths.scripts.dest));
.pipe(dest(paths.scripts.dest));
}

/*
* You could even use `export as` to rename exported tasks
*/
function watchFiles() {
gulp.watch(paths.scripts.src, scripts);
gulp.watch(paths.styles.src, styles);
watch(paths.scripts.src, scripts);
watch(paths.styles.src, styles);
}
export { watchFiles as watch };

Expand Down
16 changes: 16 additions & 0 deletions index.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import gulp from "./index.js";

// These are bound to the gulp instance in our CommonJS file
// so it is okay to reassign them to export
export const watch = gulp.watch;
export const task = gulp.task;
export const series = gulp.series;
export const parallel = gulp.parallel;
export const registry = gulp.registry;
export const tree = gulp.tree;
export const lastRun = gulp.lastRun;
export const src = gulp.src;
export const dest = gulp.dest;
export const symlink = gulp.symlink;

export default gulp;
6 changes: 6 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@
"node": ">=10.13.0"
},
"main": "index.js",
"exports": {
".": {
"import": "./index.mjs",
"require": "./index.js"
}
},
"files": [
"LICENSE",
"index.js",
Expand Down
30 changes: 30 additions & 0 deletions test/fixtures/gulpfiles/mjs/gulpfile.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import assert from "assert";
import EventEmitter from "events";

import gulp, {
watch,
task,
series,
parallel,
registry,
tree,
lastRun,
src,
dest,
symlink,
} from 'gulp';

export default function (done) {
assert(typeof watch === 'function');
assert(typeof task === 'function');
assert(typeof series === 'function');
assert(typeof parallel === 'function');
assert(typeof registry === 'function');
assert(typeof tree === 'function');
assert(typeof lastRun === 'function');
assert(typeof src === 'function');
assert(typeof dest === 'function');
assert(typeof symlink === 'function');
assert(gulp instanceof EventEmitter);
done();
}
18 changes: 18 additions & 0 deletions test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,22 @@ describe('gulp', function() {
done();
});
});

it('can run against gulpfile.mjs', function (done) {
// Node v10 didn't support `exports` in package.json
if (process.version.startsWith('v10.')) {
this.skip();
}

this.timeout(5000);

var cli = path.join(__dirname, '../bin/gulp.js');
var opts = { cwd: path.join(__dirname, 'fixtures/gulpfiles/mjs' ) };
cp.exec('node ' + cli, opts, function (err, stdout, stderr) {
expect(err).toBeNull();
expect(stdout).toMatch('gulpfile.mjs');
expect(stderr).toEqual('');
done();
});
});
});

0 comments on commit b00de68

Please sign in to comment.