Editions
  • Overview
  • Ecosystem
  • Specification
  • Tags
  • FAQ
  • Comparisons
    • Alternative Approaches
    • Fields Comparison
Powered by GitBook
On this page
  • Why use Editions?
  • Defining Editions
  • How do I define an Edition?
  • Example Editions Definition
  • Automatic Creation of Editions
  • Consuming Editions
  • A Specified Edition
  • Best Edition for the Environment
  • Manually Require a Specific Edition
  • Browser Edition
  • Documenting Editions
  • Automatic Editions Rendering without the Editions Autoloader
  • Automatic Editions Documentation with the Editions Autoloader

Was this helpful?

Overview

Editions are the best way to produce and consume the JavaScript packages you care about. With Editions you can produce packages beautifully, and consume packages perfectly.

NextEcosystem

Last updated 6 years ago

Was this helpful?

Editions is for describing the ways in which your project has been produced to accelerate manual consumption, as well as automatic consumption through .

Why use Editions?

JavaScript production and consumption has gotten difficult over the years.

Production use to be as easy as publishing your source code, which worked across all environments, with a few minor tweaks. Consumption was as easy as including the package, and you are done.

Defining Editions

An edition is each variation of your code. Usually this comes in the form of your source edition, as well as compiled editions for each environment you wish to support.

How do I define an Edition?

Practically, editions are specified in descending order of preference in the editions field of your package.json , with each edition being composed of the following fields:

  • a description field to describe the edition

  • a directory field for where the edition is located

  • a entry field for the default file inside the directory to be loaded

You can find the full technical specification here:

Example Editions Definition

For a project that has a source edition written in ESNext using require('some-package') syntax, with a compiled edition for the default browsers, as well as a compiled edition for older node versions, then a compatible editions definition for it would look like so:

package.json
{
  "editions": [
    {
      "description": "esnext source code with require for modules",
      "directory": "source",
      "entry": "index.js",
      "tags": [
        "javascript",
        "esnext",
        "require"
      ],
      "engines": {
        "node": ">=6",
        "browsers": false
      }
    },
    {
      "description": "esnext compiled for browsers with require for modules",
      "directory": "edition-browsers",
      "entry": "index.js",
      "tags": [
        "javascript",
        "require"
      ],
      "engines": {
        "node": false,
        "browsers": "defaults"
      }
    },
    {
      "description": "esnext compiled for node.js >=0.8 with require for modules",
      "directory": "edition-node-0.8",
      "entry": "index.js",
      "tags": [
        "javascript",
        "require"
      ],
      "engines": {
        "node": ">=0.8",
        "browsers": false
      }
    }
  ]
}

Automatic Creation of Editions

Consuming Editions

Editions can be consumed in multiple ways, here are the options:

A Specified Edition

For producers who only want one edition to be used by default, they can specify the default edition to be loaded via the standard main property of the package.json file:

package.json
{
  "main": "edition-node-0.8/index.js"
}

Best Edition for the Environment

  1. Inside your project, install the Editions Autoloader package via npm install --save editions

  2. Create a root index.js file that uses the Editions Autoloader to load the best edition from our available compatible editions.

    index.js
    'use strict'
    /** @type {typeof import("./source/index.js") } */
    module.exports = require('editions').requirePackage(__dirname, require)
  3. Set the package.json property main to point to the index.js file above, instead of a specfic edition.

    package.json
    {
      "main": "index.js"
    }

Custom Entry Points

For binary executables or testing, we then we would want to specify a non-default entry to load for the editions. We can do this by passing the custom entry point as an extra argument to the requirePackage function.

To specify a bin.js custom entry, then we would perform the following.

  1. Create a root bin.js file that uses the Editions Autoloader to load the best bin.js script from our available compatible editions.

    bin.js
    #!/usr/bin/env node
    'use strict'
    /** @type {typeof import("./source/bin.js") } */
    module.exports = require('editions').requirePackage(__dirname, require, 'bin.js')
  2. Set the bin property in our package.json file to point to the root bin.js file we just created.

    package.json
    {
      "bin": "bin.js"
    }

To specify a test.js custom entry, then we would perform the following.

  1. Create a root test.js file that uses the Editions Autoloader to load the best test.js script from our available compatible editions.

    bin.js
    'use strict'
    /** @type {typeof import("./source/test.js") } */
    module.exports = require('editions').requirePackage(__dirname, require, 'test.js')
  2. Set the scripts.test property in our package.json file to point to the root test.js file we just created.

    package.json
    {
      "scripts": {
        "test": "node ./test.js"
      }
    }

Manually Require a Specific Edition

// using require
require('a-editioned-package/a-custom-edition/')

// using import
import blah from 'a-editioned-package/a-custom-edition/'

Browser Edition

package.json
{
  "browser": "edition-browsers/index.js"
}

This usage of the browser field tells most tools like Browserify, WebPack, and Rollup to specifically use the edition that we precompiled for the browsers we target for.

You can find more information about the browser field and its equivalents here:

You can find tooling that already has builtin support for the Editions specification here:

Documenting Editions

Automatic Editions Rendering without the Editions Autoloader

package.json
{
  "main": "editions-node-0.8/index.js"
}

This will have Projectz turn the <!-- INSTALL --> comment in our README.md file into the following rendered output:

  • require('project') aliases require('project/edition-node-0.8')

Automatic Editions Documentation with the Editions Autoloader

However, these days, code may be run anywhere, in all sorts of browsers, desktop environments, and devices, of varying capabilities, not always known by the producer. JavaScript has also evolved, incorporating a lot of modern features that save developers time, but not supported across all possible environments - either requiring abstinence of time saving features, or eliminating environment support, or compilation on either the producer or consumer side - .

Editions comes in to solve this problem, elegantly, and , that works with current environments and development setups. Producers are able to produce their packages in their ideal configurations, then publish the package with multiple editions for the consumers to consume at their digression. Consumers are made aware of this through , and can - and by default, . All the complexity of modern JavaScript publishing is solved, for the consumer and publisher.

If you wish to delve further, refer to the document for a complete understanding of the problem space and why editions is a superior solution in it.

an optional tags field for to describe the edition that tooling can utilise

Tools like can automatically create for you the editions definition as well as the editions themselves.

For producers who want consumers to automatically load the best edition for the consumers particular environment, you can make use of the package.

For consumers who , they can opt into a non-standard edition by specifying it manually in their consumption.

For our , we would define the browser field in our package.json like so:

If producers wish to inform consumers of the editions they provide, which is not necessary for consumption, but useful to the consumer, then producers can utilise to inject the appropriate editions information into your README.md file via the HTML comment <!-- INSTALL --> .

If we partner our with the following package.json fields:

require('project/source') is source code with

require('project/edition-browsers') is compiled for browsers with

require('project/edition-node-0.8') is compiled for >=0.8 with

If we partner our to , then Projectz will turn the <!-- INSTALL --> comment in our README.md file into the following rendered output:

require('project') aliases require('project/index.js')which uses the to automatically select the correct edition for the consumers environment

require('project/source') is source code with

require('project/edition-browsers') is compiled for browsers with

require('project/edition-node-0.8') is compiled for >=0.8 with

this is all complex and difficult to manage
Alternative Approaches
Alternative Approaches
common keywords
Specification
Boundation
Editions Autoloader
Fields Comparison
Ecosystem
Projectz
Editions
ESNext
require for modules
ESNext
require for modules
ESNext
Node.js
require for modules
Editions
Editions Autoloader
ESNext
require for modules
ESNext
require for modules
ESNext
Node.js
require for modules
in a standardised way
automated README updates
select the exact edition that meets their exact needs
the best edition for the environment can be automatically loaded
are informed about the particular editions that an editioned package offers
Example Editions Definition from earlier
Example Editions Definition from earlier
Example Editions Definition from earlier
make use of the Editions Autoloader
Ecosystem Tooling
a backwards compatible standard
Watch the 2016 introductory talk to the Editions ecosystem.
GitHub - bevry/boundation: Automatic scaffolding and upgrading of your JavaScript ecosystem projects using Bevry's best practicesGitHub
Automatically create your Editions with Boundation
Logo