guybedford / ecmascript-modules-mode

ECMAScript Modules esm boundary proposal for Node.js
0 stars 0 forks source link

Package type #2

Closed GeoffreyBooth closed 5 years ago

GeoffreyBooth commented 5 years ago

I think there’s something to be said for "mode" as a general type signifier, similar to the function served by a file extension. Just as .json tells you the type of a JSON file, but not how or with what to open it, something like "mode": "esm" is “pure” metadata that describes the type of the package rather than configuring Node how to process it.

Remember that NPM packages are used not just by Node; plenty of browser libraries are published to the NPM registry nowadays. A browser package type actually makes a lot of sense. A package with "mode": "browser" would not be importable by Node at all, either in CommonJS or in ESM modes, as this NPM package simply isn’t intended for Node to use. Perhaps a loader could register itself to handle "browser" packages, and supply things like a global window object and emulated DOM.

Another possible type could be meteor. The Meteor platform maintains a separate package registry, https://atmospherejs.com/, to hold Meteor packages since they’re not importable by Node (as they have separate entry points for client and server). A "mode": "meteor" could be a way to bring them into the fold. cc @benjamn.

Likewise, packages can be flagged so that they’re only ever imported by a build tool, whether the Meteor build tool or something like Babel. A package that intermixes CommonJS and ESM syntax in the same files, for example, could be "mode": "babel" to signify that Node should not be able to directly import it but that it needs to be used only as part of a Babel build chain (or with the Babel loader registered).

The list goes on. I think there’s utility in keeping file extension mappings and this “package type” concept separate, so that for example loaders can register to handle packages of certain types without being limited to sets of file extensions. Keeping the configuration short and sweet like "mode": "esm" or "type": "browser" allows flexibility in the future, as we can expand what’s covered by this property.

guybedford commented 5 years ago

I'm open to a "type" name here, provided we can check the data on the availability of that.

In terms of interoperability, I think a core goal of this flag is for it to be supported in all tools. For example, I would support it in jspm, @jdalton's esm would support it, etc etc. That wide adoption then allows tools to work together as opposed to building their own silos of the web, which should be our goal if we care about the open platform.

GeoffreyBooth commented 5 years ago

Per this there are only 27 packages in the NPM registry that have a type field in their package.jsons:

[ { name: 'patr', type: 'zip' },
  { name: 'webler', type: 'Copyright 2015 Rudá Robson' },
  { name: 'commonjs-utils', type: 'zip' },
  { name: 'commons', type: 'zip' },
  { name: 'cozy-hello', type: 'static' },
  { name: 'dinparser', type: 'git' },
  { name: 'edbase32', type: 'git' },
  { name: 'hoodie-accountbar', type: 'app' },
  { name: 'hoodie-react-fluxxor', type: 'app' },
  { name: 'hoodie-store-and-account-tutorial', type: 'app' },
  { name: 'hoodsoul', type: 'app' },
  { name: 'irclog', type: 'zip' },
  { name: 'my-first-hoodie', type: 'app' },
  { name: 'neta-olli', type: 'theme' },
  { name: 'node-ping-addon', type: 'MIT' },
  { name: 'node-pingit', type: 'MIT' },
  { name: 'node-simplewhois', type: 'zip' },
  { name: 'nodules', type: 'zip' },
  { name: 'react-google-charts', type: 'react-component' },
  { name: 'reformed-churches-locator', type: 'app' },
  { name: 'simplednsserver', type: 'git' },
  { name: 'simplewebssl', type: 'git' },
  { name: 'spm-plugin-recess', type: 'plugin' },
  { name: 'templify', type: 'zip' },
  { name: 'test-module-deadhorse', type: 'pit' },
  { name: 'transporter', type: 'zip' },
  { name: 'whomecontrolpi', type: 'git' } ]