React Native app, where used library/module/package with own assets. (In my case OTF fonts)
At the current moment font files simply ignored by webpack and untouched.
folder structure of the module:
node_modules/@example/module
โโโ assets
โย ย โโโ fonts
โย ย โโโ native
โย ย โโโ ExampleHeadline-Bold.otf
โย ย โโโ ExampleHeadline-Bolditalic.otf
โย ย โโโ ExampleHeadline-Light.otf
โย ย โโโ ExampleHeadline-LightItalic.otf
โย ย โโโ ExampleSans-Bold.otf
โย ย โโโ ExampleSans-BoldItalic.otf
โย ย โโโ ExampleSans-Light.otf
โย ย โโโ ExampleSans-LightItalic.otf
โย ย โโโ ExampleSans-Medium.otf
โย ย โโโ ExampleSans-MediumItalic.otf
โย ย โโโ ExampleSans-Regular.otf
โย ย โโโ ExampleSans-RegularItalic.otf
โโโ build
โย ย โโโ native
โย ย โย ย โโโ ActionIconArrowBottom
โย ย โย ย โย ย โโโ index.js
โย ย โย ย โย ย โโโ index.js.map
...
โโโ package.json
โโโ readme.md
font files should be a part of the final bundle/resources.
default
Mac Os
| software | version
| ---------------- | -------
| Haul | 1.0.0-rc.7
| react-native |
| node | 8.xx
| npm or yarn | yarn
Are those fonts referenced using a require statement in any of the bundled code? Haul will only move files to the target asset folder if they are actually required.
Same is happening to us. We were requiring images in one of our other packages, then haul wasn['t including them so I had to manually require the images somewhere within the app code itself.
Same issue happened to me.
With this line in my config file and the output below:
function addResources({ config }) {
config.module.rules[1].exclude = /node_modules(?!.*[\/\\](react|@react-navigation|@react-native-community|@expo|pretty-format|@haul-bundler|metro))/;
config.module.rules[2].test = /\.(aac|aiff|bmp|caf|gif|html|jpeg|jpg|m4a|m4v|mov|mpg|obj|otf|pdf|png|psd|svg|ttf|wav|webm|webp|dds|resource)$/i;
return config;
}
haul.config.js
...
transform: ({ config }) => {
addResources({ config });
return config;
},
warn โถ๏ธ Built with warnings in 26.59s!
warn โถ๏ธ asset size limit: The following asset(s) exceed the recommended size limit (244 KiB).
This can impact web performance.
Assets:
../node_modules/foo/en-US.json.resource (528 KiB)
main.jsbundle (1.35 MiB)
entrypoint size limit: The following entrypoint(s) combined asset size exceeds the recommended limit (244 KiB). This can impact web performance.
Entrypoints:
main (1.35 MiB)
main.jsbundle
It lists the files from the transitive import it is supposed to copy but does not copy them to the bundle directory.
I think metro's behavior is correct in this instance, and haul should be fixed to match. Having to break the encapsulation boundary of a transitively-imported packages, by importing resource files directly, would make for much more brittle code and higher maintenance burden. Ryan's example above has a first-order transitive import whose .resource assets are discovered but not copied, but I would expect even second- and third-order transitive imports to correctly find and copy/bundle the specified asset file extensions as well.
@rdy @matthargett
I've created a test case for first- and second-order transitive dependencies with assets and I cannot reproduce the issue. The tests are passing and the assets are copied to bundle output directory: https://github.com/callstack/haul/pull/661/files#diff-f820790c2f4cd4c8e0d4d500a3a8c8d0R23-R60
The structure in the fixture I'm using looks like this:
node_modules/
foo/
node_modules/
baz/
index.js (imports ./asset.png)
asset.png
index.js (imports ./asset.png, imports baz, imports bar)
asset.png
bar/
index.js (imports ./asset.png)
asset.png
App.js (imports only foo)
All those 3 assets are present in correct directories/correct filenames.
Could you compare your structure and to the one I'm using? Maybe there's something more going on. Otherwise, it would be awesome to get reproduction repository.
@zamotany I think I have a reproduction case, which might help with debugging. I can see the issue when I produce an iOS bundle, but it appears to work when I produce an Android bundle. I can only reproduce when using a monorepo, where the dependency containing the asset is hoisted.
Repro steps:
yarncd packages/HaulTestyarn haul:iosAt the root of the project there should now be a bundle directory, which contains index.jsbundle, but no assets.
Next, run yarn haul:android. In bundle there should now be a index.android.bundle file, along with the image asset under bundle/drawable-mdpi/node_modules_reacttestimport_src_assets_haul_logo_box_only.png.
Talking with @rdy offline, he noticed that the asset is served by the dev server, but not bundled. Looking at index.jsbundle I notice the following code:
a.registerAsset({__packager_asset:!0,scales:[1],name:"haul_logo_box_only",type:"png",hash:"94d5b522d6ff976a852e4d2199488358",httpServerLocation:"../node_modules/react-test-import/src/assets",height:297,width:296})}));
I'm guessing the httpServerLocation being set may be why it's working in the case where the dev server is being used.
I have refined the test and noticed that in both cases (haul e2e test and repro project) the assets __were__ extracted but to an incorrect path, so I thing that the Asset Resolver is calculating paths incorrectly.
Fixed in #661