Skip to content

Commit 2e1a746

Browse files
committed
Require Node.js 18 and move to ESM
1 parent 610074a commit 2e1a746

File tree

7 files changed

+94
-121
lines changed

7 files changed

+94
-121
lines changed

.github/funding.yml

Lines changed: 0 additions & 4 deletions
This file was deleted.

.github/workflows/main.yml

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,11 @@ jobs:
1010
fail-fast: false
1111
matrix:
1212
node-version:
13-
- 14
14-
- 12
15-
- 10
16-
- 8
13+
- 20
14+
- 18
1715
steps:
18-
- uses: actions/checkout@v2
19-
- uses: actions/setup-node@v1
16+
- uses: actions/checkout@v4
17+
- uses: actions/setup-node@v4
2018
with:
2119
node-version: ${{ matrix.node-version }}
2220
- run: npm install

index.js

Lines changed: 30 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,90 +1,66 @@
1-
'use strict';
2-
const {promisify} = require('util');
3-
const fs = require('fs');
4-
const path = require('path');
5-
const replaceExt = require('replace-ext');
6-
const PluginError = require('plugin-error');
7-
const through = require('through2');
8-
9-
const readFile = promisify(fs.readFile);
10-
const stat = promisify(fs.stat);
11-
12-
// Ignore missing file error
13-
function fsOperationFailed(stream, sourceFile, error) {
14-
if (error.code !== 'ENOENT') {
15-
stream.emit('error', new PluginError('gulp-changed', error, {
16-
fileName: sourceFile.path
17-
}));
18-
}
19-
20-
stream.push(sourceFile);
21-
}
1+
import process from 'node:process';
2+
import fs from 'node:fs/promises';
3+
import path from 'node:path';
4+
import changeFileExtension from 'change-file-extension';
5+
import {gulpPlugin} from 'gulp-plugin-extras';
226

237
// Only push through files changed more recently than the destination files
24-
async function compareLastModifiedTime(stream, sourceFile, targetPath) {
25-
// TODO: Use the `stat` `bigint` option when targeting Node.js 10 and Gulp supports it
26-
const targetStat = await stat(targetPath);
8+
export async function compareLastModifiedTime(sourceFile, targetPath) {
9+
const targetStat = await fs.stat(targetPath, {bigint: true});
2710

28-
/*
29-
Precision is lost in the `mtime` when Gulp copies the file from source to target so we cannot compare the modified times directly. This has been the case since Gulp 4. Now, due to an issue in libuv affecting Node.js 14.17.0 and above (including 16.x: https://github.com/nodejs/node/issues/38981) when Gulp copies the file to the target, its `mtime` may be behind the source file by up to 1ms. For example, if the source file has a `mtime` like `1623259049896.314`, the target file `mtime` can end up as `1623259049895.999`. So to compare safely we use floor on the source and ceil on the target, which would give us `1623259049896` for both source and target in that example case.
30-
*/
31-
if (sourceFile.stat && Math.floor(sourceFile.stat.mtimeMs) > Math.ceil(targetStat.mtimeMs)) {
32-
stream.push(sourceFile);
11+
if (sourceFile.stat && sourceFile.stat.mtimeMs > targetStat.mtimeMs) {
12+
return sourceFile;
3313
}
3414
}
3515

3616
// Only push through files with different contents than the destination files
37-
async function compareContents(stream, sourceFile, targetPath) {
38-
const targetData = await readFile(targetPath);
17+
export async function compareContents(sourceFile, targetPath) {
18+
const targetData = await fs.readFile(targetPath);
3919

40-
if (sourceFile.isNull() || !sourceFile.contents.equals(targetData)) {
41-
stream.push(sourceFile);
20+
if (!sourceFile.contents.equals(targetData)) {
21+
return sourceFile;
4222
}
4323
}
4424

45-
module.exports = (destination, options) => {
25+
export default function gulpChanged(destination, options) {
4626
options = {
4727
cwd: process.cwd(),
4828
hasChanged: compareLastModifiedTime,
49-
...options
29+
...options,
5030
};
5131

5232
if (!destination) {
53-
throw new PluginError('gulp-changed', '`dest` required');
33+
throw new Error('gulp-changed: `dest` required');
5434
}
5535

5636
if (options.transformPath !== undefined && typeof options.transformPath !== 'function') {
57-
throw new PluginError('gulp-changed', '`options.transformPath` needs to be a function');
37+
throw new Error('gulp-changed: `options.transformPath` needs to be a function');
5838
}
5939

60-
return through.obj(function (file, encoding, callback) {
61-
const dest2 = typeof destination === 'function' ? destination(file) : destination;
62-
let newPath = path.resolve(options.cwd, dest2, file.relative);
40+
return gulpPlugin('gulp-changed', async file => {
41+
const destination2 = typeof destination === 'function' ? destination(file) : destination;
42+
let newPath = path.resolve(options.cwd, destination2, file.relative);
6343

6444
if (options.extension) {
65-
newPath = replaceExt(newPath, options.extension);
45+
newPath = changeFileExtension(newPath, options.extension);
6646
}
6747

6848
if (options.transformPath) {
6949
newPath = options.transformPath(newPath);
7050

7151
if (typeof newPath !== 'string') {
72-
throw new PluginError('gulp-changed', '`options.transformPath` needs to return a string');
52+
throw new TypeError('`options.transformPath` needs to return a string');
7353
}
7454
}
7555

76-
(async () => {
77-
try {
78-
await options.hasChanged(this, file, newPath);
79-
} catch (error) {
80-
fsOperationFailed(this, file, error);
56+
try {
57+
return await options.hasChanged(file, newPath);
58+
} catch (error) {
59+
if (error.code !== 'ENOENT') {
60+
throw error;
8161
}
8262

83-
callback();
84-
})();
63+
return file;
64+
}
8565
});
86-
};
87-
88-
module.exports.compareLastModifiedTime = compareLastModifiedTime;
89-
module.exports.compareContents = compareContents;
90-
66+
}

license

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) Sindre Sorhus <[email protected]> (sindresorhus.com)
3+
Copyright (c) Sindre Sorhus <[email protected]> (https://sindresorhus.com)
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
66

package.json

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,16 @@
44
"description": "Only pass through changed files",
55
"license": "MIT",
66
"repository": "sindresorhus/gulp-changed",
7+
"funding": "https://github.com/sponsors/sindresorhus",
78
"author": {
89
"name": "Sindre Sorhus",
910
"email": "[email protected]",
10-
"url": "sindresorhus.com"
11+
"url": "https://sindresorhus.com"
1112
},
13+
"type": "module",
14+
"exports": "./index.js",
1215
"engines": {
13-
"node": ">=8"
16+
"node": ">=18"
1417
},
1518
"scripts": {
1619
"test": "xo && ava"
@@ -35,21 +38,19 @@
3538
"passthrough"
3639
],
3740
"dependencies": {
38-
"make-dir": "^3.0.0",
39-
"plugin-error": "^1.0.1",
40-
"replace-ext": "^1.0.0",
41-
"through2": "^3.0.1",
41+
"change-file-extension": "^0.1.0",
4242
"touch": "^3.1.0"
4343
},
4444
"devDependencies": {
45-
"ava": "^2.3.0",
46-
"chalk": "^2.3.0",
47-
"del": "^5.0.0",
48-
"figures": "^3.0.0",
49-
"get-stream": "^5.1.0",
45+
"ava": "^5.3.1",
46+
"chalk": "^5.3.0",
47+
"del": "^7.1.0",
48+
"figures": "^6.0.1",
49+
"get-stream": "^8.0.1",
5050
"gulp": "^4.0.2",
51-
"vinyl": "^2.1.0",
52-
"xo": "^0.24.0"
51+
"gulp-plugin-extras": "^0.3.0",
52+
"vinyl": "^3.0.0",
53+
"xo": "^0.56.0"
5354
},
5455
"peerDependencies": {
5556
"gulp": ">=4"

readme.md

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,18 @@ No more wasting precious time on processing unchanged files.
66

77
By default it's only able to detect whether files in the stream changed. If you require something more advanced like knowing if imports/dependencies changed, create a custom comparator, or use [another plugin](https://github.com/gulpjs/gulp#incremental-builds).
88

9-
109
## Install
1110

11+
```sh
12+
npm install --save-dev gulp-changed
1213
```
13-
$ npm install --save-dev gulp-changed
14-
```
15-
1614

1715
## Usage
1816

1917
```js
20-
const gulp = require('gulp');
21-
const changed = require('gulp-changed');
22-
const ngAnnotate = require('gulp-ng-annotate'); // Just as an example
18+
import gulp from 'gulp';
19+
import changed from 'gulp-changed';
20+
import ngAnnotate from 'gulp-ng-annotate'; // Just as an example
2321

2422
const SOURCE = 'src/*.js';
2523
const DESTINATION = 'dist';
@@ -54,7 +52,7 @@ Type: `object`
5452

5553
##### cwd
5654

57-
Type: `string`<br>
55+
Type: `string`\
5856
Default: `process.cwd()`
5957

6058
Working directory the folder is relative to.
@@ -68,7 +66,7 @@ Extension of the destination files.
6866
Useful if it differs from the original, like in the example below:
6967

7068
```js
71-
exports.jade = () => (
69+
export const jade = () => (
7270
gulp.src('src/**/*.jade')
7371
.pipe(changed('app', {extension: '.html'}))
7472
.pipe(jade())
@@ -78,20 +76,22 @@ exports.jade = () => (
7876

7977
##### hasChanged
8078

81-
Type: `Function`<br>
82-
Default: `changed.compareLastModifiedTime`
79+
Type: `Function`\
80+
Default: `compareLastModifiedTime`
8381

8482
Function that determines whether the source file is different from the destination file.
8583

8684
###### Built-in comparators
8785

88-
- `changed.compareLastModifiedTime`
89-
- `changed.compareContents`
86+
Named imports:
87+
88+
- `compareLastModifiedTime`
89+
- `compareContents`
9090

9191
###### Example
9292

9393
```js
94-
exports.jade = () => (
94+
export const jade = () => (
9595
gulp.src('src/**/*.jade')
9696
.pipe(changed('app', {hasChanged: changed.compareContents}))
9797
.pipe(jade())
@@ -114,7 +114,7 @@ Function to transform the path to the destination file. Should return the absolu
114114
Useful if you rename your file later on, like in the below example:
115115

116116
```js
117-
exports.marked = () => (
117+
export const marked = () => (
118118
gulp.src('src/content/about.md')
119119
.pipe(changed('dist', {transformPath: newPath => path.join(path.dirname(newPath), path.basename(newPath, '.md'), 'index.html')}))
120120
.pipe(marked())
@@ -123,7 +123,6 @@ exports.marked = () => (
123123
);
124124
```
125125

126-
127126
## In-place change monitoring
128127

129128
If you're looking to process source files in-place without any build output (formatting, linting, etc), have a look at [gulp-changed-in-place](https://github.com/alexgorbatchev/gulp-changed-in-place).

0 commit comments

Comments
 (0)