Closed jeaye closed 7 years ago
Unfortunately, after refactoring to work around this issue, I've run into a design problem deeper than just the template: .re-natal
also assumes the sources are laid out this way.
Give an adapted structure like this (following typical Leiningen profile practices):
$ env/
├── android
│ ├── dev
│ │ └── env
│ │ └── android
│ │ └── main.cljs
│ └── prod
│ └── env
│ └── android
│ └── main.cljs
├── dev
│ └── user.clj
└── ios
├── dev
│ └── env
│ └── ios
│ └── main.cljs
└── prod
└── env
└── ios
└── main.cljs
15 directories, 5 files
When I try to run my normal build cycle:
$ re-natal use-figwheel
Cleaning...
index.ios.js was regenerated
index.android.js was regenerated
Host in RCTWebSocketExecutor.m was updated
ENOENT: no such file or directory, open 'env/dev/env/ios/main.cljs'
So it looks like something more fundamental will need to change for this. How people are running non-trivial apps with custom initialization per-platform, or without double initializing each startup is still unclear. It seems to me that everyone is affected.
True, unfortunately at the moment project structure is not very flexible. Some of of functions of re-natal needs to access env/dev env/prod files. Maybe it is possoble to refactor and introduce more fine-grained configuration for the paths in .re-natal. Have no good ideas at the moment.
Forcing this layout is not the problem; it's a reasonable layout that separates platform-dependent code from the shared code under src/
. The only issue is that the layout is forced, but the code isn't actually separated. Android is still going to run the iOS code at startup, and vice versa. That's a big issue, which is much more important than allowing the project layout to be flexible (since it means most people are initializing their apps twice and it also means there's not actually a way to have platform-dependent code using re-natal).
I'm hoping you'll address this, since it's the focus of this ticket. Me trying to rework the layout was just an attempted fix.
@jeaye not sure if I understand this correctly but did you prove that both iOS and Android apps are running on startup?
AFAIK they are both being compiled but only the selected target is run due to the use of :main "env.android.main"
. Everything else should be strip away by the compiler since it is not reachable from the main
namespace.
Yeah, I proved it by commenting out the iOS code that was running on startup and seeing my double initialization go away. The same should be possible by following the barest re-natal template, which I can do to further minimize the problem space.
After having tried this on a bare template, I'm able to reproduce the problem in production builds only IFF I make some changes to the project.clj
. As it is, I'm wrong that the re-natal template is broken out of the box. Alas, it seems to rely on some behavior which the ClojureScript docs say doesn't exists, so I think we need to tread very carefully.
@carocad's reply was very helpful, reminding me that :main
is used to determine the entry point. Guess what happens when :main
does exist for production builds with re-natal: both iOS and Android mains get executed. So, the simple fix is to add :main
back into our production builds. Why was it removed?
project.clj
has quite a bit of error-prone duplication, so we refactored it, following the cljsbuild docs and ClojureScript docs, so that the common bits are shared:main
isn't used when optimizations are enabled, so it was removed from the production profilesI think, going forward, re-natal could likely verify that a :main
exists, even in production, if it's requiring the key in order to behave as expected.
Thanks for prompting me to look deeper, @carocad.
As defined by the
:source-paths
here: https://github.com/drapanjanas/re-natal/blob/master/resources/project.clj#L20 there is an issue where prod builds will runenv.android.prod
andenv.ios.prod
on startup. Similarly, dev builds will runenv.android.dev
andenv.ios.dev
on startup. This is because both Android and iOS sources are grouped underenv/dev
orenv/prod
.Here's an example, as per the README: