webpack-node-module-types v1.2.4
⛔️ DEPRECATED/UNMAINTAINED
This project served its purpose back in the day. JavaScript and Webpack have evolved mightily over the last decade, and as a result this project does not make much sense anymore.
This package attempts to determine the module type (ESM/.mjs vs
CJS/.cjs/.js) of each top-level package in node_modules/, including scoped
packages. It comes to the same determination about a module's type as Webpack
does in the vast majority of cases. In other cases, like with modules that
present as CJS format, an ES module might be misclassified as CJS.
The resolution algorithm is based on
Node's ESM_FORMAT algorithm to determine module format
with the additional awareness of the module key; hence, we classify a package
as ESM if its package.json has any of the following:
- A
mainkey with a value ending in".mjs" - A sub-key (any depth) of the
exportkey with a value ending in".mjs" - A
typekey with the value"module" - A
modulekey
It cannot be determined through package metadata alone if a module exports
__esModule = true, so transpiled ES modules that don't meet any of the above
requirements will be misclassified.
This package was originally created for babel-plugin-transform-default-named-imports to help smooth over Typescript-to-CJS/ESM transpilation issues, but can be useful whenever one needs to know how Webpack will attempt to load a package.
Installation
npm install --save-dev webpack-node-module-typesUsage
In addition to the bare import, this module exports two deep exports: /sync
and /async. Both CJS require() and ESM-style import syntax are supported.
// Returns the asynchronous promise-based API (faster, better)
import { determineModuleTypes } from 'webpack-node-module-types';
// Returns the synchronous API (useful for plugin authors)
import { determineModuleTypes } from 'webpack-node-module-types/sync';
// Returns the same asynchronous promise-based API as the first version
import { determineModuleTypes } from 'webpack-node-module-types/async';Here's an example from Node's REPL listing this package's own CJS and ESM dependencies:
> const { determineModuleTypes } = require('webpack-node-module-types/sync')
undefined
> console.log(determineModuleTypes())
{
cjs: [
'@babel/cli',
'@babel/code-frame',
'@babel/compat-data',
'@babel/core',
'@babel/generator',
'@babel/helper-annotate-as-pure',
'@babel/helper-builder-binary-assignment-operator-visitor',
'@babel/helper-compilation-targets',
... 621 more items
],
esm: [
'@sinonjs/fake-timers',
'@webassemblyjs/ast',
'@webassemblyjs/floating-point-hex-parser',
'@webassemblyjs/helper-api-error',
'@webassemblyjs/helper-buffer',
'@webassemblyjs/helper-code-frame',
'@webassemblyjs/helper-fsm',
'@webassemblyjs/helper-module-context',
... 33 more items
]
}As of February 2021, most of this package's dependencies are not offering ESM entry points 🤯
Monorepo Support
As of version 1.2.0, webpack-node-module-types supports monorepo setups
through the rootMode parameter. Similar to
Babel's root-mode flag,
{ rootMode: "upward" } makes webpack-node-module-types search from the
working directory parent upward until it finds an additional node_modules
directory to scrutinize. If no higher level node_modules directory is found,
an error is thrown.
Packages found under any local node_modules directory, if it exists, take
precedence over those found in a higher-level node_modules directory.
Example:
// process.cwd() => /repos/my-workspace/packages/pkg-1
const { determineModuleTypes } = require('webpack-node-module-types/sync');
console.log(determineModuleTypes({ rootMode: 'upward' }));
// Will find:
// - /repos/my-workspace/packages/pkg-1/node_modules (local node_modules, highest precedence, optional)
// - /repos/my-workspace/node_modules ("upward" node_modules, must exist)
rootModeis set to "local" by default.
In addition to "upward" and "local", rootMode also accepts an explicit
node_modules path (beginning with ./ or ../) relative to the current
working directory. When used in this way, packages found under the relative
node_modules directory, if it exists, take precedence over those found in any
local node_modules directory. If no local node_modules directory is found,
an error is thrown.
Example:
// process.cwd() => /repos/my-workspace
const { determineModuleTypes } = require('webpack-node-module-types/sync');
console.log(
determineModuleTypes({ rootMode: './packages/pkg-1/node_modules' })
);
// Will find:
// - /repos/my-workspace/node_modules (local node_modules, must exist)
// - /repos/my-workspace/packages/pkg-1/node_modules (relative node_modules, highest precedence, optional)Documentation
This is a simple CJS2 package with a default export.
package.json includes the exports and
main keys, which point to the CJS2 entry point, the
type key, which is commonjs, and the
sideEffects key, which is false for optimal tree
shaking, and the types key, which points to a TypeScript
declarations file.
Contributing
New issues and pull requests are always welcome and greatly appreciated! If you submit a pull request, take care to maintain the existing coding style and add unit tests for any new or changed functionality. Please lint and test your code, of course!