• How to Build and Publish ES6 Modules Today, with Babel and Rollup
  • The Nuggets translation Project
  • Translator: L9m
  • Proofreader: yangzj1992, Malcolm myu

The ES2015 specification, also known as ES6, was approved as an official standard by ECMA International in June 2015. In April 2016, the Node.js Foundation released Node.js framework V6 that supports 93% of ES6 language features, thanks to V5.0 (Node.js) of V8.

It is hard to argue that there is a clear benefit to replacing third-party libraries and polyfills with ES6 and above syntax and existing syntax features. For example, simpler syntax, more readable code, less abstraction, easier maintenance and extension of your code base, faster development of your library, which in lean startup terms means first to market.

If you are developing a new JavaScript library (NPM module) based on the Node.js platform, It might be a good idea to release it to NPM in an optimized Node.js V6 environment and optionally provide fallbacks for developers still using Node.js V5 and earlier versions. So node.js 6 users can import your library normally:

const MyLibrary = require('my-library');
Copy the code

Make sure your code works in the Node.js 6 environment. And Node 0.x, 4.x, and 5.x users can import the ES5.1 version of your library instead (using Babel to convert ES6 to ES5.1) :

var MyLibrary = require('my-library/legacy');
Copy the code

In addition, it is strongly recommended to include libraries that use another version of the ES2015 module syntax in your NPM package. Modules have not landed in Node.js or V8 yet, but are widely used in Node.js and the front-end community thanks to WebPack, Browserify, JSPM, and the Babel compiler. To do this, you need to compile the source into a distributable format optimized for Node.js 6, and make sure that the import/export declarations in the source are not converted to the exports syntax of the ES5 module. Let’s demonstrate how to do this with Rollup and Babel. Your project’s directory structure might look like this:

.├ ─ / Dist / # Temp Folder for Compiled Output ├─ / Legacy / # Legacy Bundle (s) for Node 0. 4. X │ ├─ / Main.js # ├─ for Node 0. ├─ ├─ 2. X │ ├─ ├─ 2. │ ├─ 2. │ ├─ 2 / Main.mjs # ES6 bundle/W Modules for Cool Kids │ ├─ /main.browser. Js # ES5.1 bundle for ├─ /my-library.js # UMD bundle for Browsers │ ├─ / My-library.min.js # UMD bundle. Minified and optimized │ ├─ /package.json # NPM module Settings ├─ /node_modules/ # 3rd-party libraries and utilities ├─ / SRC / # ES2015+ Source Code │ ├─ / Main.js # The Main Entry Point │ ├─ / Sub-modul # A module referenced in ├─ ├─ / # ├─ / # ├─ / # ├─ / # └─ Build automation scripts and utilities └─ / Build  settingsCopy the code

There is a “SRC” folder that contains (using) the ES2015+ syntactic source code for your library, and a “dist” (or “build”) folder that you generate for your project. Include CommonJS, ES6, and UMD Bundles (compiled with Babel and Rollup) for your NPM distribution in the “dist” folder.

The package.json file contains references to these dependency packages:

{" name ":" my - library ", "version" : "1.0.0", "main" : ". The main js ", "jsnext: main" : ". The main MJS ", "browser" : "main.browser.js", ... }Copy the code

The “tools/build.js” script is an easy way to configure the build steps. It looks like this:

'use strict'; const fs = require('fs'); const del = require('del'); const rollup = require('rollup'); const babel = require('rollup-plugin-babel'); const uglify = require('rollup-plugin-uglify'); const pkg = require('.. /package.json'); const bundles = [ { format: 'cjs', ext: '.js', plugins: [], babelPresets: ['stage-1'], babelPlugins: [ 'transform-es2015-destructuring', 'transform-es2015-function-name', 'transform-es2015-parameters' ] }, { format: 'es6', ext: '.mjs', plugins: [], babelPresets: ['stage-1'], babelPlugins: [ 'transform-es2015-destructuring', 'transform-es2015-function-name', 'transform-es2015-parameters' ] }, { format: 'cjs', ext: '.browser.js', plugins: [], babelPresets: ['es2015-rollup', 'stage-1'], babelPlugins: [] }, { format: 'umd', ext: '.js', plugins: [], babelPresets: ['es2015-rollup', 'stage-1'], babelPlugins: [], moduleName: 'my-library' }, { format: 'umd', ext: '.min.js', plugins: [uglify()] babelPresets: ['es2015-rollup', 'stage-1'], babelPlugins: [], moduleName: 'my-library', minify: true } ]; let promise = Promise.resolve(); // Clean up the output directory promise = promise.then(() => del(['dist/*'])); // Compile source code into a distributable format with Babel and Rollup for (const config of bundles) { promise = promise.then(() => rollup.rollup({ entry: 'src/main.js', external: Object.keys(pkg.dependencies), plugins: [ babel({ babelrc: false, exclude: 'node_modules/**', presets: config.babelPresets, plugins: config.babelPlugins, }) ].concat(config.plugins), }).then(bundle => bundle.write({ dest: `dist/${config.moduleName || 'main'}${config.ext}`, format: config.format, sourceMap: ! config.minify, moduleName: config.moduleName, }))); } // Copy package.json and LICENSE.txt promise = promise.then(() => { delete pkg.private; delete pkg.devDependencies; delete pkg.scripts; delete pkg.eslintConfig; delete pkg.babel; fs.writeFileSync('dist/package.json', JSON.stringify(pkg, null, ' '), 'utf-8'); fs.writeFileSync('dist/LICENSE.txt', fs.readFileSync('LICENSE.txt', 'utf-8'), 'utf-8'); }); promise.catch(err => console.error(err.stack)); // eslint-disable-line no-consoleCopy the code

You can now build your library in the “dist” folder and distribute NPM by running “Node Tools /build” (assuming you have Node.js installed locally).

I hope this article has helped developers understand the best way to publish ES6 (modules) on NPM. You can also find a sample of the pre-configured NPM library here: github.com/kriasoft/ba…

If you have any comments or suggestions, feel free to leave them below. Happy Coding!