GithubHelp home page GithubHelp logo

facebook / metro Goto Github PK

View Code? Open in Web Editor NEW
4.7K 99.0 616.0 34.48 MB

🚇 The JavaScript bundler for React Native.

Home Page: https://facebook.github.io/metro

License: MIT License

JavaScript 99.76% TypeScript 0.02% CSS 0.03% SCSS 0.17% Shell 0.02%
javascript react-native bundler

metro's Introduction

Metro

MIT licensed npm package version Build status Code coverage Follow @MetroBundler on Twitter

🚇 The JavaScript bundler for React Native.

  • 🚅 Fast: We aim for sub-second reload cycles, fast startup and quick bundling speeds.
  • ⚖️ Scalable: Works with thousands of modules in a single application.
  • ⚛️ Integrated: Supports every React Native project out of the box.

Installation

Metro is included with React Native — see the React Native docs to quickly get started ⏱️.

To add Metro to an existing project, see our Getting Started guide.

Documentation

All available documentation, including on configuring Metro, can be found on the Metro website.

Source code for documentation is located in this repository under docs/.

Contributing

Metro was previously part of the react-native repository. In this standalone repository it is easier for the team working on Metro to respond to issues and pull requests. See react-native#13976 for the initial announcement.

Code of Conduct

Meta has adopted a Code of Conduct that we expect project participants to adhere to. Please read the full text so that you can understand what actions will and will not be tolerated.

Contributing guide

Read our contributing guide to learn about our development process, how to propose bug fixes and improvements, and how to build and test your changes to Metro.

Discussions

Larger discussions and proposals concerning React Native and Metro are discussed in @react-native-community/discussions-and-proposals.

License

Metro is MIT licensed, as found in the LICENSE file.

metro's People

Contributors

cpojer avatar davidaurelio avatar dependabot[bot] avatar evanyeung avatar frantic avatar gabelevi avatar gaearon avatar gkz avatar huntie avatar huxpro avatar ide avatar jacdebug avatar janicduplessis avatar javache avatar martinbigio avatar mirtleonard avatar motiz88 avatar mroch avatar pieterv avatar rafeca avatar rickhanlonii avatar robhogan avatar rubennorte avatar sahrens avatar samchou19815 avatar samwgoldman avatar sophiebits avatar tadeuzagallo avatar vjeux avatar yungsters avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

metro's Issues

[7c69e83] broke remote debugging on React Native

https://github.com/facebook/metro-bundler/blob/dbb2d44c42e23a83c1b9f51a577afa003f34e6b0/packages/metro-bundler/src/Server/index.js#L529

The change to the case of _processDebugRequest to _processdebugRequest seems to cause debuggerWorker.js of React Native to be incorrectly processed.

Symptoms include the appearance of <!doctype html><div><a href="/debug/bundles">Cached Bundles</a></div> in the middle of the downloaded debuggerWorker.js in VS Code.

Cross-referencing the following issues that are a manifestation of this.
microsoft/vscode-react-native#580
microsoft/vscode#37734

Causes the following error:

SyntaxError: Unexpected token <
vm.js:74
    at createScript (vm.js:74:10)
    at Object.runInThisContext (vm.js:116:10)
    at Module._compile (module.js:537:28)
    at Object.Module._extensions..js (module.js:584:10)
    at Module.load (module.js:507:32)
    at tryModuleLoad (module.js:470:12)
    at Function.Module._load (module.js:462:3)
    at Function.Module.runMain (module.js:609:10)
    at startup (bootstrap_node.js:158:16)
    at bootstrap_node.js:598:3

The < above corresponds to the opening of <!doctype html>.

Passing path to .babelrc as a packager option (programmatic and CLI)

In the transformer there's this comment referring to the .babelrc lookup:

// In the future let's look into adding a command line option to specify
// this location.

https://github.com/facebook/metro-bundler/blob/master/packages/metro-bundler/src/transformer.js#L54

At Expo we use a different .babelrc internally (for monorepo reasons) than in our OSS repos so being able to specify a different .babelrc without having to fork the default transformer is helpful. I was going to work on a PR for this, is this still a feature you'd want? I was thinking it'd probably be a CLI option like --babelrc and programmatic option like babelRCPath that gets passed through to the transformer.

Switching minifiers to uglify-es

Do you want to request a feature or report a bug?
Feature

What is the current behavior?
Metro uses uglify v2 for minification. uglify v3 is now out as well as uglify-es, which has the same function signatures as uglify v3 but can consume ES6+, which becomes relevant as JS VMs get upgraded (e.g. people targeting iOS 10+ may want to use a custom .babelrc).

uglify v3 doesn't have a lot of breaking changes, and I believe they don't affect RN, so this should be mostly a matter of updating how uglify is called from Metro, testing minification speed, and looking at bundle size.

Please provide your exact metro-bundler configuration and mention your metro-bundler, node, yarn/npm version and operating system.
Metro 0.11.x

An API to customize environment-specific polyfills

We'd like to be able to exclude some of the built-in polyfills depending on the platform (and ideally other options as well, such as environment variables). The basic use case is to include different polyfills on Android and iOS. An advanced use cases is to include different polyfills for different versions of iOS.

Since the packager already builds a different dependency graph for each platform, the basic use case probably needs very little refactoring to support. This is a proposal:

API proposal

The user can optionally give Metro a function that customizes the list of polyfills when building the dependency graph. The function receives the default list of polyfill paths (ex: Object.es6.js) and the current platform, and must return a new list of polyfill paths.

function customizePolyfills(defaultPolyfillPaths: string[], platform: string): string[] {
  // Do whatever you want to customize the list of polyfills. Generally you want to remove
  // or add to the default array. Return defaultPolyfillPaths without touching it to be a no-op.
}

Implementation proposal

The Resolver class at src/Resolver/index.js defines an instance method called _getPolyfillDependencies. The resolver knows which platform it is building the dependency graph for in getDependencies here. _getPolyfillDependencies would get the default list of polyfills and then pass it into the function proposed above and use the returned array.

This proposal doesn't handle the advanced use case (ex: customizing the polyfill list based on an environment variable) but it seems straightforward for the basic use case. What do you think? Is there a simpler or more general approach to customizing the polyfills or dependency graph?

Follow symlinks?

Do you want to request a feature or report a bug?

Feature

What is the current behavior?

I'm removing a test from DependencyGraph-test that looked like so, but wasn't actually working after I fixed problems with the fs mocks:

    it('should work with packages with symlinked subdirs', function() {
      var root = '/root';
      setMockFileSystem({
        'symlinkedPackage': {
          'package.json': JSON.stringify({
            name: 'aPackage',
            main: 'main.js',
          }),
          'main.js': 'lol',
          'subdir': {
            'lolynot.js': 'lolynot',
          },
        },
        'root': {
          'index.js': [
            '/**',
            ' * @providesModule index',
            ' */',
            'require("aPackage/subdir/lolynot")',
          ].join('\n'),
          'aPackage': { SYMLINK: '/symlinkedPackage' },
        },
      });

      var dgraph = new DependencyGraph({
        ...defaults,
        roots: [root],
      });
      return getOrderedDependenciesAsJSON(dgraph, '/root/index.js').then(function(deps) {
        expect(deps)
          .toEqual([
            {
              id: 'index',
              path: '/root/index.js',
              dependencies: ['aPackage/subdir/lolynot'],
              isAsset: false,
              isJSON: false,
              isPolyfill: false,
              resolution: undefined,
              resolveDependency: undefined,
            },
            {
              id: 'aPackage/subdir/lolynot.js',
              path: '/root/aPackage/subdir/lolynot.js',
              dependencies: [],
              isAsset: false,
              isJSON: false,
              isPolyfill: false,
              resolution: undefined,
              resolveDependency: undefined,
            },
          ]);
      });
    });

What is the expected behavior?

Reintroduce the test and verify symlinks work.

[RN 0.49] `React` inside app's local package either "doesn't exist", or "multiple copies loaded"

Do you want to request a feature or report a bug?

Bug. I'm not sure if I should file this with React Native instead/in addition, but since the errors I encounter since upgrading from RN 0.48 to 0.49 are all bundling errors in cli, here it is.

What is the current behavior?

From yarn outdated of my local package:

react-native-webview-bridge       0.33.0        exotic        exotic dependencies ../react-native-webview-bridge-RN0.40

With RN up to 0.48, my app's inclusion and import of react-native-webview-bridge like above works without issue. The package has no dependency itself of react.

Since upgrading to RN 0.49.3, this bundling error occurs on running react-native run-ios:

Unable to resolve module `react` from [package index]: Module does not exist in the module map

screenshot 2017-10-10 17 11 21

Then I added react as a dependency in package.json, like so:

  "devDependencies": {
    "react": "16.0.0-beta.5"
  },

Bundler will then error on Invariant violation: ... You may have multiple copies of React loaded.

screenshot 2017-10-10 17 21 23

screenshot 2017-10-10 17 21 37

A bit of a damned if I do, damned if I don't on getting react dependency in inside the package? Either none found, or there's 2 copies.

I made a hack fix as workaround around both errors, by replacing all instances inside the package of

var React = require('react');

with

var React = require('[HOMEDIR]/Documents/code/[PROJECT]/node_modules/react');

I hardcoded the react path to the exact copy of react my main app (PROJECT) imports, which avoids not able to resolve module react. I have to alter a sub module inside the package too: react-native-webview-bridge-RN0.40/node_modules/create-react-class/index.js which imports React, which makes this doubly hacky and prone to overwritten.

If there's a less dirty workaround, I'm all ears.

What is the expected behavior?

react not needed as a dependency in a local package (my fork of https://github.com/alinz/react-native-webview-bridge), nor is my hack fix needed to import directly from main app's node_modules/, and bundling goes through without error when react-native run-ios is run.

$ react-native info

Environment:
  OS:  macOS Sierra 10.12.6
  Node:  8.6.0
  Yarn:  1.2.0
  npm:  5.3.0
  Watchman:  4.9.0
  Xcode:  Xcode 9.0 Build version 9A235
  Android Studio:  Not Found

Packages: (wanted => installed)
  react: 16.0.0-beta.5 => 16.0.0-beta.5
  react-native: 0.49.3 => 0.49.3

[Feature] HMR with multiple clients

What is the current behavior?

  1. Create a new react-native project either with react-native-cli or create-react-native-app
  2. Open app on simulator
  3. Open app on device
  4. Disable live reloading and enable hot reloading on both of them
  5. Make changes
  6. Only the most recently connected client will update

What is the expected behavior?

Both clients should hot reload

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

Default react-native configuration for 0.45 (react-native-cli) and 0.44 (create-react-native-app). This is a longstanding issue that as far as I know has been present since the inception of HMR in react-native. Yarn 0.24., macOS 10.12.4

Getting "require() must have a single string literal argument" when bundling moment.js

Do you want to request a feature or report a bug?

Bug

What is the current behavior?

When attempting to package a project which makes use of the https://github.com/moment/moment.js library, the packager crashes with the error require() must have a single string literal argument

The library line in question is: https://github.com/moment/moment/blob/develop/moment.js#L1830 which appears to be perfectly javascript code.

This behavior does not seem to happen when I build the bundle with RN 0.48.4, however that particular build has issues when running on an phone running Oreo.

I can work around this issue by disabling the error in question by adding a return statement before this line: https://github.com/facebook/metro-bundler/blob/master/packages/metro-bundler/src/JSTransformer/worker/extract-dependencies.js#L39

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.

I am working on a repo to reproduce this behavior, however my time is limited due to pressing issues that need to be addressed within the next week so I have not been able to get a proper minimalist reproduction of this behavior.

I will update this issue with a link once I can get a good example.

What is the expected behavior?

There should not be any errors when packaging the JS bundle with the above library

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

RN: 0.49.0-rc.5
metro-bundler: 0.13.0
OS: Arch Linux
Mobile OS: Android 8.0.0

Add an option to change the import resolve algorithm

Feature request
When import from "component/foo" and the path "component/foo" is resolved to a directory, Metro-bundler could try to look for component/foo/foo.js as the entry. For example, this feature is implemented in directory-named-webpack-plugin for Webpack.

Packager fails: Unknown plugin "transform-runtime"

I originally posted on react-native as facebook/react-native/issues/14530, but realized it's more appropriate here. Guidance on how to decide where to post bugs would be appreciated!

Create a fresh app with: react-native init rn46 --version "0.46.0-rc.2", then CMD+R in Xcode which attempts to fire up the packager, but immediately bombs with:

ReferenceError: Unknown plugin "transform-runtime" specified in "/rn46/node_modules/regenerator-transform/package.json" at 0, attempted to resolve relative to "/rn46/node_modules/regenerator-transform" (While processing preset: "/rn46/node_modules/babel-preset-react-native/index.js")
    at /rn46/node_modules/babel-core/lib/transformation/file/options/option-manager.js:180:17
    at Array.map (native)
    at Function.normalisePlugins (/rn46/node_modules/babel-core/lib/transformation/file/options/option-manager.js:158:20)
    at OptionManager.mergeOptions (/rn46/node_modules/babel-core/lib/transformation/file/options/option-manager.js:234:36)
    at OptionManager.init (/rn46/node_modules/babel-core/lib/transformation/file/options/option-manager.js:368:12)
    at compile (/rn46/node_modules/babel-register/lib/node.js:103:45)
    at loader (/rn46/node_modules/babel-register/lib/node.js:144:14)
    at Object.require.extensions.(anonymous function) [as .js] (/rn46/node_modules/babel-register/lib/node.js:154:7)
    at Module.load (module.js:488:32)
    at tryModuleLoad (module.js:447:12)

Since it's a reference error, I add the dependency npm i babel-plugin-transform-runtime --save-dev and rerun, which now bombs with:

Error: Couldn't find preset "env" relative to directory "/rn46/node_modules/regenerator-transform" (While processing preset: "/rn46/node_modules/babel-preset-react-native/index.js")
    at /rn46/node_modules/babel-core/lib/transformation/file/options/option-manager.js:293:19
    at Array.map (native)
    at OptionManager.resolvePresets (/rn46/node_modules/babel-core/lib/transformation/file/options/option-manager.js:275:20)
    at OptionManager.mergePresets (/rn46/node_modules/babel-core/lib/transformation/file/options/option-manager.js:264:10)
    at OptionManager.mergeOptions (/rn46/node_modules/babel-core/lib/transformation/file/options/option-manager.js:249:14)
    at OptionManager.init (/rn46/node_modules/babel-core/lib/transformation/file/options/option-manager.js:368:12)
    at compile (/rn46/node_modules/babel-register/lib/node.js:103:45)
    at loader (/rn46/node_modules/babel-register/lib/node.js:144:14)
    at Object.require.extensions.(anonymous function) [as .js] (/rn46/node_modules/babel-register/lib/node.js:154:7)
    at Module.load (module.js:488:32)

Okay, let's now try npm i --save-dev babel-preset-env, which bombs with:

Error: Options {"loose":true} passed to /rn46/node_modules/babel-preset-env/lib/index.js which does not accept options. (While processing preset: "/rn46/node_modules/babel-preset-env/lib/index.js") (While processing preset: "/rn46/node_modules/babel-preset-env/lib/index.js") (While processing preset: "/rn46/node_modules/babel-preset-react-native/index.js")
    at /rn46/node_modules/babel-core/lib/transformation/file/options/option-manager.js:314:17
    at Array.map (native)
    at OptionManager.resolvePresets (/rn46/node_modules/babel-core/lib/transformation/file/options/option-manager.js:275:20)
    at OptionManager.mergePresets (/rn46/node_modules/babel-core/lib/transformation/file/options/option-manager.js:264:10)
    at OptionManager.mergeOptions (/rn46/node_modules/babel-core/lib/transformation/file/options/option-manager.js:249:14)
    at OptionManager.init (/rn46/node_modules/babel-core/lib/transformation/file/options/option-manager.js:368:12)
    at compile (/rn46/node_modules/babel-register/lib/node.js:103:45)
    at loader (/rn46/node_modules/babel-register/lib/node.js:144:14)
    at Object.require.extensions.(anonymous function) [as .js] (/rn46/node_modules/babel-register/lib/node.js:154:7)
    at Module.load (module.js:488:32)

Something has definitely gone wrong down this rabbit hole. I noticed that @davidaurelio just upgraded babel-preset-react-native with commit bc22a4d, not sure if it's related but the update is already showing up in the initialized package.json:

	"devDependencies": {
		"babel-jest": "20.0.3",
		"babel-preset-react-native": "2.0.0",
		"jest": "20.0.4",
		"react-test-renderer": "16.0.0-alpha.12"
	}

Packager is broken on current RN master

The packager is currently crashing when generating a bundle on RN master. It seem to be caused by a difference in the version of jest-haste-map. Adding .default to this require fixes the issue.

Error log from RN OSS CI:

error: bundling failed: TypeError: Right-hand side of 'instanceof' is not an object

    at ResolutionRequest._resolveHasteDependency (/Users/travis/build/facebook/react-native/node_modules/metro-bundler/src/node-haste/DependencyGraph/ResolutionRequest.js:124:17)

    at ModuleResolution.tryResolveSync (/Users/travis/build/facebook/react-native/node_modules/metro-bundler/src/node-haste/DependencyGraph/ResolutionRequest.js:103:18)

    at Object.tryResolveSync (/Users/travis/build/facebook/react-native/node_modules/metro-bundler/src/node-haste/DependencyGraph/ModuleResolution.js:113:12)

    at ResolutionRequest.resolveDependency (/Users/travis/build/facebook/react-native/node_modules/metro-bundler/src/node-haste/DependencyGraph/ResolutionRequest.js:102:39)

    at dependencyNames.map.name (/Users/travis/build/facebook/react-native/node_modules/metro-bundler/src/node-haste/DependencyGraph/ResolutionRequest.js:136:10)

    at Array.map (<anonymous>)

    at ResolutionRequest.resolveModuleDependencies (/Users/travis/build/facebook/react-native/node_modules/metro-bundler/src/node-haste/DependencyGraph/ResolutionRequest.js:135:42)

    at module.readFresh.then (/Users/travis/build/facebook/react-native/node_modules/metro-bundler/src/node-haste/DependencyGraph/ResolutionRequest.js:183:16)

    at <anonymous>

    at process._tickCallback (internal/process/next_tick.js:188:7)

Packager error: "Can't find variable: process"

Do you want to request a feature or report a bug?
Bug

Behavior
The issue was initially discovered in #65 after people began using the latest metro-bundler 0.20.0 version to work around dynamic requires in packages like moment.js

Packager throws the following error when bundling:

Unhandled JS Exception: Can't find variable: process

Repro Steps

  1. Add metro-bundler 0.20.0 to package.json as a "resolutions" entry for react-native:
"resolutions": {
  "react-native/metro-bundler": "0.20.0"
}
  1. Run react-native run-ios as normal.

NOTE: The fact that this issue manifested for people in [email protected] is a red herring. This issue appears to be happening with older versions of metro-bundler as well. I've confirmed the same error appears in [email protected] I haven't tried to reproduce it in any versions older than 0.19.0 yet.

Environment
Node: v8.5.0

package.json

  "dependencies": {
    "react": "16.0.0-beta.5",
    "react-native": "0.49.3"
  },
  "resolutions": {
    "react-native/metro-bundler": "0.19.0"  
  },

Hot reloading of assets (e.g. yaml) doesn't work

Do you want to request a feature or report a bug?
bug

What is the current behavior?
When adding a file extension (e.g. yml) to getAssetExts and using hot reloading, it's not processed by the babel transform (e.g. babel-plugin-convert-to-json), instead it tries to parse it as js

What is the expected behavior?
The hot reloading of the file transforms the file using the babel transform, just like on first loading the file

[Discuss]Problems about unstable numeric module ID.

Do you want to request a feature or report a bug?
Feature, or discuss first.

What is the current behavior?

Modules are now packed by unstable numeric module ID. There are some bad parts of this behavior:

1. Unfriendly to diff.

Supposing there is an entry which some deps like following:

import a from "./lib/a";
import b from "./lib/b";
import c from "./lib/c";
import d from "./lib/d";

Bundle it first. Then remove one of deps, for example, ./lib/a:

-import a from "./lib/a";
import b from "./lib/b";
import c from "./lib/c";
import d from "./lib/d";

Bundle it again. Check bundle's diff:

image

As you see, all define/require code (module ID, exactly) about deps after ./lib/a were changed.

This may give rise to lots of unecessary mutated in some projects's bundle which has huge dependency graph. It's not friendly to bundle diff/update. (Some Apps and 3rd. tools will update bundle by diff algorithm to reduce the consumption from un-splitting bundle size.)

2. Can' t run muti-bundle(RN App) at one context.

In our team, there are many native Apps which have been integrated React Native paritially, and each native App may include mutiple RN Apps (with mutiple entries).

We are finding a way that can run mutiple RN Apps in a common JS context so that we don't need to recreate bridge/context, run bundle and define method/modules over and over, even can share data and modules with each other.

Think about the style of Node.js server application, we don't need to redefine modules like react, react-dom, react-router blah-blah for each route when it called by requests.

image

But at least now, It can't be implemented because of numeric module ID. Bundles will override other's modules which always start with 0, 1, 2 but not an unique ID.

3. Unfriendly to bundle-splitting (module reference).

We are also trying to split bundle for decrease update download size. You can see an earlier incomplete PR facebook/react-native#10804 I've sent.

We splited most of library modules, like react, react-native and our common utils into a base bundle, only pack business code into business bundle, then maintaining a manifest.json file to handle module call from business bundle to base bundle (Like webpack's DLL way).

image

But you can guess that numeric module ID also make it unstable. If we add a module, or reorder the imports to any of deps in base bundle, manifest will get a huge change. We have to repack all business bundles. This means that we can't make a stable module reference by current packager.

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.
Not a bug.

What is the expected behavior?

Could metro-bundler support string module ID?

Support string module ID so that we can get more stable bundle, and more friendly to diff, make stable reference and work on bundle-splitting.

We know that each module has an unique path relative to project's root path. Maybe we can create a hash by the path in moduleIdFactory, to get an unique stable ID.

And if we want to create a bundle with isolate IDs (run different projects bundle, or upgrade module partially), we also can add a prefix to the moduleIdFactory when pack the bundle. It's absolutely more extensible than numeric.

I also noticed about the indexed-ram-bundle in unbundle way. It has relied on numeric ID strongly AFAIK. Could metro-bundler make compatible with this two ways? Or through option to enable stable string module ID?

looking forward to your opinions @cpojer @jeanlauliac @amasad @davidaurelio. And willing to send PR if needed!

Unable to resolve some dependencies from ‘extraNodeModules’ paths (Windows only)

Specifically this affects a subset of dependencies with names containing forward slash, that are either:

  • scoped, e.g. '@myco/mymodule'
  • relative to module e.g. 'mymodule/folder'

... where said modules exist under a path referenced by extraNodeModules

Existing behaviour:

On Windows:

Unable to resolve module `@alexbinary/object-deep-assign` from . . . : Module does not exist in the module map

(working as intended on other platforms)

Root cause:

When resolving extraNodeModules, toModuleName is split using the platform specific path.sep (so backslash on Windows), but would more commonly contain a forward slash regardless of platform.
In the example above the module name will not split on \ and fails to resolve a folder @alexbinary/object-deep-assign.
I would expect the module name to split on either \ or / on Windows, in which case a folder @alexbinary would be resolved correctly.

Possible Fix

On Windows, when we need to split such a path to resolve, we need to consider both separators.

A potential fix at https://github.com/facebook/metro-bundler/blob/14428a67e5e2c9842af4cb864d0f458b3038959d/packages/metro-bundler/src/node-haste/DependencyGraph/ModuleResolution.js#L269
is to use a regex

        const bits = toModuleName.split(path.sep === '/' ? path.sep : /[\/\\]/);`

… I’m happy to to submit this as a pull request.

Environment

The problem was observed in 0.7.8 but is still present in the latest master (above link), although the code has been considerably refactored since
npm 3.10.6, node v6.11.2

Note this is unrelated to other path separator fixes, e.g. for issue #2

Add ability to log stack traces for bundling errors

Do you want to request a feature or report a bug?

feature

What is the current behavior?

Currently when there is a bundling error the bundler strips off all stack information before printing an error.

The TerminalReporter _logBundlingError function states We do not want to log the whole stacktrace for bundling error, because these are operational errors, not programming errors, and the stacktrace is not actionable to end users.

What is the expected behavior?

There should be an option to enable the bundler to report the full stack information of any errors it encounters, something like a --verbose option would suffice.

There are multiple scenarios where having this information would make a developer's live a lot easier (such as the one I am experiencing trying to debug babel issues). Currently I have to resort to modifying module code, and running the bundler within an inspector just to extract information which should realistically be much easier to get at.

TransformCaching module try to collect cache every time I build bundle

Do you want to request a feature or report a bug?
Report a bug

What is the current behavior?
TransformCaching module try to collect cache every time I build bundle. _collectCacheIfOldSync method returns when Date.now() - lastCollected > GARBAGE_COLLECTION_PERIOD.

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.

What is the expected behavior?
Shouldn't the judgment be Date.now() - lastCollected < GARBAGE_COLLECTION_PERIOD

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

Is the `.mjs` file extension resolved by metro bundler?

Hi all, quick question as library maintainer, is the .mjs file extension supported by metro? In order words, will a package json with a module field like this work like with webpack (or is module ignored completely, which would be fine as well):

"module": "lib/mobx.mjs"

Flow Errors (use inside of react native)

Do you want to request a feature or report a bug? Bug

What is the current behavior?

When running flow on the latest React Native (0.47.1 at time of posting), I get the following errors:

node_modules/metro-bundler/src/Bundler/index.js.flow:483
483:             /* $FlowFixMe: `getModuleId` is monkey-patched */
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Error suppressing comment. Unused suppression

node_modules/metro-bundler/src/Server/index.js.flow:614
614:                   /* $FlowFixMe: should be enforced not to be null. */
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Error suppressing comment. Unused suppression

node_modules/metro-bundler/src/node-haste/DependencyGraph/HasteMap.js.flow:64
 64:     (this: any)._processHastePackage = throat(1, this._processHastePackage.bind(this));
                                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function call. Could not decide which case to select
 64:     (this: any)._processHastePackage = throat(1, this._processHastePackage.bind(this));
                                            ^^^^^^ intersection type
  Case 1 may work:
    3: declare function throat<TResult, TFn: (...args: Array<any>) => Promise<TResult>>(size: number, fn: TFn): TFn;
                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ polymorphic type: function type. See: node_modules/throat/index.js.flow:3
  But if it doesn't, case 3 looks promising too:
    5: declare function throat(size: number): <TResult>(fn: () => Promise<TResult>) => Promise<TResult>;
                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function type. See: node_modules/throat/index.js.flow:5
  Please provide additional annotation(s) to determine whether case 1 works (or consider merging it with case 3):
  165:   _processHastePackage(file: string, previousName: ?string) {
                                                                  ^ return

node_modules/metro-bundler/src/node-haste/DependencyGraph/HasteMap.js.flow:65
 65:     (this: any)._processHasteModule = throat(1, this._processHasteModule.bind(this));
                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function call. Could not decide which case to select
 65:     (this: any)._processHasteModule = throat(1, this._processHasteModule.bind(this));
                                           ^^^^^^ intersection type
  Case 1 may work:
    3: declare function throat<TResult, TFn: (...args: Array<any>) => Promise<TResult>>(size: number, fn: TFn): TFn;
                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ polymorphic type: function type. See: node_modules/throat/index.js.flow:3
  But if it doesn't, case 3 looks promising too:
    5: declare function throat(size: number): <TResult>(fn: () => Promise<TResult>) => Promise<TResult>;
                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function type. See: node_modules/throat/index.js.flow:5
  Please provide additional annotation(s) to determine whether case 1 works (or consider merging it with case 3):
  150:   _processHasteModule(file: string, previousName: ?string) {
                                                                 ^ return

These are all the errors I get, and prior to this version, I got no errors.\

What is the expected behavior?

No flow errors.

no such file or directory, open '/Users/.../project-name/node_modules/metro-bundler/src/Resolver/polyfills/prelude_dev.js'

Getting this error all of a sudden. Tried deleting node modules and reinstalling, clearing cache, upgrading react native, reinstalling metro-bundler. None of it worked.

The path indeed does not exist. In fact I don't see any src folder in node_modules/metro-bundler.

I downloaded the src folder from this repo and added it to node-modules/metro-bundler. Now the file is definitely there. But it's still showing the same error...saying there's no such file.
screenshot 2017-09-18 22 29 41

Anyone has insights on this?

Update: cleared cache again after adding src folder. It worked one time. And then when I rebuild I'm now getting this same error...

Documentation for available options

Do you want to request a feature or report a bug?

Feature

What is the current behavior?

I can't find any documentation for the packager options

What is the expected behavior?

It would be cool to be able to have documentation for the packager options

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

N/A

Dynamic import not working

There has been a conversation around this problem on different thread, please see:
facebook/react-native#6391 (comment)

The problem is essentially that as of now it is not possible to import or require modules dynamically or programatically (using a variable).

With import() in Stage 3 in TC39 this feature is fast becoming a standard language element and the lack of this facility in React Native is becoming all the more limiting.

Also, as per the above conversation there are very legitimate scenarios (dependency injection for example), where such lazy and conditional loading is a must.

Based on all this I would like to make a feature request for this (please let me know if this is not the right forum for doing so).

Cannot find module 'wordwrap'

Do you want to request a feature or report a bug?
Bug
What is the current behavior?
When I'm trying to build the project with "react-native run-android". Packager throws the following error when bundling:
Error: Cannot find module 'wordwrap'
at Function.Module._resolveFilename (module.js:469:15)
at Function.Module._load (module.js:417:25)
at Module.require (module.js:497:17)
at require (internal/module.js:20:19)
at Object. (/Users/apple/Documents/Workspace/appUnifyme/node_modules/metro-bundler/src/lib/formatBanner.js:15:16)
at Module._compile (module.js:570:32)
at Object.Module._extensions..js (module.js:579:10)
at Module.load (module.js:487:32)
at tryModuleLoad (module.js:446:12)
at Function.Module._load (module.js:438:3)

So, there is a require of the module wordwrap but this module wasn't install. To fix the bug I installed the module with the classic "npm install wordwrap".

blacklist completely ignored

Do you want to request a feature or report a bug?

bug

What is the current behavior?

The file blacklist is ignored.

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.

With react-native v0.48.3 init a new project and add a rn-cli.config.js file to the root directory:

const metroBundler = require('metro-bundler');

module.exports = {
  getBlacklistRE: function() {
    console.log("yes, i am being called but no one seems to listen.");
    // ignore everything!
    return metroBundler.createBlacklist([/.*/]);
  },
};

Now, run react-native run-ios the packager will open up print the message and still bundle everything!

A cursory look through the source code did not uncover any places where the blacklistRE option was ever actually used in the code. I couldn't find any tests for blacklistRE either.

What is the expected behavior?

For the blacklist to work.

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

metro-bundler 0.11.0
react-native 0.48.3
yarn 0.17.2
macOS

Provide an option to disable name mangling, make it opt-in

Do you want to request a feature or report a bug?
Feature

What is the current behavior?
When bundling production builds for React Native, names are mangled by default. This can break code (if it relies on Function.name) and the issue is kinda hard to track down (especially if the code accessing Function.name is deep into your dependency tree).

What is the expected behavior?
There should be at least an option to disable mangling, but I believe ideally it should be opt-in rather than opt-out. (Since it can break code in unpredictable ways)

Other people have been hitting this, and are relying on manually patching minify.js:

facebook/react-native#9711

Thanks in advance!

Submodule depends on Node only package and packager can't find it

In order to avoid code duplication, I have inserted my React/Redux web application inside my React Native directory. This way, I should be able to import the Redux store and use it in my React Native application.

The packager doesn't seem to like the submodule and it's complaining with the following message.

image

Additional Information

  • React Native version: 0.44.0
  • Platform: Both
  • Development Operating System: MacOS

You can also find the same question (and a couple more details) in the following Stack Overflow link: https://stackoverflow.com/questions/44499428/react-native-submodule-depends-on-node-only-package

[discussion] supporting platform-specific Babel plugins

Do you want to request a feature or report a bug?
Feature

What is the current behavior?
Currently Metro doesn't tell Babel the platform for which it's transforming a file.

What is the desired behavior?
We'd like to transform files differently based on the platform (ex: Android, iOS, Windows). These are a couple of use cases:

  1. The JS VM on a platform may support more features of modern JS, like classes. A platform-specific Babel plugin would omit the ES class transform on one platform but not another.

  2. RN Windows needs to override some of the require() calls. Specifically, it wants to rewrite require('Text') (inside of react-native) to require('react-native-windows/Libraries/Text/Text.windows.js'). Currently RN Windows relies on a private implementation detail of Haste to override how Metro resolves modules. With platform-specific Babel plugins, RN Windows could offer a Babel plugin that rewrites requires only if platform=windows were specified. (The motivation for this is: this would help remove one of the last reasons why RN OSS needs Haste.)

There are a few different ways we could achieve this:

  1. Set an environment variable (in the transform worker) that Babel plugins can inspect: METRO_PLATFORM.
  2. Somehow passing the platform into the Babel plugins another way (via options? not sure if this can be done cleanly)
  3. Platform-specific presets: the default transformer.js inside Metro already knows how to look up .babelrc. We could modify this code to look up .{android,ios,windows,native,web}.babelrc. This feels easy to explain to someone who knows about platform-specific modules like module.ios.js.
  4. Something else?

Regardless of the option, we'd need to make sure to include the platform in the transform cache key. I think this already happens but don't quote me on that =)

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

Can not install metro-bundler

Do you want to request a feature or report a bug?
bug
What is the current behavior?
npm install metro-bundler
[email protected]
updated 1 package in 1.39s
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.

What is the expected behavior?
[email protected]
updated 1 package in 1.39s
Please provide your exact metro-bundler configuration and mention your metro-bundler, node, yarn/npm version and operating system.
npm 5.5.1

NPM modules being preferred over Haste modules

I've debugged facebook/react-native#13765 (comment) down to an issue where RN's var merge = require('merge') will import node_modules/merge, instead of the expected react-native/Libraries/vendor/core/merge.js (which contains a @providesModule merge directive).

According to the dozens of users affected, it seems to be non-deterministic behavior that sometimes resolves itself with reinstallation, different versions of node, or recreation of the directory and node_modules directory. I'm not yet sure if this nondeterminisim is a bug in React-Native library code layout, or a bug in the RN packager (aka metro-bundler?) itself...but I'm leaning towards the latter, since it seems to violate my expectations for Haste module imports.

runBeforeMainModule is an empty array

Do you want to request a feature or report a bug?
report a bug

What is the current behavior?
runBeforeMainModule is an empty array. I noticed that runBeforeMainModule config was removed from metro-bundler in this commit Make the runBeforeMainModule config param to RN repo and make it absolute. runBeforeMainModule is passed into Server instance in react-native local-cli.

const options = {
      assetExts: defaultAssetExts.concat(assetExts),
      assetRegistryPath: ASSET_REGISTRY_PATH,
      blacklistRE: config.getBlacklistRE(),
      extraNodeModules: config.extraNodeModules,
      getPolyfills: config.getPolyfills,
      getTransformOptions: config.getTransformOptions,
      globalTransformCache: null,
      hasteImpl: config.hasteImpl,
      maxWorkers: args.maxWorkers,
      platforms: defaultPlatforms.concat(platforms),
      postMinifyProcess: config.postMinifyProcess,
      postProcessModules: config.postProcessModules,
      postProcessBundleSourcemap: config.postProcessBundleSourcemap,
      projectRoots: config.getProjectRoots(),
      providesModuleNodeModules: providesModuleNodeModules,
      resetCache: args.resetCache,
      reporter: new TerminalReporter(terminal),
      runBeforeMainModule: config.runBeforeMainModule,
      sourceExts: defaultSourceExts.concat(sourceExts),
      transformCache: TransformCaching.useTempDir(),
      transformModulePath: transformModulePath,
      useDeltaBundler: false,
      watch: false,
      workerPath: config.getWorkerPath && config.getWorkerPath(),
};

packagerInstance = new Server(options);

However, runBeforeMainModule is not passed into bundle options.
In shared/output/bundle.js module, runBeforeMainModule is not included when packagerClient.buildBundle is called.

// shared/output/bundle.js
function buildBundle(packagerClient: Server, requestOptions: RequestOptions) {
  return packagerClient.buildBundle({
    ...Server.DEFAULT_BUNDLE_OPTIONS,
    ...requestOptions,
    isolateModuleIDs: true,
  });
}

In Server/index module, runBeforeMainModule is also not included when this._bundler.bundle(options) is called.

async buildBundle(options: BundleOptions): Promise<Bundle> {
    const bundle = await this._bundler.bundle(options);
    const modules = bundle.getModules();
    const nonVirtual = modules.filter(m => !m.virtual);
    bundleDeps.set(bundle, {
      files: new Map(
        nonVirtual.map(({sourcePath, meta}) => [
          sourcePath,
          meta != null ? meta.dependencies : [],
        ]),
      ),
      idToIndex: new Map(modules.map(({id}, i) => [id, i])),
      dependencyPairs: new Map(
        nonVirtual
          .filter(({meta}) => meta && meta.dependencyPairs)
          .map(m => [m.sourcePath, m.meta.dependencyPairs]),
      ),
      outdated: new Set(),
    });
    return bundle;
  }

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.

What is the expected behavior?
Shouldn't this._opts.runBeforeMainModule merged into options when this._bundler.bundle(options) is called in buildBundle function of Server module?

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

Release optimization pass doesn't respect input source maps?

Hey peeps! Nice work splitting this off from react-native :)

It seems that, despite best intentions, input source maps get ignored when bundling for release. Here is the culprit: https://github.com/facebook/metro-bundler/blob/e87a8205d8ca070df0fcef67dbe4f02389770b95/packages/metro-bundler/src/JSTransformer/worker/index.js#L126

The transform steps done inside both of those optimization passes seem to ignore input source maps, regardless of whether they are passed inline or not. This may well be an issue with Babel rather than Metro. Indeed, it may even be desired behaviour in babel, but metro should probably be mapping between compiled and input code properly :)

The first place that the input source map gets left behind is during the inline operation. Notice that it transforms the input with the babel option source set to false - When you do that, babel never outputs a map property during the File#generate method because it ends up calling File#makeResult in such a way that it is impossible for a map to be emitted.

However, even if you patch inline to set code: true, the emitted map appears to be based only on the code passed to the transform step, completely ignoring the inputSourceMap property.

I've done a few hours trying to debug this but gotten nowhere. Maybe one of you can look at it?

I made a failing test over here: https://github.com/ds300/metro-bundler/blob/aadd5d8303ac99c8d5e5918ac752ca90b1c2fbdb/packages/metro-bundler/src/JSTransformer/worker/__tests__/source-mapping-test.js

Thanks ❤️

JSTransformer ignores timeout option

Do you want to request a feature or report a bug?

bug

What is the current behavior?

The transformTimeoutInterval is set from a const, but the error message says it should be settable by an option.

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.

Pass transformTimeoutInterval=1 to the bundler
Bundle a package that takes longer than one second
The timout will not occur after one second

Here's the problem: https://github.com/facebook/metro-bundler/blob/master/packages/metro-bundler/src/JSTransformer/index.js#L110 (along with the error message formatting on line 165)

What is the expected behavior?

Specified timeout is respected

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

the issue is in master branch as linked above.

Support npm/yarn linking

Do you want to request a feature or report a bug?
Feature/Bug

What is the current behavior?
When building a react-native module, it is currently widely used to have an Example project with a relative reference (file:../ in package.json) to the main package/module. It has the advantage that local development is easier.

But the module resolution isn't supporting linked modules or modules that are defined as being relative using file:../ in a package.json.

Examples:

The two projects mentioned above isn't currently working as the bundler isn't supporting the file:../ reference. It fails with a:

UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 650): UnableToResolveError: Unable to resolve module react from /Users/kenneth/git/react-native-camera/index.js

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.

What is the expected behavior?
Similar to webpack resolve.fallback I would like the bundler to support this. See http://webpack.github.io/docs/troubleshooting.html#npm-linked-modules-doesn-t-find-their-dependencies

Would it make sense to have this as a fallback searchQueue? Something like this in the resolver:

    const fallbackSearchPath = path.join(process.cwd(), 'node_modules');
    if (this._dirExists(fallbackSearchPath)) {
      // add module of current working directory as fallback
      searchQueue.push(path.join(fallbackSearchPath, realModuleName))
    }

The alternative for me right now is to have a rn-cli-config.js similar to this:

const path = require('path');

// As the metro bundler does not support linking correctly, we add additional
// search path queries to all modules.
const extraNodeModulesGetter = {
  get: (target, name) => path.join(process.cwd(), `node_modules/${name}`),
};

module.exports = {
  extraNodeModules: new Proxy({}, extraNodeModulesGetter),
};

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

Object Dot notation doesn't transpile when bundling for production

When bundling for production I'm getting an error when using dot notation over bracket notation whilst mutating an object:

Property left of AssignmentExpression expected node to be of a type ["LVal"] but instead got "StringLiteral"

Example:

    Platform['OS'] = platform.OS; // works
    Platform.OS = platform.OS; // doesn't work

This can be reproduced with the following steps:

> react-native init my-project
# ...
> cd my-project
> npm install react-primitives --save

# modify index.ios.js to: import { Text } from react-primitives;

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/

I am tracking this issue on react-primitives here: lelandrichardson/react-primitives#79

Option for stable module Ids?

Do you want to request a feature or report a bug?
Feature

i’m working on OTA updates for RN at airbnb, and one of the things that i’m looking to do is to ensure that we can push just the code that’s changed and not the whole bundle to the clients. since the RN packager uses unstable module ids after bundling code (ie, require(123) might need to turn into require(124) after a relatively trivial change in module loading order).

I was thinking about submitting a PR to metro-bundler that would add in an option to use "stable ids" for the require algorithm. This would probably end up using the localPath of the module, as opposed to the auto-incrementing module id.

I'm still considering strategies, but I'm thinking that in the situation where the user is using unbundle, a map of localPath => moduleId could be added to a global variable or something, which the require.js polyfill could utilize.

If I made such a PR, would FB be willing to accept it? It would be done in such a way that it would be completely opt-in.

cc @jeanlauliac @cpojer

Stay off my [email protected] lawn?

Do you want to request a feature or report a bug?
Bug

What is the current behavior?
Controlling polyfills forcing ideologies and telling me how to live my life

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.
It is simple to reproduce, put something in the object prototype chain that is enumerable (which does and can happen all the time... including injection from 3rd party libraries, and creating context objects via Object.create)

What is the expected behavior?
Stay off my lawn, stop telling me how to code, and stop doing things the slow way just to tell other people how to do things

Please provide your exact metro-bundler configuration and mention your metro-bundler, node, yarn/npm version and operating system.
Simple hello world example + var a = { test: 'derp' }, b = Object.create(a), c = Object.assign({}, b);

Your Polyfill for Object.assign (Object.es6.js) is completely backwards, slow, and forcing an ideology. You are DELIBERATELY walking and copying the entire prototype chain, which is slow, and often not desired. The SUPER INSANE part? You are telling me how to live my life, and throwing an exception if there IS an enumerable property in the prototype chain. Forcing people to do things YOUR way is the wrong way. Please update the polyfill to 1) NOT walk the entire chain, 2) NOT tell me how to code.

By the way, I ran into this simply inheriting from EventEmitter, which is SUPER COMMON by the way.

// We don't currently support accessors nor proxies. Therefore this
    // copy cannot throw. If we ever supported this then we must handle
    // exceptions and side-effects.
    
    // No SANE person would ever copy an object with `key in obj`
    // please use `Object.keys(obj)` instead, which is much faster, and doesn't involve forced ideologies
    for (var key in nextSource) {
      if (false) { // <--- Add false here... because you don't need to tell me the proper way to code
        var hasOwnProperty = Object.prototype.hasOwnProperty;
        if (!hasOwnProperty.call(nextSource, key)) {
          throw new TypeError(
            'One of the sources for assign has an enumerable key on the ' +
            'prototype chain. Are you trying to assign a prototype property? ' +
            'We don\'t allow it, as this is an edge case that we do not support. ' +
            'This error is a performance optimization and not spec compliant.'
          );
        }
      }
      target[key] = nextSource[key];
    }

DeltaBunder for?

hai, I want to know metro-bundler DeltaBunder modules is used for? beacuse i upgrade rn to 0.49.0, i was used rn with 0.45.1 version, i modify some code fit my demand(code split), in 0.49.0 version
i find DeltaBunder modules, i want to know used for?

support for .e2e.platform.js mock file loading

feature request
Working with detox, a graybox e2e testing framework for react-native;
A very important feature is to be able to load specific files with the packager instead of the production code, as that is the only sure way to inject test configuration into the sim/device or mocking certain files while running e2e tests.
So for example while in your production code you import './foo' and have a foo.js file that does some server calls and a foo.e2e.js file that just returns a resolved promise; while running a packager instance with (for example) --customExtensions=e2e, you will get the foo.e2e.js file instead of foo.js.

We already are successfully working locally with a forked react-native 0.44, where I used this to solve this problem (a quick hack that applies some file changes to the packager code inside node_modules).

I started working on a PR for this functionality into metro-bundle, and would like some feedback and help on this issue.

Assets not picked up with multi project roots

Do you want to request a feature or report a bug?
Bug.

What is the current behavior?
If you have a project setup with multiple roots and there are overlapping relative directories, assets are only picked up from directory in the first root.

Here is a failing testcase:

      const server = new AssetServer({
        projectRoots: ['/root', '/root2'],
        assetExts: ['png'],
      });

      fs.__setMockFilesystem({
        'root': {
          imgs: {
            'a.png': 'a image',
          },
        },
        'root2': {
          imgs: {
            'b.png': 'b image',
          },
        },
      });

      return Promise.all([
        server.get('imgs/a.png').then(data =>
          expect(data).toBe('a image')
        ),
        server.get('imgs/b.png').then(data =>
          expect(data).toBe('b image')
        ),
      ]);

The test fails on not being able to find imgs/b.png, because internally _findRoot always returns the first matching path (imgs) and no b.png is present there.

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.

Checkout the fork at https://github.com/AlbertBrand/metro-bundler

I added the above testcase to AssetServer-test.js that shows the issue.

What is the expected behavior?
I would expect the asset server to look in each project root for the asset. Or, even more correct: the AssetServer get call should take in account the root of the asset. If you then would refer to an asset from a specific root, it can directly resolve the correct one.

bundle fails: EISDIR: illegal operation on a directory, open

bug

What is the current behavior?

When running:
react-native bundle --platform ios --dev false --entry-file index.ios.js --bundle-output ./ --sourcemap-output ./

I got:
EISDIR: illegal operation on a directory, open './'

I've tried with reset-cache, tried using different directories, tried sudo -- nothing helps.

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

node v.6.11.0
react-native-cli: 2.0.1
react-native: 0.44.0
npm v.3.10.10
macOS v.10.12


When running Xcode build/run (Release scheme) everything works great.

Images with @2x or @3x in their file names are not resolved (breaks static image resources)

Do you want to request a feature or report a bug?

Report a bug

What is the current behavior?

Images with @2x or @3x in the file name are not resolved when doing require('../[email protected]'). If I remove the @ then it loads the file without an issue.

image

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.

Others have reproduced this behavior as you can see 👉 facebook/react-native#15030

What is the expected behavior?

I expect the files to load and be resolved without an issue. This problem breaks static image resources 👉 https://facebook.github.io/react-native/docs/images.html#static-image-resources

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

I've used the stock version that comes with react-native 0.47.1.
I've also tried --reset-cache and finally I've also updated metro-bundler to version 0.11.0.
npm 5.0.3
yarn 0.27.5
Mac OSX 10.12.6

The only workaround I've found is to remove the @ when requiring the file

Bundler can't resolve a JSON file in the project root directory with file name that starts with "."

Bug Report

The bundler can't resolve JSON files in the root directory with a file name of .foo.json. It can resolve JSON files with a name of foo.json.

What is the current behavior?

When importing a JSON file from a JS file like so:

import { thing } from './.thing.json'; // note the . at the beginning of the file name
export const bar = thing.foo;

The bundler will crash with the following:

Bundling `index.ios.js`  [development, non-minified, hmr disabled]  99.3% (297/298), failed.
Error: Expected root module to be relative to one of the project roots
    at toLocalPath (/Users/matthamil/workspace/reactnative/Ralli/node_modules/metro-bundler/src/node-haste/lib/toLocalPath.js:29:9)
    at ModuleCache.getModule (/Users/matthamil/workspace/reactnative/Ralli/node_modules/metro-bundler/src/node-haste/ModuleCache.js:93:20)
    at ModuleResolver._loadAsFile (/Users/matthamil/workspace/reactnative/Ralli/node_modules/metro-bundler/src/node-haste/DependencyGraph/ModuleResolution.js:416:48)
    at ModuleResolver._loadAsFileOrThrow (/Users/matthamil/workspace/reactnative/Ralli/node_modules/metro-bundler/src/node-haste/DependencyGraph/ModuleResolution.js:380:25)
    at tryResolveSync (/Users/matthamil/workspace/reactnative/Ralli/node_modules/metro-bundler/src/node-haste/DependencyGraph/ModuleResolution.js:233:10)
    at tryResolveSync (/Users/matthamil/workspace/reactnative/Ralli/node_modules/metro-bundler/src/node-haste/DependencyGraph/ModuleResolution.js:111:12)
    at ModuleResolver._resolveFileOrDir (/Users/matthamil/workspace/reactnative/Ralli/node_modules/metro-bundler/src/node-haste/DependencyGraph/ModuleResolution.js:231:12)
    at ModuleResolver.resolveNodeDependency (/Users/matthamil/workspace/reactnative/Ralli/node_modules/metro-bundler/src/node-haste/DependencyGraph/ModuleResolution.js:255:19)
    at ResolutionRequest.resolveDependency (/Users/matthamil/workspace/reactnative/Ralli/node_modules/metro-bundler/src/node-haste/DependencyGraph/ResolutionRequest.js:109:14)
    at dependencyNames.map.name (/Users/matthamil/workspace/reactnative/Ralli/node_modules/metro-bundler/src/node-haste/DependencyGraph/ResolutionRequest.js:118:10)

I think the bug is related to this function. I could be wrong. That's where the error is being thrown in my stack trace.

Steps to reproduce:

Create a new React Native project. In the root project directory, create a .thing.json file like so:

{
  "thing": {
    "foo": "bar"
  }
}

Create a JS file also in the root directory, call it something like MyConfig.js.

Make MyConfig.js look like the following:

import { thing } from './.thing.json'; // note the . at the beginning of the file name
export const bar = thing.foo;

In the index.ios.js file, add the following line to the top of the file:

import { bar } from './MyConfig';

and change the render method to look like:

render() {
  return (
    <View>
      <Text>{bar}</Text>
    </View>
  );
}

Run react-native start and react-native run-ios.

What is the expected behavior?

The JSON file should be imported without any problems. If you change the file name of the JSON file to thing.json without the prepended . in the file name (and update the import statement in MyConfig.js), the import works fine.

Environment:

software version
Metro Bundler 0.9.2
react-native 0.47.1
node 8.2.1
yarn 0.24.5

Modules required from outside of root directory does not find node_modules

Hi! I hope I post this in the right place, sorry if I'm not.

I'm trying to setup requiring files outside of the root project directory, as I'm building both a web app and a native app that'll share some code. I've configured this using rn-cli.config.js, and I can successfully import my shared files from outside of my root.

However, the files imported from outside of the root does not find any modules from node_modules (React for example). Files required from inside of the project root does find them (which I guess is because node_modules is in a parent directory to them). I just get a Cannot resolve module 'React'.

The folder structure looks like this:

common
- components
- - ....code
web
- node_modules
- ....code
native
- node_modules
- ...code, rn-cli.config.js, etc...

rn-cli.config.js:

const path = require('path');

module.exports = {
  getProjectRoots() {
    return [
      path.resolve(__dirname, '../common'),
      path.resolve(__dirname, 'node_modules'),
      path.resolve('.')
    ]
  }
};

If I add a package.json to common and install react there it works. So I guess this has to do with the packager walking the file upwards and not finding node_modules as it's in a sibling directory and not a parent directory?

Am I missing something obvious here? I've tried clearing the cache etc. I'm on the latest Expo which I'm pretty sure uses RN 0.43.

Thanks in advance!

Dependency on image-size in root package.json and metro-bundler/package.json inconsistent version

Do you want to request a feature or report a bug?

Neither!

What is the current behavior?

image-size should not be included in the root package.json, just in metro-bundler/package.json, unless I am gravely mistaken -- in which case, the versions should at least be the same.

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.

It is included in the root package.json (and the wrong version of it is included there too)

What is the expected behavior?

Only include it in metro-bundler/package.json or match the versions.

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

N/A

Documentation for behaviour of node_modules with babel config

Do you want to request a feature or report a bug?

Feature

What is the current behavior?

No documentation for potentially confusing behaviour of running babel on node_modules and merging config.

What is the expected behavior?

Have some documentation and perhaps a better error message if babel config leading to error came from node_modules.

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

N/A

More context

https://twitter.com/notbrent/status/887796674353012736

Integrating CI tests with GitHub

I noticed the Travis and CircleCI tests don't run when sending a PR. Would probably make it easier to review PRs if the test results were available?

[BUG] error: bundling: NotFoundError: Cannot find entry file index.ios.js in any of the roots

When I run the react native app on the simulator by react-native run-ios, this error appear:

image

error: bundling: NotFoundError: Cannot find entry file index.ios.js in any of the roots: ["/Users/goon/HelloRN/node_modules/react-native/packager"]
    at DependencyGraph._getAbsolutePath (/Users/goon/HelloRN/node_modules/react-native/packager/src/node-haste/DependencyGraph.js:280:11)
    at DependencyGraph.getDependencies (/Users/goon/HelloRN/node_modules/react-native/packager/src/node-haste/DependencyGraph.js:218:26)
    at Resolver.getDependencies (/Users/goon/HelloRN/node_modules/react-native/packager/src/Resolver/index.js:107:27)
    at /Users/goon/HelloRN/node_modules/react-native/packager/src/Bundler/index.js:591:37
    at next (native)
    at step (/Users/goon/HelloRN/node_modules/react-native/packager/src/Bundler/index.js:12:445)
    at /Users/goon/HelloRN/node_modules/react-native/packager/src/Bundler/index.js:12:605
    at process._tickCallback (internal/process/next_tick.js:103:7)
Bundling `index.ios.js`  0.0% (0/1), failed.

What I've tried:

watchman watch-del-all
rm -rf node_modules && npm install
npm start -- --reset-cache

then
react-native run-ios

..even tried to re-install react & react native

But it's still not working.

Minification breaks regenerator-runtime package and redux-saga is not usable

Do you want to request a feature or report a bug?
Bug

What is the current behavior?
The [email protected]/runtime.js is not minified properly. Throwing the following error:

ExceptionsManager.js:73 uncaught at n at n 
 ReferenceError: record is not defined
    at Generator._invoke (http://localhost:8081/index.android.bundle?platform=android&dev=true&minify=true:221:931)
    at Generator.t.(anonymous function) [as next] (http://localhost:8081/index.android.bundle?platform=android&dev=true&minify=true:221:1352)
    at t (http://localhost:8081/index.android.bundle?platform=android&dev=true&minify=true:869:536)
    at o (http://localhost:8081/index.android.bundle?platform=android&dev=true&minify=true:869:7374)
    at t.runSaga (http://localhost:8081/index.android.bundle?platform=android&dev=true&minify=true:867:806)
    at o.default (http://localhost:8081/index.android.bundle?platform=android&dev=true&minify=true:865:440)
    at http://localhost:8081/index.android.bundle?platform=android&dev=true&minify=true:514:173
    at t (http://localhost:8081/index.android.bundle?platform=android&dev=true&minify=true:2:1273)
    at http://localhost:8081/index.android.bundle?platform=android&dev=true&minify=true:2:614
    at n (http://localhost:8081/index.android.bundle?platform=android&dev=true&minify=true:2:622)

This is the original code:

var record = tryCatch(innerFn, self, context);
if (record.type === "normal") {

This is the minified:

if (o = b, "normal" === (record = n(t, r, e)).type) {

The regenerator-runtime/runtime.js has this header with strict mode enabled (this cause the error):

!(function(global) {
  "use strict";

With this error the redux-saga package is unusable and the whole app is broken.

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.

What is the expected behavior?
The record variable is well defined. Work fine on:

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

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.