'How write an npm package that supports every JavaScript environments (module systems)

For the last couple of weeks I've been working on a utility library and now I want to publish it on npm for other people to use.

The library doesn't use any node specific features except the commonjs module system. It's written in pure es6 and doesn't have any dependency. I want it to be compatible with both front-end (vanilla JavaScript, react etc.) and also for back-end in Nodejs.

I already looked up a few articles about this but they used babel, webpack some talked about rollup and bower... I'm only familiar babel and webpack but I don't know how to use them for this project (but I'm willing to learn those technologies if needed).

I just need some hint how to move forward from this point. Please give me some suggestion on this topic.

Thanks is advance <3. I highly appreciate your efforts on StackOverflow.



Solution 1:[1]

A low tech solution is to create a single variable that provides the complete API or API endpoints provided by the package script when loaded in a browser. If need be write the package inside an IIFE to prevent package variables polluting the browser's global address space.

Additionally test if the script has been required in node as a commonJS module and export the API using commonJS hooks if it has:

var myAPI = (()=>{
   var exports = {}
   //...
   exports.foo = "foo";
   //...
   return exports;
})();

// export myAPI if running in node

if( typeof module == "object" && module && module.exports
 && this && this === module.exports
 && typeof require == "function") {
    module.exports = myAPI;
}

The not-so-well-known part of the node signature is that commonJS modules are called with their this object set to module.exports.

This approach was developed as a workaround for you can't run JS modules via a file:// URL - if the restrictions on module use are acceptable consider using JS modules directly.

While aware of more complicated methods to handle a wider range of usage environments, I have not seen descriptions of how they work. If readers have insights into better or more general solutions I would welcome reading additional answers.


You can also tell node that a JavaScript file with a .js extension is actually an es6 module by including

  "type": "module",

in the root (JSON) object of the project's package.json file - which for a package containing a single script should be all that is needed.

To actually use a module file in node, ensure that the main application script file has been given an mjs extension (so it can use import statements without throwing errors), or in a commonJS environment import the module using an import expression.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1