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

feat: Provide an ESM export #2760

Merged
merged 3 commits into from Mar 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
32 changes: 9 additions & 23 deletions README.md
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
@@ -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
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
@@ -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
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();
});
});
});