🚇 The JavaScript bundler for React Native. https://facebook.github.io/metro
Go to file
Martín Bigio cc4ab48057 Unbreak packager on oss master
Summary: @​public
This was a hard one, bare with me on the full story of what happened.

We recently started writting additional JS scripts in ES6 for the cli. These code needs to be transformed by babel before we execute it as we don't run node with `--harmony`. To do so we removed the `only` attribute on the `babel-register`. Turns out this broke the packager on oss as if no `only` not `ignore` parameter is specified babel will ignore `node_modules`. Since on oss when a project is created `react-native-github` is located inside of `node_modules` we started getting syntax errors.

The fix is to include separately all the different paths we need to make sure babel transforms each of them. We cannot simply have a single `babel-core/register` as we need to include paths that belong both to oss and internal only. So, we need to have multiple `register` invocations. Since babel does not accumulate the `only` you send on every invocation we need to build a small wrapper to do so.

Reviewed By: @frantic

Differential Revision: D2522426

fb-gh-sync-id: 379a7bb169c7d5cb3002268742de269238bba766
2015-10-08 17:37:27 -07:00
react-packager Unbreak packager on oss master 2015-10-08 17:37:27 -07:00
README.md Fix packager docs 2015-10-01 20:10:13 +01:00
blacklist.js Fix more name collisions 2015-09-29 22:01:21 -07:00
checkNodeVersion.js Update the packager's version check message for Node 4.0 2015-10-03 11:49:21 -07:00
cpuProfilerMiddleware.js Factor out cpu profiler middleware into it's own file 2015-10-08 14:21:07 -07:00
debugger.html Have the chrome debugger run javascript within a web worker, to remove the global document. 2015-09-24 08:19:55 -07:00
debuggerWorker.js Have the chrome debugger run javascript within a web worker, to remove the global document. 2015-09-24 08:19:55 -07:00
formatBanner.js [io.js] Print a warning message if the user is not on io.js 2.x 2015-07-10 00:32:46 -08:00
getDevToolsMiddleware.js Unify oss and internal version of dev-tools middleware 2015-10-08 14:20:33 -07:00
getFlowTypeCheckMiddleware.js [react-native] Make flow warn on timeout instead of redbox 2015-08-24 19:51:14 -08:00
launchChromeDevTools.applescript [ReactNative] Don't activate Chrome when debugger is already open 2015-06-19 13:26:29 -08:00
launchEditor.js TextMate support for launchEditor 2015-09-23 19:28:44 -07:00
launchPackager.command #!/bin/bash => #!/usr/bin/env bash 2015-07-23 11:17:22 -08:00
loadRawBodyMiddleware.js Unify oss and internal version of base body loader middleware 2015-10-08 14:21:15 -07:00
openStackFrameInEditorMiddleware.js Unify oss and internal version of stack trace editor opener 2015-10-08 14:20:42 -07:00
package.json [io.js] Print a warning message if the user is not on io.js 2.x 2015-07-10 00:32:46 -08:00
packager.js Unify oss and internal version of base body loader middleware 2015-10-08 14:21:15 -07:00
packager.sh #!/bin/bash => #!/usr/bin/env bash 2015-07-23 11:17:22 -08:00
parseCommandLine.js Introduce react native CLI 2015-09-22 09:02:32 -07:00
statusPageMiddleware.js Unify oss and internal version of status page middleware 2015-10-08 14:20:50 -07:00
systraceProfileMiddleware.js Unify oss and internal version of systrace profiler middleware 2015-10-08 14:20:58 -07:00
transformer.js enable es6 module syntax 2015-10-01 10:57:23 -07:00
webSocketProxy.js Remove useless warning 2015-10-07 11:07:29 -07:00

README.md

React Native Packager

React Native Packager is a project similar in scope to browserify or webpack, it provides a CommonJS-like module system, JavaScript compilation (ES6, Flow, JSX), bundling, and asset loading.

The main difference is the Packager's focus on compilation and bundling speed. We aim for a sub-second edit-reload cycles. Additionally, we don't want users -- with large code bases -- to wait more than a few seconds after starting the packager.

The main deviation from the node module system is the support for our proprietary module format known as @providesModule. However, we discourage people to use this module format because going forward, we want to completely separate our infrastructure from React Native and provide an experience most JavaScript developers are familiar with, namely the node module format. We want to even go further, and let you choose your own packager and asset pipeline or even integrate into your existing infrastructure.

React Native users need not to understand how the packager work, however, this documentation might be useful for advanced users and people who want to fix bugs or add features to the packager (patches welcome!).

HTTP interface

The main way you'd interact with the packager is via the HTTP interface. The following is the list of endpoints and their respective functions.

/path/to/moduleName.bundle

Does the following in order:

  • parse out path/to/moduleName
  • add a .js suffix to the path
  • looks in your project root(s) for the file
  • recursively collects all the dependencies from an in memory graph
  • runs the modules through the transformer (might just be cached)
  • concatenate the modules' content into a bundle
  • responds to the client with the bundle (and a SourceMap URL)

/path/to/moduleName.map

  • if the package has been previously generated via the .bundle endpoint then the source map will be generated from that package
  • if the package has not been previously asked for, this will go through the same steps outlined in the .bundle endpoint then generate the source map.

Note that source map generation currently assumes that the code has been compiled with jstransform, which preserves line and column numbers which allows us to generate source maps super fast.

/path/to/moduleName.(map|bundle) query params

You can pass options for the bundle creation through the query params, if the option is boolean 1/0 or true/false is accepted.

Here are the current options the packager accepts:

  • dev boolean, defaults to true: sets a global __DEV__ variable which will effect how the React Native core libraries behave.
  • minify boolean, defaults to false: whether to minify the bundle.
  • runModule boolean, defaults to true: whether to require your entry point module. So if you requested moduleName, this option will add a require('moduleName') the end of your bundle.
  • inlineSourceMap boolean, defaults to false: whether to inline source maps.

/debug

This is a page used for debugging, it has links to two pages:

  • Cached Packages: which shows you the packages that's been already generated and cached
  • Dependency Graph: is the in-memory graph of all the modules and their dependencies

Programmatic API

The packager is made of two things:

  • The core packager (which we're calling ReactPackager)
  • The scripts, devtools launcher, server run etc.

ReactPackager is how you mainly interact with the API.

var ReactPackager = require('./react-packager');

ReactPackager.middleware(options)

Returns a function that can be used in a connect-like middleware. Takes the following options:

  • projectRoots array (required): Is the roots where your JavaScript file will exist
  • blacklistRE regexp: Is a patter to ignore certain paths from the packager
  • polyfillModuleName array: Paths to polyfills you want to be included at the start of the bundle
  • cacheVersion string: used in creating the cache file
  • resetCache boolean, defaults to false: whether to use the cache on disk
  • transformModulePath string: Path to the module used as a JavaScript transformer
  • nonPersistent boolean, defaults to false: Whether the server should be used as a persistent deamon to watch files and update itself
  • assetRoots array: Where should the packager look for assets

ReactPackager.buildPackageFromUrl(options, url)

Build a package from a url (see the .bundle endpoint). options is the same options that is passed to ReactPackager.middleware

ReactPackager.getDependencies(options, main)

Given an entry point module. Recursively collect all the dependent modules and return it as an array. options is the same options that is passed to ReactPackager.middleware

Debugging

To get verbose output when running the packager, define an environment variable:

export DEBUG=ReactNativePackager:*

You can combine this with other values, e.g. DEBUG=babel,ReactNativePackager:*. Under the hood this uses the debug package, see its documentation for all the available options.

The /debug endpoint discussed above is also useful.

FAQ

Can I use this in my own non-React Native project?

Yes. It's not really tied to React Native, however feature development is informed by React Native needs.

Why didn't you use webpack?

We love webpack, however, when we tried on our codebase it was slower than our developers would like it to be. You find can more discussion about the subject here