Summary: When starting to use `metro-bundler` as a standalone server, I found quite complicated the fact that it needs a transformer by default. Moreover, the transformer is not passed as a reference to a JS object, but as a path to a required file. I removed the need to be required, and defaulted to a dummy, basic transform, that does nothing by default. This avoids having to create an extra file and linking to it (potentially needing to involve `path` and other extra modules).
Reviewed By: cpojer
Differential Revision: D5622906
fbshipit-source-id: 0c2b1bec86fa542b3c05de42c89d4b5bb4384b34
Summary:
<!-- Thanks for submitting a pull request! Please provide enough information so that others can review your pull request. The two fields below are mandatory. -->
**Summary**
<!-- Explain the **motivation** for making this change. What existing problem does the pull request solve? -->
I am sending this PR to fix an error in TransformCaching module. See this issue [TransformCaching module try to collect cache every time I build bundle #46](https://github.com/facebook/metro-bundler/issues/46).
**Test plan**
<!-- Demonstrate the code is solid. Example: The exact commands you ran and their output, screenshots / videos if the pull request changes UI. -->
```
/**
* When restarting packager we want to avoid running the collection over
* again, so we store the last collection time in a file and we check that
* first.
*/
_collectCacheIfOldSync() {
const {_rootPath} = this;
const cacheCollectionFilePath = path.join(_rootPath, 'last_collected');
const lastCollected = Number.parseInt(
tryReadFileSync(cacheCollectionFilePath) || '',
10,
);
if (
Number.isInteger(lastCollected) &&
Date.now() - lastCollected < GARBAGE_COLLECTION_PERIOD
) {
return;
}
const effectiveCacheDirPath = path.join(_rootPath, CACHE_SUB_DIR);
mkdirp.sync(effectiveCacheDirPath);
collectCacheSync(effectiveCacheDirPath);
fs.writeFileSync(cacheCollectionFilePath, Date.now().toString());
}
```
Steps:
1. Create a new react-native project.
2. Put your breakpoint at this sentence `collectCacheSync(effectiveCacheDirPath);`.
3. Bundle the project, program will break at `collectCacheSync(effectiveCacheDirPath);`
4. Resume the program, finish the first time bundle.
5. Bundle again, this time program won't break.
Closes https://github.com/facebook/metro-bundler/pull/48
Differential Revision: D5726161
Pulled By: jeanlauliac
fbshipit-source-id: 0865f1bf25d6eb36f067ac3dc7764df9fd5026dc
Summary:
The HMR logic used to try to calculate the dependencies of every new added (or modified) file, including assets. This resulted in a TransformError.
This commit adds a check that stops the HMR bundling once it finds out that the updated file is an asset
Reviewed By: cpojer
Differential Revision: D5697391
fbshipit-source-id: faf7ccad76ac4922b70ed1c7ce8ce32b03c4e8ee
Summary: We were not using the timeout at all, so we decided to remove it. Also, the current value is pretty high, so it should never fail unless there's something really bad.
Reviewed By: jeanlauliac
Differential Revision: D5640839
fbshipit-source-id: 3eaa567a6828902376fe5df9fe3f4e96b83a23bd
Summary:
We'll revert when the root problem is fixed, that should mitigate for now.
What might be the root problem, I believe, is that when there are some cached files already on the machine, we immediately try to build all the dependencies, but the worker farm is queuing these and it takes a long time to finish. The timeout should include only the transformation time, not the queuing. I'll fix that separately.
Reviewed By: mjesun
Differential Revision: D5650380
fbshipit-source-id: f4b045876cc822caee3998f69ca98ea986709bf4
Summary: It might be that Metro bundler is getting used directly with the `http` module and not within an express app. If that's the case, the `next` method will not exist, so we have to guard against it.
Reviewed By: davidaurelio
Differential Revision: D5639944
fbshipit-source-id: bcee4a70f6a7b643218b11af0d8aedbc7762eead
Summary: This is the last piece of work to make all the clients do a single request for both HMR/non-HMR modes. I'm not completely sure how this URL is used by the client, but it does not need the `hot` param.
Reviewed By: davidaurelio
Differential Revision: D5639946
fbshipit-source-id: a76f9ba7b9ace625352a156761d3ee2809f80c92
Summary:
This diff enables the HMR transforms for any bundle requested through the metro-bundler HTTP server, so it ignores the `hot` parameter passed in the URL.
This allows much faster switches when enabling/disabling HMR, since metro-bundler does not need to re-compile each single file again, while not impacting substantially build times when HMR is off.
I've done some lightweight benchmarks on my machine and these are the results (all the tests have been done after running metro-bundler with a clean cache and restarting the app).
**Before**
Time to build (HMR off): 1x (baseline)
Time to build (HMR on): 1.90x
**This diff**
Time to build (HMR off): 1.009x
Time to build (HMR on): 1.036x
(The reason why now it takes double the time to load the HMR bundle than the non-HMR bundle after launching the app is because the device after a restart always asks for the non-HMR bundle and afterwards the HMR bundle, causing the server to have to build both bundles).
**Bundle size**
In terms of bundle size, adding the HMR transforms increases the size by around 3-4% (this regression is due to the wrappers added around React components, and will depend on the app).
**Next steps**
There are two improvements to do after this diff:
1. Remove the `hot=true` parameter from the clients when they request the bundle. This will reduce by half the memory used by metro-bundler when switching from non-HMR to HMR (or when opening the app with HMR enabled), since metro-bundler caches the bundles based on url.
2. After this diff, the `hot` parameter in the various options objects will not make much sense, so my suggestion is to just remove it from everywhere and instead of checking for that parameter in the transformer, check for `dev=true` there.
Reviewed By: davidaurelio
Differential Revision: D5623623
fbshipit-source-id: cb76b9182e55f442e2987fcf59eee2ba2571578e
Summary: now that `ResolutionRequest.resolveDependency` is synchronous, we can also make `ResolveFn` synchronous.
Reviewed By: fkgozali
Differential Revision: D5528094
fbshipit-source-id: 0b40df29024b809a99b7e577716b24e9fa499578
Summary: Adds filtering to the assets written from a Buck build, so that we don’t write all assets present in libs, but rather only the ones included in the bundle.
Reviewed By: cpojer
Differential Revision: D5522844
fbshipit-source-id: fcca3567b726dfab1ecf9560932fd6e1a174b31f
Summary: makes flow typing for the entry point more sound and fixes two issues
Reviewed By: BYK
Differential Revision: D5507650
fbshipit-source-id: 6b03f7de792ffcece4d0d61950e136a61ea7db2e
Summary: Format everything, one subdir at a time.
Reviewed By: mjesun
Differential Revision: D5481590
fbshipit-source-id: 6d9157e6857d61b8116bcf9285bd4be415c5ba01
Summary:
By default, when Babel transforms a file, it looks for .babelrc in the file's directory and all parent directories until it finds a .babelrc file. This means that when Metro tries to transform `<PROJECT_ROOT>/node_modules/dep/mod.js`, it searches for `<PROJECT_ROOT>/node_modules/dep/.babelrc`. If that .babelrc actually exists, Babel will try to apply it.
In practice, this often causes problems because packages that include .babelrc often do so unintentionally -- they don't intend for the package consumer to look at that .babelrc file. One thing we've done a lot is `rm` all .babelrc files under node_modules -- this commit effectively achieves the same in a less destructive way by telling Babel not to look up .babelrc files. (To clarify, Metro will still apply the .babelrc file in the project root.)
Since the current behavior is to look at .babelrc files, this commit keeps that behavior for now. We'll consider overriding the default behavior (that is, making Babel not lookup .babelrc files) in the default configuration of Expo/RN projects. If this goes well and we empirically find that people are having a better time, we may want to consider flipping this option's default in Metro, so that Metro tells Babel not to look up .babelrc files by default.
Closes https://github.com/facebook/metro-bundler/pull/31
Differential Revision: D5469620
Pulled By: jeanlauliac
fbshipit-source-id: fe7a1042feafff843e1a6d8cc9487eb6ff8e8358
Summary:
The main goal of this is to be able to show bundle download progress in a follow up PR for react-native.
**Test plan**
Tested that it is possible to show bundle download progress in react-native using this header and added unit test.
Closes https://github.com/facebook/metro-bundler/pull/28
Reviewed By: davidaurelio
Differential Revision: D5443344
Pulled By: jeanlauliac
fbshipit-source-id: 63fd655c964d7df526125fbe55eb9c7cccd7dba9
Summary:
Adding a Babel plugin that will analyze the file looking for any potential candidate to use `regenerator-runtime`, and if so, will inject dynamically the module. The module is injected per file, so we avoid polluting the global environment. The plugin is also able to inject the `require` call beforehand, so that the inliner can pick them and inline them.
The Babel plugin is part of `react-native-babel-preset`, so as long as you are using this preset you are safe. If not, you should include the specific transformer into your list of plugins, as `react-native-babel-preset/transforms/transform-regenerator-runtime-insertion.js`.
Reviewed By: davidaurelio
Differential Revision: D5388655
fbshipit-source-id: dc403f3d5e2d807529eb8569a85c45fec36a6a3e
Summary: Downgrade the locked version of Babel block scoping, kinda temporarily until we upgrade internally. This makes in on par with the version we use internally, so that the `basic_bundle` test had the same results on both infrastructures. This doesn't change a single thing for `metro-bundler` consumers, because this `yarn.lock` file is only used for testing/CI, not when the library is installed as part of a project.
Reviewed By: cpojer
Differential Revision: D5442368
fbshipit-source-id: f3033e450855f7d61ac775a46719d7b1743960c5
Summary: Now we have a nice specific error type for duplicates errors. This changeset have been commited before but was reverted as part of a stack, so here we go again.
Reviewed By: cpojer
Differential Revision: D5442363
fbshipit-source-id: 068c8decaf20cd4f9a73d9d54984030c79cff606
Summary: I appears `Object.assign` is not properly typed-checked by Flow, and silently so, so I propose we switch to an explicit list until we find an alternative solution. I prefer to have strong typing especially for options, and as the lack of typing has caused breakage before.
Reviewed By: cpojer
Differential Revision: D5442319
fbshipit-source-id: 82b0ec760c7dea6da6f7932896243147ce12ebf9
Summary: I'd like to get rid of the function as blacklist, because it's impossible to process properly at the `jest-haste-map` level (https://github.com/facebook/jest/pull/4047). The reason we use a function in Metro bundler is because we excludes all the `__tests__` modules. However, I removed this exclusion completely, and I could build our package without any problem and with no difference in the final bundle. I can only assume, then, that this line is only here for slightly increasing performance. Therefore, I think it's reasonnable to move it as part of the default blacklist shipped with Metro bundler instead.
Reviewed By: cpojer
Differential Revision: D5434351
fbshipit-source-id: dea39f6299985143d25fcb3b7b365d793acd64a9
Summary: Now we have a nice specific error type for duplicates errors.
Reviewed By: cpojer
Differential Revision: D5433438
fbshipit-source-id: 47cad9ca6bf0bdec91a158ccb2807b6c5571966a
Summary: This put it on par with the version we use on other projects. This new version breaks assumptions about the way Promise/ticks/timers use to work, and I was not able to make it work properly synchronously. Since it's fragile anyway (because rely on Promise and feature internals), I propose the switch to async as done in this changeset. If `res.end` is not called, tests will just timeout instead.
Reviewed By: cpojer
Differential Revision: D5423823
fbshipit-source-id: 015e808a2cf2b8297a36b16feeb811a6e745a835
Summary: Going one step further, we can start working around the throwing version. To simply some code, I also piggybacked the addition of helper functions `resolvedAs` and `failedFor` in this changeset, hope it's okay. I can split if necessary.
Reviewed By: davidaurelio
Differential Revision: D5415196
fbshipit-source-id: 1bd5955b5733866af52fa873bcd1d9e4ce8215cf
Summary:
Adding a Babel plugin that will analyze the file looking for any potential candidate to use `regenerator-runtime`, and if so, will inject dynamically the module. The module is injected per file, so we avoid polluting the global environment. The plugin is also able to inject the `require` call beforehand, so that the inliner can pick them and inline them.
The Babel plugin is part of `react-native-babel-preset`, so as long as you are using this preset you are safe. If not, you should include the specific transformer into your list of plugins, as `react-native-babel-preset/transforms/transform-regenerator-runtime-insertion.js`.
Reviewed By: davidaurelio
Differential Revision: D5321193
fbshipit-source-id: fd4805b28c8a2b986842e23570a64003370d2067
Summary:
This fixes https://github.com/facebook/react-native/issues/14530 on my local repro. The reason the original problem appears is because when requiring the preset itself, what I think is a bug in babel-register kicks in and it starts transforming the presets themselves. That fails because these preset don't actually have the correct transforms plugins installed/specified in their `package.json` (they do it at prepublish time).
Closes https://github.com/facebook/metro-bundler/pull/21
Reviewed By: cpojer
Differential Revision: D5380795
Pulled By: jeanlauliac
fbshipit-source-id: 023fd6b36dc7ebd26961878edd71d423ea9856b5
Summary: Restores the ability to write the expected header for indexed RAM bundles by avoiding to stringify buffers as utf8. Some minor cleanups included
Reviewed By: javache
Differential Revision: D5351839
fbshipit-source-id: 056661b064336ff74571b9f44c16d709fc59145b
Summary:
Remove our internal docbloc module and use `jest-docblock` instead.
The development server is using `jest-haste-map` exclusively, which in turn relies on `jest-docblock`, which differs slightly from our own docblock module.
Depending on only one version greatly reduces the number of edge cases
Reviewed By: cpojer
Differential Revision: D5328472
fbshipit-source-id: 4a31d8159519e01a83fda04b76e8f14f0beb16af
Summary:
Trims doc block annotations. This mitigates problems with leading and trailing spaces in `providesModule` annotations.
This module doesn’t have tests, but it is exclusively used for `providesModule` annotations right now.
Reviewed By: mjesun
Differential Revision: D5319814
fbshipit-source-id: de55df5b4b199738f9b01151eb86f3c863485b15
Summary: Given a file `test.android.png`, this allows it to be found as `test.android` for arbitrary platforms.
Reviewed By: bestander
Differential Revision: D5305807
fbshipit-source-id: d869a1da0cc502f853314790385734897f269d6a
Summary:
This makes it a little more convenient to dynamically load font files. We currently do with help from the "assetExts" config flag and find that we specify it a lot. Would you be interested in taking this PR?
Closes https://github.com/facebook/metro-bundler/pull/14
Differential Revision: D5284158
Pulled By: jeanlauliac
fbshipit-source-id: d102cf4776b9e3659c33e15d9d72f7ea0ea52d57
Summary:
With these last fixes, the test is now finishing properly instead of hanging up forever! This means tests should now hopefully pass on CircleCI, amazing!
I had to disable a test that was actually broken, I'd like to fix that in a separate changeset.
Reviewed By: davidaurelio
Differential Revision: D5282917
fbshipit-source-id: d61b13ed40da7cd43a542ad916158a2aefecda18
Summary:
We use a custom rn-cli.config.js file that specifies a custom blacklist. In addition to blacklisting some of our own directories, we still want to keep RN's default rules for what to blacklist so we also call into the packager's blacklist.
Closes https://github.com/facebook/metro-bundler/pull/13
Differential Revision: D5275117
Pulled By: davidaurelio
fbshipit-source-id: 0ad79fa47b8730af5a2c4e9ecbedf02b7d673b6c
Summary: Use `processDgraph` so that the instance is properly ended. Tested using `yarn jest DependencyGraph-test`
Reviewed By: davidaurelio
Differential Revision: D5274139
fbshipit-source-id: 82e919e0f7248ddd01de9c8fa3908c3943184016
Summary: Use `processDgraph` so that the instance is properly ended. Tested using `yarn jest DependencyGraph-test`
Reviewed By: davidaurelio
Differential Revision: D5274137
fbshipit-source-id: d4f46d9b2c02622c81bd178c2b76c9cea89b6dd0
Summary: Use `processDgraph` so that the instance is properly ended. Tested using `yarn jest DependencyGraph-test`
Reviewed By: davidaurelio
Differential Revision: D5274132
fbshipit-source-id: 9a19482f969f105d4e2ec6dffc5ae901a5a7da32
Summary:
**Summary**
fixes edge case for replacing browser "main" field, when "main" field value is a file name rather than a file path
**Test plan**
added breaking test in 1st commit, fix in 2nd commit
Closes https://github.com/facebook/metro-bundler/pull/3
Reviewed By: cpojer
Differential Revision: D5255292
Pulled By: jeanlauliac
fbshipit-source-id: 65764144adfcda9f6dbdf8f5f754186b05e1a8bb
Summary:
`retainLines` is no longer necessary with the much improved source map generation.
`sourceMaps` is handled by the transformer itself.
Reviewed By: cpojer
Differential Revision: D5237103
fbshipit-source-id: e5c6bf5aa9d553fce9c3f4d59b3ea0057d45cfdc
Summary: The `DependencyGraph-test` hangs forever if run in isolation because the watch mode is not properly ended. I propose we just wrap each test in a function that does the correct thing, and also migrate tests to `async`/`await`.
Reviewed By: cpojer
Differential Revision: D5245477
fbshipit-source-id: ea30c0e637e0c7b85afe4c76c5e985846ae9b243
Summary: `worker.transformCode` is a callback-taking function, but did not properly guard against errors thrown in its body.
Reviewed By: cpojer
Differential Revision: D5245253
fbshipit-source-id: 3fd08b68dd8605f664b316652ebd1f9497b2dac9
Summary: That happens after a reboot on macOS for example, because temp dir is wiped.
Reviewed By: davidaurelio
Differential Revision: D5236249
fbshipit-source-id: be19cd97a7488850e3195b3fc419779ed0df2c38
Summary:
This diff cleans up some cruft and adds some features:
* It removes the usage of an env variable to control workers.
* It removes the lazy and handwavy calculation on how many workers to use for jest-haste-map. Jest itself uses the maximum amount of workers available and it has never been reported as an issue – especially since it is a one-time startup cost of about 3 seconds on a cold cache only.
* It adds a `--max-workers` flag to replace the env variable. This one is able to control both the number of workers for `jest-haste-map` as well as the transformers.
* It makes the transformers run in the parent process if 1 or fewer workers are are specified. This should help with debugging.
Once you approve this diff, I will publish a new version of metro to npm and update the version used in RN and remove the use of the env variable altogether: https://our.intern.facebook.com/intern/biggrep/?corpus=xplat&filename=&case=false&view=default&extre=&s=REACT_NATIVE_MAX_WORKERS&engine=apr_strmatch&context=false&filter[uninteresting]=false&filter[intern]=false&filter[test]=false&grep_regex=
Note: the process of adding a CLI option is really broken. Commander also has a weird API. We should consider building a better public API for Metro and then consider how to build a new CLI on top of it and simplify our internal integration. I really don't like how Metro is integrated across pieces of the RN cli in ways that is hard to manage. But that is a larger task for another time :)
Reviewed By: jeanlauliac
Differential Revision: D5217726
fbshipit-source-id: 74efddbb87755a9e744c816fbc62efa21f6a79bf
Summary: Upgrades uglify to version 3 with (experimental) ES6 support turned on.
Reviewed By: cpojer
Differential Revision: D5227245
fbshipit-source-id: db8638eebe2daf40b60570cac34905e9a7288705