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

main-dir

v1.0.2

Published

Add support for the `mainDir` field in a node module

Downloads

10

Readme

main-dir

This package is a userland implementation of a proposed change to the Node module resolution alogrithm, proposed in nodejs/node#14970.

This adds support for a mainDir property in package.json files, which lets package authors indicate a subfolder of the package that all lookups should be relative to.

Usage

require('main-dir');
// All require calls from here on out will respect `mainDir` 
// options when present in package.json files

Use cases

The predominant use case for this is for packages written in a different source language, and compiled/transpiled down to JavaScript to ensure interopability with the widest audience of Node.js consumers.

Without mainDir, such package authors are left with a tradeoff when it comes time to compile and publish their work:

  1. They compile into a dist/ folder and publish the root directory. Downside: consumers must include dist/ in the path of any file-specific imports, i.e. require('foo/dist/bar/quux').
  2. They compile into a dist/ folder and publish only the dist/ folder. Downside: they must remember to publish from a subfolder every time, and if the author wants to ship other files in the package (i.e. a readme), additional build steps are now required to copy those into dist/ too.
  3. They compile into the project root and publish the root directory. Downside: cluttered root directory, especially while using npm link to test the package locally, as well as potential naming collisions with other package files.

With the proposed changes, such addon authors could specify "mainDir": "dist" in their package.json, and avoid any of these downsides:

  1. Consumers don't need to specify build directories in import paths, since Node would check mainDir automatically and transparently
  2. The author can publish from root directory like a normal package, no additional build steps needed to include readmes, etc.
  3. Projects stay tidy by compiling into a single dist/ folder

If a main field is also specified, and the consumer attempts to import the entire module, then mainDir and main are joined to find the entry point for the module:

// foo/package.json
{
  "main": "helloworld.js",
  "mainDir": "dist"
}

// my-app.js
require('foo'); // loads 'foo/dist/helloworld.js'

If no main field is specified, then the usual index.js file is attempted:

// foo/package.json
{
  "mainDir": "dist"
}

// my-app.js
require('foo'); // loads 'foo/dist/index.js'

Potential downsides

The module resolution alogrithm is sacrosanct in Node, largely because even subtle changes have the chance to potentially break the vast ecosystem of packages relying on the current semantics.

The proposal above for a change to core attempts to minimize this by claiming a new package.json field rather than repurposing the existing main field. A Github code search reveals zero uses of the newly proposed mainDir field in any public package.json file. While this doesn't guarantee that private repositories somehwere are not using it, it's a strong indicator that any such use is minimal (if existent at all).

Where does this package fit in?

This package, main-dir, provides an opt-in way to try the proposed semantics. It does so by monkey-patching Node's Module class. Only a handful of lines are changed to check for and respect any mainDir fields encountered. Require this package once in your Node process, and all subsequent requires will respect mainDir.

Because it monkey-patches the Module class, care should be taken when upgrading Node. While the semantics of that Module are unlikely to change from version to version, caution is still worthwhile given the low-level nature of the patching performed by this package.