Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Babel 8 Release Plan #10746

Open
20 of 30 tasks
nicolo-ribaudo opened this issue Nov 21, 2019 · 45 comments
Open
20 of 30 tasks

Babel 8 Release Plan #10746

nicolo-ribaudo opened this issue Nov 21, 2019 · 45 comments

Comments

@nicolo-ribaudo
Copy link
Member

@nicolo-ribaudo nicolo-ribaudo commented Nov 21, 2019

We plan to release a new major version in 2021 (milestone).

This release won't have all the migration pain which there was while migrating from Babel 5 to Babel 6 and then from Babel 6 to Babel 7. We plan to only make a few breaking changes, and provide an easy migration strategy for each of them. Because of this, you won't see ~80 prereleases like we did in for Babel 7.0.0, but we plan to only release a few of them.

Babel 8.0.0 will only contain breaking changes: we will release a minor version the same day, containing all the bug fixes and new features that would otherwise be released in 8.0.0.

This document is still a work in progress, but you can already start by applying the suggested migration strategies to your own codebase.

  • Compilation breaking changes

    • Don't remove uninitialized class fields when using Flow/TS (pr for flow: #10120, pr for TS: #11114)

      • Area: Flow and TypeScript transforms

      • Impact: High (only for flow and TypeScript users)

      • Migration:
        You can use the new declare syntax, introduced in TypeScript 3.7 (Babel 7.7) and in Flow 0.120 (Babel 7.9), if you don't want fields to be initialized to undefined:

        class A {
          foo: string | void; // initialized to undefined
          declare bar: number; // type-only
        }

        Note that while this syntax is enabled by default in @babel/parser when using the typescript or flow plugins, if you are using Babel to remove type annotations you must enable the allowDeclareFields option:

        // TypeScript
        {
          presets: [
            ["@babel/typescript", { "allowDeclareFields": true }]
          ]
        }
        
        // Flow
        {
          presets: [
            ["@babel/flow", { "allowDeclareFields": true }]
          ]
        }
    • Disallow sequence expressions inside JSX attributes (pr: #8787)

      • Area: JSX, @babel/parser
      • Impact: Low
      • Migration: If you are using them, you can already wrap them in parentheses:
        <div key={foo, bar}></div> // Invalid
        <div key={(foo, bar)}></div> // Valid
    • Disallow } and > in JSX text (pr: #11046)

      • Area: @babel/parser with JSX
      • Impact: Low
      • Migration: You can use {'}'} and {'>'} instead.
      • Notes: This is technically a bug fix becase the specification already forbids them. However, we have chosen to postpone it until Babel 8 because it could break someone's code.
    • Transforms JSX spread properties using object spread (pr: #11141, docs: website#2289)

      • Area: JSX
      • Impact: Medium
      • Migration: You can already have this behavior by using the useSpread option in Babel 7.7.0. If your code needs to run in an environment which doesn't support object spread, you can either use @babel/preset-env (recommended) or @babel/plugin-proposal-object-rest-spread. If you want to transpile Object.assign down to Babel's _extends helper (which is the current default behavior) you also need to enable @babel/plugin-transform-object-assign.
    • Use the new JSX implementation by default (pr: #11436, docs: website#2289)

      • Area: JSX
      • Impact: High
      • Migration: Starting from Babel 7.9.0, you can pass the runtime: "classic" option to @babel/preset-react or @babel/plugin-transform-react-jsx to be explicit about your usage of createElement (or the equivalent function in other libraries).
        If you are using a modern enough version of React or Preact, you can already use the new runtime: "automatic" implementation.
    • Parse JSX elements when both the JSX and TS plugins are enabled, and throw an error when both Flow and TS are enabled (pr: #11316)

      • Area: JSX, TypeScript
      • Impact: Low
      • Migration: If you don't want <Foo> to be parsed as a JSX element, but as a TypeScript typecast, you can disable the JSX plugin.
      • Note: The current behavior is that JSX parsing is only handled by the isTSX option of the TypeScript plugin. We are also removing this option. We think that having the JSX plugin control JSX parsing is less confusing for our users.
    • Remove moduleAttributes support (pr: #13308)

      • Area: Import assertions ES proposal
      • Impact: Low
      • Migration: Replace @babel/plugin-syntax-module-attributes by @babel/plugin-syntax-import-assertions: you can already start doing this in Babel 7. After you replace the plugin, you should search the following patterns in your codebase
      import value from "module" with type: "json";

      and replace them by

      import value from "module" assert { type: "json" };

      If you are not using @babel/plugin-syntax-module-attributes, you don't need to do anything.

  • Configuration breaking changes

    • Require @babel/plugin-proposal-dynamic-import when transforming import() to SystemJS (#12700)
      • Area: @babel/plugin-transform-modules-systemjs
      • Impact: Medium
      • Migration: Add @babel/plugin-proposal-dynamic-import to your config: you can already do it in Babel 7. If you are using @babel/preset-env, you don't need to do anything.
      • Notes: All the other plugins which support dynamic import (transform-modules-commonjs and transform-modules-amd) require the separate plugin since it was introduced. We couldn't change it for transform-modules-systemjs because that package did already support dynamic import.
    • Use defaults, not ie 11 as default targets
      • Area: @babel/preset-env
      • Impact: Medium
      • Migration: If you are already using targets or have a .browserslist config file, this change won't affect you. Otherwise, you'll probably be fine with the new behavior (which supports these modern browsers). Note that the default targets does not include IE. If you still need to support IE, please specify IE 11 in targets. If you need to enable every possible plugin for even older browsers, you can already enable the forceAllTransforms option.
    • Remove uglify target (pr: #10895, docs: website#2290)
      • Area: @babel/preset-env
      • Impact: Low
      • Migration: The uglifyjs target had been deprecated since 7.0.0-beta.0, if you still need this, you can enable the forceAllTransforms option.
    • Move root AMD/UMD/SystemJS options to be plugin/preset options (pr: #11194, #12724)
      • Area: @babel/core, @babel/cli, @babel/plugin-transform-modules-amd, @babel/plugin-transform-modules-umd, @babel/plugin-transform-modules-systemjs
      • Impact: Medium
      • Migration: When upgrading to Babel 8, you'll move to modify your config and pass these options to the correct plugin or preset.
        If you are passing these options using the cli, you'll need to create a configuration file.
    • Drop support for core-js 2 (pr: #11751)
      • Area: @babel/preset-env, @babel/plugin-transform-runtime, @babel/compat-data
      • Impact: High
      • Migration: You can already change your config to use core-js@3. Don't forget to npm install it!
      • Notes:
        1. When useBuiltIns is enabled, the default core-js version is now 3.6 instead of 2
        2. If you still need core-js@2 support, you can use babel-plugin-polyfill-core-js2.
    • Add mandatory version option to the decorators plugins, and merge the two plugins in @babel/parser.
  • API breaking changes

  • AST breaking changes

    • Use an identifier for TSTypeParameter.name (#12829)
      • Area: @babel/parser
      • Impact: High for customized Babel plugin depending on TypeScript TSTypeParameter, e.g. the T in function f<T>() {}
      • Notes: For a TS type parameter node, node.name is a string in Babel 7 while in Babel 8 it is an Identifier
      • Migration: If you have a customized plugin accessing the name of a type parameter node, use node.name.name in Babel 8.
  • Misc breaking changes

    • Bump peer dependency on @babel/core to ^8.0.0
      • Area: Every package
      • Impact: None if you update every @babel/* package
    • ESM runtime helper files should have the .mjs extension
      • Area: @babel/runtime, @babel/runtime-corejs2, @babel/runtime-corejs3
      • Impact: Medium
      • Notes: ES Modules are now unflagged (nodejs/node#29866), and .js modules don't work with native import unless our package.json specifies type: "module" (which will break cjs helpers).
    • Change the format of CommonJS helpers in @babel/runtime
      • Area: @babel/runtime, @babel/runtime-corejs2, @babel/runtime-corejs3
      • Impact: Low
      • Notes: This will only affect you if you are using @babel/runtime 7.x with @babel/plugin-transform-runtime 8.x (or the other way around), which woudln't be supported anyway.
    • Disallow importing internal files of the different packages (pr: #10850)
      • Area: Every package
      • Impact: High
      • Notes: This will break at least vue-cli (cc @sodatea) and ember-cli-babel [2] (cc @rwjblue). We will provide targets-parser as a separate helper in v7.8.0.
        ⚠️ If anyone else is relying on internal Babel files, please let us know!
    • Output non-ASCII characters as-is in string literal (pr: #11384)
      • Area: @babel/generator
      • Impact: High only if you are manually calling the babel.transform API and your server is not serving js files in the utf8 encoding.
      • Notes: If you are using any one of @babel/cli, WebPack, Rollup, create-react-app or other Node.js powered bundlers, the transformed code is always encoded with utf-8. That said, this issue probably won't affect your app.
      • Mitigation: Ensure your server is always serving js files in the utf8 encoding. If you can not control the server output, use <script charset="utf-8" src="your-app.js"></script> in the html files. You may also restore to the Babel 7 behaviour by
        {
          generatorOpts: {
            jsescOption: {
              minimal: false
            }
          }
        }
    • Align Babel parser error codes between Flow and TypeScript (pr: #13294)
      • Area: @babel/parser
      • Impact: Low. It has an effect only if you handle the Babel parsing error when error.code is OptionalBindingPattern .
      • Mitigation The error.code for OptionalBindingPattern is renamed as PatternIsOptional.
  • Other possibly breaking changes

    • Remove ts type imports on Program:exit (pr: #10009, #12706)
      • Area: @babel/plugin-transform-typescript
      • Impact: Low
    • Allow skipped NodePaths to be requeued (pr: #13291)
      • Area: @babel/traverse
      • Impact: Low
      • Notes: This is actually a bugfix, but it causes an infinite loop in the tdz implementation of @babel/plugin-transform-block-scoping
    • Look for comments containing "Babel 8" in the source code
      • Area: Every package
      • Impact: Low
      • Notes: Most of those comments are just for internal dependencies between packages. Any significant change will have a dedicated point in this list of breaking changes.

Related: #10752


Note for contributors

~~We implement Babel 8 breaking changes under the BABEL_8_BREAKING env flag. To test the breaking changes, please duplicate the affected tests with the -babel-7 suffix and add BABEL_8_BREAKING: false to test options. The breaking changes will be merged to the main branch but stripped before publishing. ~~

@nicolo-ribaudo nicolo-ribaudo added this to the Babel 8.x milestone Nov 21, 2019
@JLHwung JLHwung pinned this issue Nov 21, 2019
@TrejGun
Copy link

@TrejGun TrejGun commented Nov 22, 2019

Remove ts type imports on Program:exit

will this allow to generate .d.ts files?

@nicolo-ribaudo
Copy link
Member Author

@nicolo-ribaudo nicolo-ribaudo commented Nov 29, 2019

@TrejGun It is totally unrelated I think. I'd be happy to hear more about it on our Slack!

@fwh1990
Copy link

@fwh1990 fwh1990 commented Dec 2, 2019

Will 8.x be faster than 7.x when building my own project?

@nicolo-ribaudo
Copy link
Member Author

@nicolo-ribaudo nicolo-ribaudo commented Dec 2, 2019

No. Version 8.0 will only contain breaking changes, so if there are any performance improvements that we can make they will also be included in 7.x.

@Andarist
Copy link
Member

@Andarist Andarist commented Dec 4, 2019

I would like to propose a breaking change.

I believe that @babel/runtime helpers should not get special treatment when transpiled to CJS - at least not for their export shape (used requires etc can still be optimized). I propose such output:

+"use strict";
+exports.__esModule = true;
+exports.default = _toPropertyKey;

-var _typeof = require("../helpers/typeof");
+var _typeof = require("../helpers/typeof").default;

-var toPrimitive = require("./toPrimitive");
+var toPrimitive = require("./toPrimitive").default;

function _toPropertyKey(arg) {
  var key = toPrimitive(arg, "string");
  return _typeof(key) === "symbol" ? key : String(key);
}

-module.exports = _toPropertyKey;

With such ESM-compatible output we could try to explore removing useESModules option from @babel/plugin-transform-runtime because it's possible to create a "proxy" package.json that would allow bundlers & node to pick up the correct version of a particular helper on their own using a single path (that would be inserted by transform runtime). The directory structure could look smth like this

helpers/toPropertyKey/package.json
helpers/toPropertyKey/toPropertyKey.js
helpers/toPropertyKey/toPropertyKey.mjs

with package.json being:

{
  "name": "@babel/runtime/helpers/toPropertyKey",
  "private": true,
  "type": "module",
  "main": "./toPropertyKey.cjs.js",
  "module": "./toPropertyKey.js",
  "exports": {
    ".": {
      "require": "./toPropertyKey.cjs.js",
      "default": "./toPropertyKey.js"
    }
  }
}

@XaveScor
Copy link

@XaveScor XaveScor commented Jan 12, 2020

@babel/preset-env using core-js@2 by default. Can @bable/preset-env@8 using core-js@3 only?

@nicolo-ribaudo
Copy link
Member Author

@nicolo-ribaudo nicolo-ribaudo commented Jan 12, 2020

Yeah, this is a good idea!
@zloirock WDYT about dropping support for core-js@2?

@zloirock
Copy link
Member

@zloirock zloirock commented Jan 12, 2020

Yes, core-js@2 support should be dropped and the version of core-js should be required argument with useBuiltIns in preset-env. Maybe it could be good also to enforce specifying of minor core-js version.

@zloirock
Copy link
Member

@zloirock zloirock commented Jan 12, 2020

Why it should be dropped - copy-paste from the draft of one post:

core-js@3 was published 10 months ago - I hoped that this is enough to update. However, core-js@2 still is used more often than core-js@3 - if some dependencies depend on core-js@2, users don't wanna have some copies of core-js in the bundle. However, we should kill core-js@2 ASAP. The main reason is even not some bugs, it's... V8 (de)optimizations - even if nothing is polyfilled. WTF? Now, if V8 saw the usage of some non-often used features (like @@species pattern), for example, in the features detection - V8 always will use the non-optimized version of a method that theoretically could use it. In core-js@2, that affects regexes, iterators, some array methods, typed arrays, promises, etc... Sometimes that causes ~100x performance degradation, let's say thanks to V8. At this moment, V8 is the most popular JS engine, so it's a complex of critical issues. Workarounds for a big part of those deoptimizations were added in core-js@3.0, for remaining - at the latest patch releases. I don't see any reason to spent many days fixing those (and other) issues in the obsolete version.

sodatea added a commit to sodatea/vue-cli that referenced this issue Feb 3, 2020
As planned in babel/babel#10746,
in babel 8 the old `loadPartialConfig` can't be used synchronously.
sodatea added a commit to sodatea/vue-cli that referenced this issue Feb 3, 2020
sodatea added a commit to vuejs/vue-cli that referenced this issue Feb 3, 2020
…abel 8 (#5133)

* refactor: use babel.loadPartialConfigSync (added in babel 7.8)

As planned in babel/babel#10746,
in babel 8 the old `loadPartialConfig` can't be used synchronously.

* refactor: remove dependence on internal babel files, preparing for babel 8

See
babel/babel#10746
babel/babel#10899
sebinsua added a commit to sebinsua/perspective that referenced this issue Feb 5, 2020
We should upgrade core-js@2 to core-js@3 because the (1) the next major
release of Babel will do so, and (2) there are many V8 de-optimizations
in core-js@2 that have been fixed in core-js@3.

See: babel/babel#10746 (comment)
See: babel/babel#10746 (comment)
See: https://github.com/zloirock/core-js/blob/master/docs/2019-03-19-core-js-3-babel-and-a-look-into-the-future.md

We also bumped Babel to 7.8.4 because it was only after 7.4 that
core-js@3 was supported.

See: https://babeljs.io/blog/2019/03/19/7.4.0#core-js-3-7646-https-githubcom-babel-babel-pull-7646
@Pranav2612000
Copy link

@Pranav2612000 Pranav2612000 commented Feb 6, 2020

Hey. I would love to contribute to Babel 8. What are some easy features I can work on? I think I can work on :-

Look for comments containing "Babel 8" in the source code
Area: Every package
Impact: Low
Notes: Most of those comments are just for internal dependencies between packages. Any significant change will have a dedicated point in this list of breaking changes.

Are there any other issues I can contribute to and help?

@nicolo-ribaudo
Copy link
Member Author

@nicolo-ribaudo nicolo-ribaudo commented Feb 6, 2020

Another good one could be #9546, which would give you the chance to dig into @babel/parser's internals.
Or maybe Disallow using babel.transform, babel.transformFile, babel.transformFromAst, babel.parse, babel.loadOptions and babel.loadPartialConfig synchronously, which is probably a bit easier.
If you prefer, Transforms JSX spread properties using object spread involves removing the useSpread option and making it the default behavior.

If you want to work on the TODOs left in the comments containing "Babel 8", please don't resolve all of them in a single PR but keep separate changes in different PRs.

@Pranav2612000
Copy link

@Pranav2612000 Pranav2612000 commented Feb 8, 2020

Disallow using babel.transform, babel.transformFile, babel.transformFromAst, babel.parse, babel.loadOptions and babel.loadPartialConfig synchronously
Area: @babel/core
Impact: Medium
Migration: You can use babel.transformSync, babel.transformFromAstSync and babel.transformFileSync, supported since version 7.0.0. babel.parseSync, babel.loadOptionsSync and babel.loadPartialConfigSync will be introduced in v7.8.0.

Shoud I just delete the given functions? Or am I misunderstanding the requirements?

@nicolo-ribaudo
Copy link
Member Author

@nicolo-ribaudo nicolo-ribaudo commented Feb 8, 2020

Currently they behave asynchronously if you pass them a callback, otherwise they behave synchronously. Only the callback-based version should be allowed.

mactanxin added a commit to mactanxin/vue-cli that referenced this issue Feb 11, 2020
…abel 8 (vuejs#5133)

* refactor: use babel.loadPartialConfigSync (added in babel 7.8)

As planned in babel/babel#10746,
in babel 8 the old `loadPartialConfig` can't be used synchronously.

* refactor: remove dependence on internal babel files, preparing for babel 8

See
babel/babel#10746
babel/babel#10899
@kaicataldo
Copy link
Member

@kaicataldo kaicataldo commented May 9, 2020

I’m beginning to rethink our plan to release the @babel/eslint-* packages with Babel 8. I believe we’re ready to release those packages now - any further necessary changes will become apparent with the myriad of integrations in the community. If we were to release these packages in the next v7 line release, we could start getting immediate feedback. One other possible benefit is that if we need to make any breaking changes we can get them out in the v8 release.

Thoughts?

@nicolo-ribaudo
Copy link
Member Author

@nicolo-ribaudo nicolo-ribaudo commented May 9, 2020

The next ESLint release has been in the prerelease state for too long. If it's already compatible with ESLint 7, I would be ok with releasing it in Babel 7.

@cpojer
Copy link
Member

@cpojer cpojer commented May 10, 2020

Question: could the official upgrade guide suggest how library authors can make their code compatible with both Babel 7 and 8, and then recommend them to use a semver range that works with either 7 or 8 until 7 is dropped at a later time?

I believe that could significantly reduce the gap in time when some tools are upgraded but others aren't.

@nicolo-ribaudo
Copy link
Member Author

@nicolo-ribaudo nicolo-ribaudo commented May 11, 2020

Yes!

  1. We will check which Babel 7 plugins in this repository work with @babel/core 8, and relax their semver ranges
  2. The @babel/core API (used by Babel integrations such as Jest, Parcel, the webpack and rollup plugins, etc) will work both with Babel 7 and Babel 8. There is a breaking change (#11110), but the alternative already works with Babel 7.
  3. If an open-source plugin author needs help to make their plugin work both with Babel 8 and Babel 7, I am happy to help on Slack (and probably also the rest of the team).

@cpojer
Copy link
Member

@cpojer cpojer commented May 11, 2020

Thanks for the reply @nicolo-ribaudo, that's really exciting as that will ease the transition 👍

@hzoo
Copy link
Member

@hzoo hzoo commented May 13, 2020

Was thinking through some ideas on how to make the migration easier (not for 1 project for the ecosystem) with @nicolo-ribaudo and @existentialism and I'll post an idea we had here: https://hackmd.io/lAEuzTXzQl6fAir01YgfkQ. (this is in addition to writing up a guide to migrate and codemods where possible)

Basically was thinking we could enable the breaking changes in a 7.x patch under an environmental flag, run like BABEL_8_BREAKING babel or with whatever integration so that any library/plugin can opt-into trying that locally and publish new versions ahead of us releasing anything. We would have to manage the if branches in the code and even tests + cleanup after but maybe that can help ease?

Other ideas welcome.

@cpojer
Copy link
Member

@cpojer cpojer commented May 13, 2020

@hzoo I think that's a great idea, thank you for thinking about this.

@Airkro
Copy link

@Airkro Airkro commented May 27, 2020

How about drop support for core-js 3 (in preset-env). We have babel-plugin-polyfill-corejs3 now.

@nicolo-ribaudo
Copy link
Member Author

@nicolo-ribaudo nicolo-ribaudo commented May 27, 2020

That was one of my goals when I started working on the polyfill packages, but we should first do babel/rfcs#2

@xiaoxiangmoe
Copy link

@xiaoxiangmoe xiaoxiangmoe commented Sep 20, 2020

When will babel 8 release?

@TrySound

This comment has been hidden.

@nicolo-ribaudo

This comment has been hidden.

@fabis94
Copy link

@fabis94 fabis94 commented Oct 14, 2020

Would be nice to know when we can expect Babel 8. The OP says that it'll come out in 2020, but the year is soon coming to a close and there's no news yet.

@WillBeebe
Copy link

@WillBeebe WillBeebe commented Oct 14, 2020

Who else is pumped for the chokidar dependency bump? :D

@nicolo-ribaudo
Copy link
Member Author

@nicolo-ribaudo nicolo-ribaudo commented Oct 14, 2020

@fabis94 Sorry for the lack of communication about a precise schedule. My hope is to release Babel 8 alongside with 7.13 (so in about 2 months), since there isn't much left to do. However, please don't take this as an hard deadline since anything could happen 🙏

@WillBeebe Starting from Babel 7.12.0, it will use chokidar@3 if you are using a modern Node.js version 😉 #11560

@fabis94
Copy link

@fabis94 fabis94 commented Dec 16, 2020

Any updates regarding this?

@nicolo-ribaudo
Copy link
Member Author

@nicolo-ribaudo nicolo-ribaudo commented Dec 16, 2020

Yes!
We wanted to work on this in a separate branch next-8-dev/next-8-rebased, but we found out that it was really slowing us down. We are now starting to add these Babel 8 changes to main, so that it's easier for us to work on them and hopefully will help us finish this release in a reasonable time.

@jridgewell
Copy link
Member

@jridgewell jridgewell commented Mar 17, 2021

One more thing that's always bugged me: we should rename OVERWRITE to TEST_OVERWRITE. It doesn't make sense to use make test-only TEST_ONLY=class-properties TEST_GREP=public OVERWRITE=true

@nicolo-ribaudo
Copy link
Member Author

@nicolo-ribaudo nicolo-ribaudo commented Mar 17, 2021

No need to wait for Babel 8, we can add an alias now.

@rnarkk
Copy link

@rnarkk rnarkk commented Jul 2, 2021

Would you mind updating the current progress of the task list? Some of them seem to have already been solved.

@Ontopic
Copy link

@Ontopic Ontopic commented Aug 18, 2021

Yes!
We wanted to work on this in a separate branch next-8-dev/next-8-rebased, but we found out that it was really slowing us down. We are now starting to add these Babel 8 changes to main, so that it's easier for us to work on them and hopefully will help us finish this release in a reasonable time.

So in order to play around with where things are at, will a @next or ^7.15 bring me the closest?

@JLHwung
Copy link
Contributor

@JLHwung JLHwung commented Aug 18, 2021

So in order to play around with where things are at, will a @next or ^7.15 bring me the closest?

7.15 has been published but it will not contain Babel 8 breaking changes, as required by semver. We don't have Babel 8 nightly build, but we have Babel 8 e2e test on popular libraries:

e2e-breaking-babel:
you can fork Babel repo and run e2e test on your own library to see if Babel 8 will break. Feedbacks are always welcome.

@Ontopic
Copy link

@Ontopic Ontopic commented Aug 18, 2021

Thanks! Long time since I last build Babel myself. Let's see the dev contributor experience nowadays :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet