Skip to content

Latest commit

 

History

History
89 lines (58 loc) · 5.58 KB

README.md

File metadata and controls

89 lines (58 loc) · 5.58 KB

esmy

Build Status

Converts npm packages to native ES6 modules which can be imported directly from modern browsers without bundlers and transpilers.

For example, to install the react package as a browser-compatible ES6 module run this command: npx esmy react, or: npm init esmy react, or: yarn create esmy react. The file ./es_modules/react.js will be created. Modern browsers can import it like this:

<script type="module">
import React from './es_modules/react.js';
console.log(React);
</script>

Why

All modern browsers now support importing ES6 modules within <script type="module">. They also support most of the other ES6+ features. So it makes feasible to get rid of the bloat of bundlers and transpilers at least during development.

Also, it's tempting to use the npm package registry as the largest source of third-party JavaScript code. But at the moment of writing, most of its packages are provided in the CommonJS format which is incompatible with ES6 modules. Although some of them are distributed as ES6 modules as well, package authors assume that they will be used in conjunction with bundles like webpack which are not strictly compatible with browsers' implementation of ES6 modules (e.g. extensions in imports may be omitted: import './foo', or there may be 'unqualified' imports from node_modules or Node.js packages: import 'foo', etc.)

esmy solves this problem trying to build browser-compatible ES6 modules from npm packages on install time with the help of the Rollup bundler.

This project was inspired by jspm.io (not to be confused with the seemed to be obsolete jspm package manager) which provides CDN for browser-compatible ES6 modules compiled from npm packages.

Usage

To quickly install npm packages as browser-compatible ES6 modules, without installing esmy itself, run (if you have npm >= 5.2.0 installed):

npx esmy react

For older npm, or if your system has no npx executable:

npm init esmy react

Or if you prefer yarn and have it installed:

yarn create esmy react

If you have a project with package.json and want to declare browser-compatible ES6 modules as dependencies than install esmy as a development dependency either using yarn:

yarn add -D esmy

or using npm:

npm install -D esmy

It will install the esmy command locally which can be run using one of these commands: yarn esmy, npx esmy, or ./node_modules/.bin/esmy.

Then add the esmy command to the "install" script entry of package.json:

{
  "scripts": {
    "install": "esmy"
  }
}

It will build browser-compatible ES6 modules from npm packages declared in the "dependencies" section in package.json and put them in the ./es_modules directory every time yarn install or npm install is performed.

If you pass any arguments to the esmy command it will first try to run yarn with these arguments if it's available, otherwise, it will run npm with them. So you can pass any arguments (or options) yarn or npm understand.

Special cases

Some npm packages (like react) rely on the NODE_ENV environment variable to provide different behavior under different environments like development or production. esmy builds them with NODE_ENV=development by default. You can override it (if you need to) passing an actual environment variable NODE_ENV like this:

NODE_ENV=production esmy react

Some npm packages use the Node.js standard library which is not available in browsers and needs to be polyfilled. To make esmy build them install npm packages rollup-plugin-node-builtins and rollup-plugin-node-globals as development dependencies and run esmy locally which will use these plugins on a build. Note that not all standard Node.js modules can be polyfilled, see (readme)(https://github.com/calvinmetcalf/rollup-plugin-node-builtins/blob/master/readme.md) of rollup-plugin-node-builtins for details.

Limitations

  • npm modules can export only default exports which rollup-plugin-commonjs (used under the hood of esmy) can convert to named ones most of the times. But sometimes it's not possible, see here.
  • ES6 modules implies operating in strict mode (like one you get with 'use strict';). Some npm modules use non-strict (aka lousy mode) and may fail in strict mode. Therefore they can't be converted to ES6 modules without rewriting original npm modules, see here.
  • At the moment it's not possible to import submodules. E.g. it's a known issue for the rxjs package which exposes its API not only from an entry package module (require('rxjs')) but also from its submodules (require('rxjs/operators')). It may be addressed in next esmy versions.
  • If multiple packages depend on the same package than they all will include a copy of it in their compiled ES6 packages because of how bundling currently works. There are exclusions for some popular packages like jquery and react which are declared as external dependencies but you may expect some code duplication with other shared packages. A list of known external dependencies can be expanded by a pull request.