Skip to content

ES Numeric Separators broken by babel (Unexpected token: name (_000)) #645

Closed

Description

@westphalen

Do you want to request a feature or report a bug?
Bug / improvement for metro-react-native-babel-preset

What is the current behavior?

Error: Unexpected token: name (_000) in file App.tsx at 16:25

A build error that makes little sense in the context of a larger code base. The line:col isn't true to the original code, I had to console.log from within /metro/src/JSTransformer/worker.js to find the problematic line.

If the current behavior is a bug, please provide the steps to reproduce and a minimal repository on GitHub that we can yarn install and yarn test.

  • react-native init MyApp --template react-native-template-typescript
  • Use ES Numeric Separators syntax in your code, e.g. const thousand = 1_000;
  • Try to bundle the project for release

Minimal repository reproducing the issue:

  • git clone https://github.com/westphalen/metro-babel-preset-numeric-separators
  • yarn install
  • yarn build

What is the expected behavior?
Since the boilerplate project is set up to support TypeScript and es2017/esnext, one would expect that ES Numeric Separators were supported out of the box.

Solution
yarn install @babel/plugin-proposal-numeric-separator

Update babel.config.js with this line:

  plugins: ['@babel/plugin-proposal-numeric-separator'],

Would suggest this plugin is included by default in metro-react-native-babel-preset

Please provide your exact Metro configuration and mention your Metro, node, yarn/npm version and operating system.

  • macOS 10.15.7
  • node -v v10.22.0
  • "metro-react-native-babel-preset": "0.63.0"
  • metro "0.58.0"

Activity

  1. motiz88 commented on Mar 25, 2021

    @motiz88
    Contributor

    Hey @westphalen, would you be interested in sending a PR that adds @babel/plugin-proposal-numeric-separator to the preset?

  2. SConaway commented on Jun 28, 2021

    @SConaway
    Contributor

    @motiz88 after having a weird issue where numeric separators were only an issue when building for iOS without Hermes (it works fine in dev on iOS and on Android in dev and prod), i'd be willing to make a super-quick PR to do that. Would it be accepted?

    Should it go in https://github.com/facebook/metro/blob/master/packages/metro-react-native-babel-preset/src/passthrough-syntax-plugins.js or https://github.com/facebook/metro/blob/master/packages/metro-react-native-babel-preset/src/configs/main.js?

  3. motiz88 commented on Jul 1, 2021

    @motiz88
    Contributor

    @SConaway I'd happily review a PR that adds the numeric separator plugin to https://github.com/facebook/metro/blob/master/packages/metro-react-native-babel-preset/src/configs/main.js. We need to transform this syntax rather than just pass it through, because some of the engines we target don't natively support it. I guess that's what you may have seen on iOS, since JavaScriptCore only added support for this syntax in iOS 13 per https://caniuse.com/mdn-javascript_grammar_numeric_separators.

  4. SConaway commented on Jul 4, 2021

    @SConaway
    Contributor

    Ok cool! Working on getting my developer environment setup now.

    Is there are a reason why @babel/preset-env isn't used as a base plugin since it includes many of the ones that are currently in that file?

  5. motiz88 commented on Jul 6, 2021

    @motiz88
    Contributor

    @babel/preset-env differs in subtle ways from Metro's React Native preset. The latter accepts some different config options that are React Native-specific / Metro-specific; the former doesn't have a way to target Hermes specially (which is an experimental feature in Metro). Migrating to preset-env would be doable and probably beneficial to the ecosystem, but it's not trivial IMO.

  6. SConaway commented on Jul 6, 2021

    @SConaway
    Contributor

    Yes, fair. Let me know if there's anything else needed. I did update the list of included syntax transforms.

  7. cristianoccazinsp commented on Aug 11, 2021

    @cristianoccazinsp

    Any work around for libraries that use this syntax and need to be transformed in react-native?

  8. SConaway commented on Aug 11, 2021

    @SConaway
    Contributor

    Nope, my PR (#681) hasn’t been merged yet.

  9. hm-harshit commented on Nov 25, 2021

    @hm-harshit

    is there any update on this issue ?

  10. FelipeSSantos1 commented on Nov 25, 2021

    @FelipeSSantos1

    on metro.config.js I just included the babel plugin and it worked for me

    module.exports = {
      transformer: {
        getTransformOptions: async () => ({
          transform: {
            experimentalImportSupport: false,
            inlineRequires: true,
          },
        }),
        plugins: ['@babel/plugin-proposal-numeric-separator'],
      },
    }
  11. geraintwhite commented on Nov 29, 2021

    @geraintwhite

    @felipemillhouse this works for me in debug mode, but not when building a release build from Xcode. Have you experienced this?

    Error: Unexpected token: name (_28) in file node_modules/color/index.js at 240:30
        at minifyCode (/Users/jenny/workspace/Cloud_Voice_App_update-color/node_modules/metro-transform-worker/src/index.js:99:13)
        at transformJS (/Users/jenny/workspace/Cloud_Voice_App_update-color/node_modules/metro-transform-worker/src/index.js:317:28)
        at transformJSWithBabel (/Users/jenny/workspace/Cloud_Voice_App_update-color/node_modules/metro-transform-worker/src/index.js:408:16)
        at processTicksAndRejections (internal/process/task_queues.js:97:5)
        at Object.transform (/Users/jenny/workspace/Cloud_Voice_App_update-color/node_modules/metro-transform-worker/src/index.js:569:12)
    info Run CLI with --verbose flag for more details.
    

    Edit:

    It seems like this issue is caused by metro-minify-uglify using uglify-es which has been deprecated in favour of uglify-js.

    #661

  12. FelipeSSantos1 commented on Nov 29, 2021

    @FelipeSSantos1

    @grit96 For me it also works on release (archiving). I'm using "react-native": "0.66.1" and "color": "^4.0.1" BTW.

    Don't forget to yarn add @babel/plugin-proposal-numeric-separator -D

  13. geraintwhite commented on Nov 29, 2021

    @geraintwhite

    Very strange. I'm on "react-native": "0.66.3" and "color": "4.0.2". Works perfectly archiving once I add a custom minifier copied from here but replacing uglify-es with uglify-js.

    minifierPath: require.resolve('./config/minifier')

  14. mfbx9da4 commented on Dec 17, 2021

    @mfbx9da4
    Contributor

    For those wondering what may have caused this check your code for a number like 10_000 using the _ to separate numbers

  15. cristianoccazinsp commented on Feb 4, 2022

    @cristianoccazinsp

    Any thoughts on supporting this with metro? color maintainer refuses to do a simple "fix" to remove the underscore from numerical values.

  16. 2 remaining items

  17. cristianoccazinsp commented on Feb 11, 2022

    @cristianoccazinsp

    The maintainer is kind of stubborn, but hey, anyone is free to fork this and fix that 1 char issue.

  18. macrozone commented on Feb 11, 2022

    @macrozone

    The maintainer is kind of stubborn, but hey, anyone is free to fork this and fix that 1 char issue.

    actually a lot of people did ;-)

    It must be hard to have such a prominent name on github and npm and to have to deal with all those poor souls who have to use "old" bundlers ;-)

    but thats off-topic....

    i had the same issue with storybook and decided to remove the library, but i am curious if anyone knows the actual fix

  19. cristianoccazinsp commented on Feb 23, 2022

    @cristianoccazinsp

    @macrozone any drop-in replacement for it?

  20. Dean177 commented on Feb 23, 2022

    @Dean177

    @cristianoccazinsp scroll up a little to my reply 😉

  21. added a commit that references this issue on Apr 7, 2022
  22. JahChwen commented on May 24, 2022

    @JahChwen

    replace uglify-es with terser
    install metro-minify-terser and edit metro.config.js.

    // metro.config.js
    module.exports = {
      transformer: {
        minifierPath: 'metro-minify-terser',
      },
    }
  23. chriswiggins commented on Jun 2, 2022

    @chriswiggins

    I stumbled into this issue today too, doing the following sorted the issue for me (YMMV):

    npm install --save-dev @babel/plugin-proposal-numeric-separator

    In the root of your project, create the file babel.config.js and add the following. This just extends metro's preset, and includes the numeric-separator transform

    /**
     * Babel configuration override for React Native
     * Includes the @babel/plugin-proposal-numeric-separator plugin to fix _ numerical formatting
     *
     */
    
    module.exports = {
      plugins: ['@babel/plugin-proposal-numeric-separator'],
      presets: ["module:metro-react-native-babel-preset"]
    }
  24. Jorundur commented on Aug 25, 2022

    @Jorundur

    @chriswiggins Thanks, this fixed it for me! Simple solution.

  25. robhogan commented on Dec 20, 2022

    @robhogan
    Collaborator

    This should be fixed by the release of Metro 0.73, which is bundled with React Native 0.71.

    The root cause here is Metro's previous use of the uglify-es minifier, which can't parse numeric separators. I think numeric separators are supported by all of RN's runtime targets, we just needed a minifier that didn't choke on them.

    In Metro 0.67 we introduced support for async minifiers, and therefore Terser 5 (#606). In Metro 0.73 we made Terser the default minifier (#871).

    Using Terser with React Native 0.69.x and 0.70.x (Metro >= 0.67.0)

    If you have a Metro version >= 0.67.0 but can't yet upgrade to RN 0.71 (still in RC), you can switch to Terser by modifying your minifierPath in Metro config:

    Add metro-minify-terser to your project dependencies:

    yarn add metro-minify-terser

    Point Metro at it with minifierPath:

    // metro.config.js
    module.exports = {
      // ...
      transformer: {
        // ...
        minifierPath: require.resolve('metro-minify-terser')
      }
    }  

    For users on RN 0.68 or older, you can try the same config with yarn add metro-minify-terser@~0.66.2 (untested) - this will use Terser v4, which is synchronous and therefore should work with old Metro versions.

    Closing, but feel free to reopen if anyone is still running into issues on RN 0.71 or later.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions