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](https://user-images.githubusercontent.com/4403937/26960562-dcf75432-4d0a-11e7-88fd-dc7c32cd8b35.png)
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](https://user-images.githubusercontent.com/4403937/26965347-e90249e0-4d27-11e7-92d0-c6d031e48bd0.png)
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](https://user-images.githubusercontent.com/4403937/26966101-4fcad1b2-4d2b-11e7-8be4-767ed6c45cb3.png)
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!