From 10894a9199831f713f4cd4a590c860556a25d46c Mon Sep 17 00:00:00 2001 From: Jordan Tucker Date: Thu, 11 Aug 2022 16:33:15 -0500 Subject: [PATCH] feat: add support for modules This large commit enhances support for JavaScript modules. This adds `lib/index.mjs`, which re-exports `lib/index.js` as a default export and `parse` and `stringify` as named exports. The `module` field in `package.json` now points to this file as the entry point for `import` statements in versions of Node.js that support modules. With this change, `import` statements in Node.js no longer need to use the path `json5/dist/index.mjs`, and should import the module as `json5` instead. `test/index.mjs` ensures that `lib/index.js` and `lib/index.mjs` export the same instance. This follows the guidance in approach #1 of [Writing dual packages while avoiding or minimizing hazards][guidance]. `rollup.config.js` now uses `lib/index.mjs` as its entry point for building browser bundles for JavaScript modules environments. It now writes browser bundles to `dist/json5.js` and `dist/json5.esm.js`, as well as minified versions. These are the new canonical paths for browser bundles. The legacy `dist/index.*` paths still exist for backward compatibility, but they will be removed in the next major version. All files in `build` and `lib` now explicitly require `lib/index.js` to ensure that `lib/index.mjs` is not imported. All files in `test` now require the package root to simulate the default behavior of the version of Node.js being tested. [guidance]: https://nodejs.org/dist/latest-v16.x/docs/api/packages.html#writing-dual-packages-while-avoiding-or-minimizing-hazards --- build/es5.js | 2 +- build/package.js | 2 +- lib/cli.js | 2 +- lib/index.mjs | 7 +++++ lib/index.mjs.d.ts | 5 ++++ lib/register.js | 2 +- package.json | 4 +-- rollup.config.js | 70 +++++++++++++++++++++++++++++++++------------- test/errors.js | 2 +- test/index.mjs | 8 ++++++ test/parse.js | 2 +- test/stringify.js | 2 +- 12 files changed, 79 insertions(+), 29 deletions(-) create mode 100644 lib/index.mjs create mode 100644 lib/index.mjs.d.ts create mode 100644 test/index.mjs diff --git a/build/es5.js b/build/es5.js index 1123c534..957c7c97 100644 --- a/build/es5.js +++ b/build/es5.js @@ -1,6 +1,6 @@ require('core-js/fn/string/code-point-at') require('core-js/fn/string/from-code-point') -const JSON5 = require('../lib') +const JSON5 = require('../lib/index.js') module.exports = JSON5 diff --git a/build/package.js b/build/package.js index 9abf3f79..39f5f769 100644 --- a/build/package.js +++ b/build/package.js @@ -1,7 +1,7 @@ const fs = require('fs') const path = require('path') -const JSON5 = require('../lib') +const JSON5 = require('../lib/index.js') const pkg = require('../package.json') diff --git a/lib/cli.js b/lib/cli.js index 93cb8092..e88a36e7 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -3,7 +3,7 @@ const fs = require('fs') const path = require('path') const pkg = require('../package.json') -const JSON5 = require('./') +const JSON5 = require('./index.js') const argv = parseArgs() diff --git a/lib/index.mjs b/lib/index.mjs new file mode 100644 index 00000000..e8840d05 --- /dev/null +++ b/lib/index.mjs @@ -0,0 +1,7 @@ +/* eslint-disable node/no-unsupported-features/es-syntax */ + +import JSON5 from './index.js' + +export const parse = JSON5.parse +export const stringify = JSON5.stringify +export default JSON5 diff --git a/lib/index.mjs.d.ts b/lib/index.mjs.d.ts new file mode 100644 index 00000000..7c6a8700 --- /dev/null +++ b/lib/index.mjs.d.ts @@ -0,0 +1,5 @@ +import parse = require('./parse') +import stringify = require('./stringify') + +export {parse, stringify} +export default {parse, stringify} diff --git a/lib/register.js b/lib/register.js index 935cdbaf..6eea8de8 100644 --- a/lib/register.js +++ b/lib/register.js @@ -1,5 +1,5 @@ const fs = require('fs') -const JSON5 = require('./') +const JSON5 = require('./index.js') // eslint-disable-next-line node/no-deprecated-api require.extensions['.json5'] = function (module, filename) { diff --git a/package.json b/package.json index 41a3f68f..4df67085 100644 --- a/package.json +++ b/package.json @@ -3,9 +3,9 @@ "version": "2.2.1", "description": "JSON for humans.", "main": "lib/index.js", - "module": "dist/index.mjs", + "module": "lib/index.mjs", "bin": "lib/cli.js", - "browser": "dist/index.js", + "browser": "dist/json5.js", "types": "lib/index.d.ts", "files": [ "lib/", diff --git a/rollup.config.js b/rollup.config.js index 871066d8..0beba22c 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -8,11 +8,19 @@ module.exports = [ // ES5 Non-minified { input: 'build/es5.js', - output: { - file: pkg.browser, - format: 'umd', - name: 'JSON5', - }, + output: [ + { + file: pkg.browser, + format: 'umd', + name: 'JSON5', + }, + { + // Legacy path + file: 'dist/index.js', + format: 'umd', + name: 'JSON5', + }, + ], plugins: [ resolve(), commonjs(), @@ -22,11 +30,19 @@ module.exports = [ // ES5 Minified { input: 'build/es5.js', - output: { - file: pkg.browser.replace(/\.js$/, '.min.js'), - format: 'umd', - name: 'JSON5', - }, + output: [ + { + file: pkg.browser.replace(/\.js$/, '.min.js'), + format: 'umd', + name: 'JSON5', + }, + { + // Legacy path + file: 'dist/index.min.js', + format: 'umd', + name: 'JSON5', + }, + ], plugins: [ resolve(), commonjs(), @@ -36,11 +52,18 @@ module.exports = [ }, // ES6 Modules Non-minified { - input: 'lib/index.js', - output: { - file: pkg.browser.replace(/\.js$/, '.mjs'), - format: 'esm', - }, + input: 'lib/index.mjs', + output: [ + { + file: pkg.browser.replace(/\.js$/, '.esm.js'), + format: 'esm', + }, + { + // Legacy path + file: 'dist/index.mjs', + format: 'esm', + }, + ], plugins: [ resolve(), commonjs(), @@ -48,11 +71,18 @@ module.exports = [ }, // ES6 Modules Minified { - input: 'lib/index.js', - output: { - file: pkg.browser.replace(/\.js$/, '.min.mjs'), - format: 'esm', - }, + input: 'lib/index.mjs', + output: [ + { + file: pkg.browser.replace(/\.js$/, '.esm.min.mjs'), + format: 'esm', + }, + { + // Legacy path + file: 'dist/index.min.mjs', + format: 'esm', + }, + ], plugins: [ resolve(), commonjs(), diff --git a/test/errors.js b/test/errors.js index 1d1657c6..115dea94 100644 --- a/test/errors.js +++ b/test/errors.js @@ -1,5 +1,5 @@ const assert = require('assert') -const JSON5 = require('../lib') +const JSON5 = require('..') require('tap').mochaGlobals() diff --git a/test/index.mjs b/test/index.mjs new file mode 100644 index 00000000..e09bdb41 --- /dev/null +++ b/test/index.mjs @@ -0,0 +1,8 @@ +/* eslint-disable import/no-duplicates, node/no-unsupported-features/es-syntax */ + +import JSON5Modules from '..' +import JSON5CommonJS from '../lib/index.js' + +import t from 'tap' + +t.strictSame(JSON5Modules, JSON5CommonJS, 'Modules export and CommonJS export are the same') diff --git a/test/parse.js b/test/parse.js index 59fbdd15..e87f98b7 100644 --- a/test/parse.js +++ b/test/parse.js @@ -1,6 +1,6 @@ const assert = require('assert') const sinon = require('sinon') -const JSON5 = require('../lib') +const JSON5 = require('..') require('tap').mochaGlobals() diff --git a/test/stringify.js b/test/stringify.js index a0c494f0..9933885a 100644 --- a/test/stringify.js +++ b/test/stringify.js @@ -1,5 +1,5 @@ const assert = require('assert') -const JSON5 = require('../lib') +const JSON5 = require('..') require('tap').mochaGlobals()