Part of the point of the NG brainstorming is to see how we can make backward-incompatible changes to core.
One early proposal was to use ES6 modules as a "switch": const fs = require("fs") gives you the existing fs, and import fs from "fs" gives you "fs v2" with back-compat breakages. However, this suffers from the "this time we'll do it right!" fallacy, and assumes we won't ever want to break back-compat again. (Or at least, it doesn't have a strategy for doing so.)
I think a better approach would be to start versioning the core modules. The version numbers that are used in code would be a single number, i.e. 1 or 2, not 1.3.4; we only need to signal back-compat breakages, not additions or fixes. There are a variety of ways you could envision this working then:
require and import do the exact same thing, and "fs" is an alias for "fs@1"
require stays unchanged and can only ever require "fs"; import cannot import "fs", but can import "fs@1" or "fs@2" or...
(I think I like the second better; however, it does mean we block progress on this idea until ES6 modules ships in V8, and that could be a long time.)
Relatedly there comes the question of how we distribute these modules. Here is one scheme that I like:
- io.js ships with a set of core modules, as it does now. We just also make them accessible using versions like
"fs@1" in addition to the normal way.
- If we want to make a back-compat-breaking change to fs, we keep shipping fs@1 with no changes, but we also ship fs@2 with the change. When doing so, we do not increment the major io.js version, as no old code breaks! We can just increment the minor instead.
- If at some point we feel that we are shipping too many versions of core modules (maybe we are shipping 10 versions of fs now, or maybe we are shipping 2-3 versions of every core module), and we want to trim the fat, we can bump the io.js major version and remove old core module versions.
- (More tricky to get right) At all times, every version is distributed on npm (probably via automated publish process from core, assuming we like the single-repo structure). This means that people who want to use old versions that are no longer included in io.js can just add them to package.json. And sometimes it will allow people on older versions of io.js to use newer versions of core modules, but this is not guaranteed, since those newer versions might depend on e.g. new C++ APIs or other things.
Part of the point of the NG brainstorming is to see how we can make backward-incompatible changes to core.
One early proposal was to use ES6 modules as a "switch":
const fs = require("fs")gives you the existing fs, andimport fs from "fs"gives you "fs v2" with back-compat breakages. However, this suffers from the "this time we'll do it right!" fallacy, and assumes we won't ever want to break back-compat again. (Or at least, it doesn't have a strategy for doing so.)I think a better approach would be to start versioning the core modules. The version numbers that are used in code would be a single number, i.e. 1 or 2, not 1.3.4; we only need to signal back-compat breakages, not additions or fixes. There are a variety of ways you could envision this working then:
requireandimportdo the exact same thing, and"fs"is an alias for"fs@1"requirestays unchanged and can only ever require"fs";importcannot import"fs", but can import"fs@1"or"fs@2"or...(I think I like the second better; however, it does mean we block progress on this idea until ES6 modules ships in V8, and that could be a long time.)
Relatedly there comes the question of how we distribute these modules. Here is one scheme that I like:
"fs@1"in addition to the normal way.