lelandrichardson / react-primitives

Primitive React Interfaces Across Targets

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

react-primitives is not transpiling when bundling for react-native production

peterp opened this issue · comments

In my react-native project

node ./node_modules/react-native/local-cli/cli.js bundle --entry-file index.ios.js --platform ios --dev false --reset-cache --bundle-output /tmp/main.jsbundle --assets-dest /tmp/
**TypeError: /Users/peterp/Personal/xxx/node_modules/react-primitives/lib/modules/Platform.js: Property left of AssignmentExpression expected node to be of a type ["LVal"] but instead got "StringLiteral"**
transform[stderr]:     at Object.validate (/Users/peterp/Personal/xxx/node_modules/babel-types/lib/definitions/index.js:109:13)
transform[stderr]:     at Object.validate (/Users/peterp/Personal/xxx/node_modules/babel-types/lib/index.js:505:9)
transform[stderr]:     at NodePath._replaceWith (/Users/peterp/Personal/xxx/node_modules/babel-traverse/lib/path/replacement.js:176:7)
transform[stderr]:     at NodePath.replaceWith (/Users/peterp/Personal/xxx/node_modules/babel-traverse/lib/path/replacement.js:160:8)
transform[stderr]:     at PluginPass.MemberExpression (/Users/peterp/Personal/xxx/node_modules/metro-bundler/build/JSTransformer/worker/inline.js:126:14)

I've narrowed it down the assignment here: https://github.com/lelandrichardson/react-primitives/blob/master/src/modules/Platform.js#L13

I changed line 13-14 to

    Platform['OS'] = platform.OS;
    Platform['Version'] = platform.Version;

and it built successfully, this comment helped me figure it out. This seems like something that should be fixed in React Native's bundler, but I'm not sure?

We're having this issue too, but unfortunately the fix above doesn't seem to work for us.

We had to remove react-primitives from our project and instead use React Native versions from our project to get release builds to work on React Native. :-(

I'll watch this issue and we'll switch back as soon as we can!

@blargity I've created a very hacky release that you could test: npm install peterp/react-primitives.

It fixes the touchable and this bundling issue. I'm using this on react-native 0.46.3. If it does work, then please do not use this long term... It's a stopgap whilst I was trying to figure this out.

I'm fundamentally interested in sharing a design system between react-dom and react-native. It feels like we're so close!

That's ok, I'll keep an eye on this issue for an official fix. We'll be able to switch back really easily. Thanks though!

You can also alias react-native to react-native-web if you're having problems

@necolas that sounds interesting, how would one go about doing that?

commented

@peterp What fixes did you end up implementing? I can't find your repo and the 'string accessor' fix doesn't seem to work

Note, the string accessor fix works for me when applied to lib/modules/Platform.js (note lib, not src as linked by @peterp's original post. The index.js imports directly from lib.)

The issue is caused by Metro bundler inlining Platform.OS declaration during the JS transform phase, as described in these tests, so that Platform.OS = platform.OS; becomes "ios" = platform.OS, which is obviously an invalid expression.

If you want the change to be patched in permanently until this gets fixed, I can recommend patch-package.

  1. Install patch-package with npm install --dev patch-package.

  2. Add prepare npm script:

scripts: {
  //snip...
  "prepare": "patch-package"
}
  1. Replace the dot notation property access with brackets in lib/modules/Platform.js (and in src as well, if you want to be cool about it):
-    Platform.OS = platform.OS;
-    Platform.OS = platform.Version;
+    Platform['OS'] = platform.OS;
+    Platform['Version'] = platform.Version;
  1. Run patch-package to generate patch:
npm run prepare -- react-primitives
  1. Commit the created patches/ folder to source control.

The patch should now be applied every time you npm install or yarn

@peterp @lelandrichardson I know this is an issue that should really be fixed in metro-bundler, but for the time being (and for backwards compatibility for existing versions of Metro going forward) I think the fix should be upstreamed to react-primitives.

Is there a reason you didn't create a PR for this? I can go ahead and do that, just wanted to check if this is something you've already thought through and considered a bad idea?

@jevakallio I've already reported the issue to the metro-bundler team: facebook/metro#27

I agree that this could be fixed here, but I don't know if it would be merged, since the touchable and stylesheet pull-requests have been open for almost 2 months.

Certainly that isn't a good attitude to have on my part, but I needed a fix almost immediately and opted for alias approach instead of a injection package.

I submitted a PR for it in Metro, let's see how that goes facebook/metro#45

I think we can close this