npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

esm-loader-manager

v0.5.1

Published

Allows to use several ESM loaders in one Node.js application.

Downloads

10,460

Readme

esm-loader-manager

Build Status codecov npm

Like Pirates but for ESM.

Works with Node 16.12.0+.

⚠️ As ESM loaders are still experimental in Node.js, this package should also be considered experimental. Use in production environment at your own risk!

How does it work?

This package allows to use several ESM loaders inside one Node.js application. It basically provides an ESM loader that can be configured to pass some of importing modules to user-provided transformation functions (see Examples section for more info).

Built-in Node.js modules and modules located inside node_modules are ignored by the manager!

Installation

npm install esm-loader-manager

Usage

The loader manager needs to be added as an ESM loader to your Node application. It can be done in two different ways.

Via Node.js flag

This is probably the easiest way to use the loader manager. You can add it to your application using the --experimental-loader flag:

node --experimental-loader=esm-loader-manager

Via esmlm executable

If, however, you find the flag version too long/repulsive, the package provides esmlm executable that adds it for you! It takes the path to the Node.js application as a parameter (defaults to CWD)

The esmlm can be e.g. used inside npm scripts:

{
	// Rest of package.json
	"scripts": {
		"start": "esmlm"
	}
}

Or it can be invoked using npx:

npx esm-loader-manager <path to your app>

Note that you need to use package name (not executable one!) when using npx.

Configuration

The loader manager does nothing on its own but you can declare your loaders inside the configuration file.

Configuration file format

The configuration file needs to be named .esmlmrc.js or .esmlmrc.mjs.

The sample one could look like the one below:

export default {
	loaders: [
		{
			matcher( url ) {
				return url.endsWith( 'module.js' );
			},
			loader( url, content ) {
				return content;
			}
		}
	]
};

The configuration file needs to export an object as a default export. This object needs to have the loaders property that contains an array of loaders.

Each loader is an object with two methods: matcher() and loader().

matcher( url: string, context: LoaderContext ): boolean

The task of this method is to check if the module identified by the passed URL should be handled by this particular loader. If yes, it should return true and false otherwise.

loader( url: string, source: Buffer | string ): Buffer | string

This method transforms the source of the module. The manager takes care of actual loading of module file and each loader gets its content. The content is then passed via all loaders sequentially.

Configuration file location

The manager will look for the configuration file inside the CWD and go up until it hits the project root directory (the nearest one with the package.json file). Let's imagine we have a following file structure:

- projectRoot/
|- package.json
|- .esmlmrc.js
|- subdir/
|  |- app.js
|  |- .esmlmrc.js
|- someOtherDir/
|  |- someOtherApp.js

If we launch Node.js inside projectRoot/subdir, the manager will use the projectRoot/subdir/.esmlmrc.js file. However, if we launch Node.js inside projectRoot/someOtherDir (which does not contain its own configuration file), the projectRoot/.esmlmrc.js one will be used.

If for some reason you want to have a config file under some other name, you can provide the path to it via ESMLM_CONFIG environment variable, e.g.

ESMLM_CONFIG="./customConfig.js" esmlm .

Typings

The package contains also basic typings for the configuration file. They can be used via JSDoc syntax, e.g.:

/**
 * @type {import('esm-loader-manager').LoaderConfiguration}
 */
const config = {
	loaders: [
		{
			matcher( url ) {
				return url.endsWith( 'module.js' );
			},
			loader( url, content ) {
				return content;
			}
		}
	]
};

export default config;

For some reason TS seems to have issue when the export is inlined and the type can be incorrectly applied to the export itself instead of the exported object. It's much safer to move exported object to its own variable.

Examples

Transforming PNG images into JS modules

Files

index.js

import samplePng from './sample.png';

console.log( samplePng ); // data:image/png;base64,[…]

.esmlmrc.js

export default {
	loaders: [
		{
			matcher( url ) {
				return url.endsWith( '.png' );
			},
			loader( url, content ) {
				const dataURL = content.toString( 'base64' );

				return `export default "data:image/png;base64,${ dataURL }";`;
			}
		}
	]
};

package.json

{
  "name": "esmlm-test",
  "version": "1.0.0",
  "main": "index.js",
  "type": "module",
  "dependencies": {
    "esm-loader-manager": "^0.1.0"
  },
  "scripts": {
    "start": "esmlm"
  }
}

sample.png

Well, a sample PNG image ¯\(ツ)

Running

cd app-dir
npm start

If you enter the app directory and then run npm start, you should see an image Data URL displayed in the terminal.

Known limitations

  • Only file:// module URLs are supported.
  • The project root path is not customizable, meaning that this package can be less useful in monorepo environments.
  • Ignoring built-in modules and node_modules ones can't be configured.

License

See LICENSE file for details.