pnpm: Not working with CRNA

I tried it in the previous release too & also in this release but the only reason I can’t use PNPM is because it doesn’t work using CRNA.

Now its giving error - Cannot find module 'babel-plugin-transform-flow-strip-types'

Steps to repro -

create-react-native-app myApp
rm -rf node_modules && rm yarn.lock
pnpm i
pnpm start

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 23 (20 by maintainers)

Most upvoted comments

So I got react-native working with pnpm. https://github.com/pnpm/pnpm/issues/1051#issuecomment-372753512

I will take a look at getting it working for CRNA soon.

@deadcoder0904 --shamefully-flatten would help with the missing deps, yes, but this is easy and safer to fix in the pnpmfile.

But the main challenge was patching metro. And patching it in multiple versions because Expo uses an older version of react-native.

Updated pnpmfile.js that works for me.

'use strict'
module.exports = {
  hooks: {
    readPackage,
  },
}

function readPackage(pkg) {
  if (pkg.name === 'metro-core') {
    Object.assign(pkg.dependencies, {
      wordwrap: '*',
    })
  }
  if (pkg.name === 'metro') {
    Object.assign(pkg.dependencies, {
      'babel-plugin-transform-flow-strip-types': '6',
      'babel-plugin-transform-object-rest-spread': '6',
      'babel-plugin-transform-class-properties': '6',
      'babel-plugin-transform-async-to-generator': '6',
      'babel-plugin-syntax-trailing-function-commas': '6',
      xtend: '*',
      errno: '*',
    })
  }
  return pkg
}

I still couldn’t get it to work. There are some more issues related to react-native not supporting symlinks. See https://github.com/facebook/react-native/issues/18156

Here is a more automated way to work with CRNA.

I will be removing the babel-register dependency tomorrow.

pnpmfile.js

require('babel-register')
module.exports = require('./pnpmfile/index')

pnpmfile/package.json

{
  "name": "pnpmfile",
  "version": "0.0.1",
  "devDependencies": {
    "@pnpmfile/create-react-native-app": "^0.0.2-0"
  },
  "dependencies": {
    "babel-preset-env": "^1.6.1"
  }
}

pnpmfile/index.js

export default {
  hooks: {
    readPackage,
  },
}

function readPackage(pkg) {
  //require('pnpmfile-check').default(pkg)
  console.log({pkg})
  require('@pnpmfile/create-react-native-app').default(pkg)
  if (pkg.name === 'photo-booth-ios-crna') {
    console.log(pkg.dependencies)
  }
  return pkg
}

package.json

{ 
  dependencies: {
    'pnpmfile': '*',
    'babel-register: '^6'
  }
}

You must run the following to ensure that pnpmfile deps are installed first.

pnpm recursive install

Got CRNA working with pnpmfile.js. Was a bit tricky because expo hides errors from the react-native packager and it uses an older version of react-native which I had to create a custom patch of metro.

Will tidy this up later.

'use strict'
module.exports = {
  hooks: {
    readPackage,
  },
}

// NOTE: To see crna packager errors you must add `console.log(JSON.stringify(msg, null, 2))` to `this._handlePackagerEvent` here:
//   photo-booth-ios-crna/node_modules/.registry.npmjs.org/xdl/48.0.2/node_modules/xdl/build/logs/PackagerLogsStream.js

// NOTE: Test changes with `pnpm up`.
// NOTE: For `console.log` to appear correctly use: `pnpm up --reporter=append-only`.

function readPackage(pkg) {
  require('pnpmfile-check').default(pkg)

  // `metro` pnpm support.
  // TODO(vjpr): Use semver instead to test metro version.
  if (pkg.name === 'react-native' && pkg.version === '0.52.0') {
    Object.assign(pkg.dependencies, {
      'metro': 'npm:metro-pnpm@0.24.7-vjpr.1',
      //'metro-resolver': '~/dev-live/metro/.dev/metro-resolver-0.28.0.tgz',
      'uuid': '*', // Libraries/Blob/Blob.js
    })
  }
  if (pkg.name === 'react-native-scripts') {
    Object.assign(pkg.dependencies, {
      expo: '*',
    })
  }

  if (pkg.name === 'metro-core') {
    console.log('adding wordwrap to metro-core')
    Object.assign(pkg.dependencies, {
      wordwrap: '*',
    })
  }
  // expo/src/Notifications.js
  if (pkg.name === 'expo') {
    Object.assign(pkg.dependencies, {
      fbjs: '^0.8.16',
      lodash: '*',
      'json-schema-traverse': '*',
    })
  }

  // 1.0.0-alpha.39
  if (pkg.name === 'react-native-gesture-handler') {
    Object.assign(pkg.dependencies, {
      fbjs: '^0.8.16',
    })
  }

  // @expo/vector-icons@6.3.1
  if (pkg.name === '@expo/vector-icons') {
    Object.assign(pkg.dependencies, {
      'prop-types': '*',
    })
  }

  if (pkg.name === 'metro-pnpm') {
    Object.assign(pkg.dependencies, {
      'babel-plugin-transform-flow-strip-types': '6',
      'babel-plugin-transform-object-rest-spread': '6',
      'babel-plugin-transform-class-properties': '6',
      'babel-plugin-transform-async-to-generator': '6',
      'babel-plugin-syntax-trailing-function-commas': '6',
      'babel-template': '6',
      resolve: '*',
      xtend: '*',
      errno: '*',
    })
  }

  /*
  pnpm ls babel-preset-expo

  ├─┬ expo@25.0.0
  │ └── babel-preset-expo@4.0.0
  └─┬ react-native-scripts@1.11.1
    └─┬ expo@25.0.0
      └── babel-preset-expo@4.0.0
  */
  const pjson = require('./package.json')
  if (pkg.name === pjson.name) {
    Object.assign(pkg.dependencies, {
      'babel-preset-expo': '^4',
      'babel-plugin-transform-react-jsx-source': '6',
    })
  }
  return pkg
}

@deadcoder0904 I just checked. It is an issue with metro-bundler. It uses a bunch of packages that are not declared in its package.json. They should fix it.

With a pnpm hook, I added the missing dependencies to its manifest and it worked.

pnpmfile.js:

'use strict'
module.exports = {
  hooks: {
    readPackage
  }
}

function readPackage (pkg) {
  if (pkg.name === 'metro-bundler') {
    Object.assign(pkg.dependencies, {
      'babel-plugin-transform-flow-strip-types': '6',
      'babel-plugin-transform-object-rest-spread': '6',
      'babel-plugin-transform-class-properties': '6',
      'babel-plugin-transform-async-to-generator': '6',
      'babel-plugin-syntax-trailing-function-commas': '6',
      'xtend': '*',
      'errno': '*',
    })
  }
  return pkg
}

Part 1 - Getting expo-cli working with pnpm: https://github.com/expo/expo-cli/issues/183

Will track progress here: https://github.com/pnpm/pnpm/issues/1501