Skip to content

Official, gradual path to RN packages not publishing untranspiled code #10966

@ljharb

Description

@ljharb

The current practice in the RN community for package authors is to publish untranspiled code, to npmignore babelrc, and for the RNP to transpile node_modules.

While this may work great for the RN community, this defies many best practices in the wider node/npm/JS community:

  • package.json's "main" only points to ES5 commonJS
  • npm explore foo && npm install && npm test should work (note this isn't universal, but it's frustrating to be asked to npmignore .babelrc and break this use case due to the RNP)

In addition, this practice kind of permanently cements RN packages with the transpiler settings that the RNP uses - which, since it includes not-yet-stage-4 features, are quite likely to change in a breaking way in the future.

Here's my proposal to enable the benefits of the current approach (cleaner stack traces, optimization opportunities within the RNP, etc) in a way that will allow RN packages to rejoin the wider JS ecosystem:

  1. Designate a new top-level package.json key - let's go with "sources" for the time being. This contains an object. All subkeys of "sources" are optional.
  2. Within "sources":
  3. "raw" points to the entry point for utterly untranspiled code. .babelrc (or other babel config locations), if provided, configure how this code should be transformed.
  4. "react-native-v1" (swap out v1 for any versioning scheme; this frees up the RNP to change their preferred transpiler settings freely.
  5. "node4", "node5", "node6", "node7", etc: code transpiled down to features matching the indicated major node version, following https://www.npmjs.com/package/babel-preset-node7, https://www.npmjs.com/package/babel-preset-node6, etc.
  6. "es2015", "es2016", etc: code transpiled down to features that are included in the given year of publication of the ecmascript standard.
  7. The RNP ships with support for this, with priority: ["react-native-", "node-" (>= the major node version, obv), "main" (with transpiling)]. This change is loudly communicated with blogs, tweets, and documentation.
  8. At some future point (this can be as soon, or as indefinite, as is deemed necessary), the RNP will cease transpiling "main" - since the other "sources" don't require looking for babel configs, this will be when RN packages can (and should) publish their .babelrcs again.

This approach allows for supporting other languages, future transpiler settings, etc, in a nonbreaking way, without infecting the npm ecosystem with untranspiled "main" entry points (inhibiting people's ability to share RN packages across normal react). A package will always be able to choose to omit "main" entirely, which will clearly and explicitly convey to users that their package must not be used without the RNP.

Further reading (credit @ide): https://gist.github.com/ide/e7b9181984933ebb0755c7367a32e7e8

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions