On this page
Node.js logo on the abstract background. Abstract background made by Gerd Altmann from Pixabay.

Replacing glob-all with fs.promises.glob in Node.js

Replace glob-all with fs.promises.glob in Node.js to simplify code, reduce dependencies, and optimize bundle size.

As Node.js continues to get more and more native, built-in features, developers are constantly looking for ways to simplify their code and reduce dependencies on external packages. One such opportunity arises when replacing (or much better alternative to) the glob-all package with the built-in fs.promises.glob function, available in Node.js from version 22.0.0 behind the flag --experimental-glob and became un-flagged in v22.2.0.

The glob-all package has been a popular choice for globbing files in Node.js, but with the introduction of fs.promises.glob in recent versions of Node.js, it’s now possible to achieve the same results without an additional dependency.

The glob-all way of using

Previously, you might have used glob-all to glob files like this:

Before (glob-all)
const glob = require('glob-all');
const pattern = ['src/**/*.js', '!src/**/*.test.js'];
const files = await glob(pattern, options);

Where:

  • pattern: the glob pattern to match files (e.g., /path/*.json)
  • options: an object with options, such as ignore (e.g., ['/path/ignore'])

Replace glob-all with fs.promises.glob in Node.js at least 22.2

With fs.promises.glob, you can achieve the same result using the built-in fs module:

After (native)
const fs = require('node:fs');
const pattern = 'src/**/*.js';
const options = {
  exclude: ['**/*.test.js']
};
const files = await fs.promises.glob(pattern, options);

Where:

  • pattern: <string> | <string[]>
  • options: <Object>
    • cwd: <string> | <URL> current working directory. Default:process.cwd()
    • exclude<Function> | <string[]> Function to filter out files/directories or a list of glob patterns to be excluded. If a function is provided, return true to exclude the item, false to include it. Default:undefined. If a string array is provided, each string should be a glob pattern that specifies paths to exclude. Note: Negation patterns (e.g., ‘!foo.js’) are not supported.
    • withFileTypes: <boolean>true if the glob should return paths as Dirents, false otherwise. Default:false.
  • Returns: <AsyncIterator> An AsyncIterator that yields the paths of files that match the pattern.
ignore to exclude (must be globs)
glob-allfs.promises.glob
ignore: ['some/dir']exclude: ['some/dir/**']
ignore: ['**/*.tmp']exclude: ['**/*.tmp']

Forget the /** suffix and the rule is silently ignored. You need to add it back.

Mapping old way to new way

Here’s a direct mapping:

Old way
const glob = require('glob-all');

const filesToProcess = await glob('/path/*.json', {
  ignore: ['/path/ignore'],
});
The shortest new way
const fs = require('node:fs');
const files = await fs.promises.glob(pattern, options);

fs.promises.glob ignores bare paths silently, so you must supply minimatch patterns in an exclude array.

Eventually, want to transform each path while iterating? Use Array.fromAsync:

Transform each path while iterating
const fs = require('node:fs');

const files = await Array.fromAsync(
  fs.promises.glob('src/**/*.js'),
  path => path.replace(/\.js$/, '.mjs')
);

Quick conversion rule

  • ignore: ['some/dir']exclude: ['some/dir/**']
  • ignore: ['**/*.test.js']exclude: ['**/*.test.js']

If your ignore rule stopped working, 99 % of the time you forgot the /** suffix or you’re still using the old ignore key.

Error handling

fs.promises.glob throws on illegal patterns or permission errors. Wrap with try…catch in production code.

Benefits of using fs.promises.glob

By using fs.promises.glob, you can:

  • Remove the glob-all package as a dependency.
  • Simplify your code and reduce the number of dependencies.
  • Take advantage of the built-in functionality provided by Node.js.
  • Reduce your bundle size.

Example use case

Here’s a more comprehensive example that demonstrates how to use fs.promises.glob to glob files:

Example usage of fs.promises.glob
const fs = require('node:fs');

async function main() {
  try {
    const pattern = '/path/*.json';
    const options = {
      exclude: ['/path/ignore/**']   // glob pattern, not bare folder
    };

    const filesToProcess = await fs.promises.glob(pattern, options);
    console.log(filesToProcess);
  } catch (error) {
    console.error(error);
  }
}

main();

Conclusion

Replacing glob-all with fs.promises.glob is a straightforward process that can help simplify your code and reduce dependencies. By taking advantage of the built-in functionality provided by Node.js, you can write more efficient and maintainable code.

Related posts

Comments

Leave a Reply

Search in sitelint.com

Looking for automated testing for technical SEO?

With SiteLint, you can help search engine spiders crawl and index your site more effectively.