Closed jamesnyika closed 5 years ago
Ok. Found a solution to this.
The user.clj file generates the index.js file under target/expo/env/index.js .
In that file (user.clj) is a line (#120 as of the writing of this comment) that generates a js/require statement for figwheel. This is why it is all in quotes.
This is done early on when preparing the dev environment for figwheel to work and the generated build to run on your device or simulator. I wish @seantempesta could do a writeup someday to explain what all the pre-work does so that we can help better maintain this fabulous template :stuck_out_tongue_winking_eye:
For some reason that i have not yet devined, the line #120 in env/dev/env/user.clj that says
(js/require "figwheel-bridge")
no longer functions to load up figwheel bridge or to find the .js file. You need to now specify the path to the .js file directly.
I am not sure if the change is due to a new react-native or expo.io change, but this file is not being loaded.
To fix portion on line 120 that says
(js/require "figwheel-bridge")
to
(js/require "../../../js/figwheel-bridge")
Everything else should work perfectly otherwise.
You might want to see another issue I had to fix when doing this upgrade too here (bug 74)
This fixes dev builds. If it affects prod I will update this comment otherwise assume it fixes both.
@seantempesta
I would appreciate your thoughts on this fix and if you have a better solution to offer. For now this helped me keep moving. Thank you for everything you do for this project.
Huh. That's strange. I guess the search path was changed and it's no longer picking it up? I'm reopening the issue until I can patch this.
Thank you @jamesnyika for tracking this bug down!
@seantempesta Well... I have worse news... At least dev work will work out ok. But the production build will not work at all.
When you upgrade to Expo 31, everything builds fine but you get this terrible error that I have a spent a week trying to track down.
Changing your production build optimizations to :simple
or :none
works fine for the use cases I tried (my application and a brand new application created using this template). However, :advanced
optimizations break completely with very little information to track down the problem.
I thought the problem might have been the google closure compiler producing code with missing externs or symbols being munged and not being seen but the same code with a different (older version of the EXPO SDK - I tried SDK 26) works just fine. So that is probably the wrong path. So I am firmly of the opinion it is either something the @expo team put in that is causing closure optimized code to fail.
This first portion installs expo 26 I believe.
lein new expo comp +reagent
. Perform the requisite yarn
or yarn install
to install node modules. lein prod-build
expo start -c
Watch and it will load up perfectly.
Upgrade to expo 31
{
"name": "comp",
"version": "0.0.1",
"description": "",
"author": "",
"private": true,
"main": "main.js",
"dependencies": {
"expo": "^31.0.5",
"react": "16.5.0",
"react-native": "https://github.com/expo/react-native/archive/sdk-31.0.1.tar.gz",
"create-react-class": "15.6.3"
}
}
and project.clj is
```` clojure
(defproject comp "0.1.0-SNAPSHOT"
:description "FIXME: write description"
:url "http://example.com/FIXME"
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}
:dependencies [[org.clojure/clojure "1.9.0"]
[org.clojure/clojurescript "1.10.238"]
[binaryage/oops "0.5.8"]
[reagent "0.7.0" :exclusions [cljsjs/react cljsjs/react-dom cljsjs/react-dom-server cljsjs/create-react-class]]
[re-frame "0.9.3"]
[react-native-externs "0.1.0"]]
:plugins [[lein-cljsbuild "1.1.4"]
[lein-figwheel "0.5.14"]]
:clean-targets ["target/" "main.js"]
:aliases {"figwheel" ["run" "-m" "user" "--figwheel"]
; TODO: Remove custom extern inference as it's unreliable
;"externs" ["do" "clean"
; ["run" "-m" "externs"]]
"rebuild-modules" ["run" "-m" "user" "--rebuild-modules"]
"prod-build" ^{:doc "Recompile code with prod profile."}
["with-profile" "prod" "cljsbuild" "once" "main"]}
:profiles {:dev {:dependencies [[figwheel-sidecar "0.5.14"]
[com.cemerick/piggieback "0.2.1"]]
:source-paths ["src" "env/dev"]
:cljsbuild {:builds [{:id "main"
:source-paths ["src" "env/dev"]
:figwheel true
:compiler {:output-to "target/expo/not-used.js"
:main "env.expo.main"
:output-dir "target/expo"
:optimizations :none}}]}
:repl-options {:nrepl-middleware [cemerick.piggieback/wrap-cljs-repl]}}
:prod {:cljsbuild {:builds [{:id "main"
:source-paths ["src" "env/prod"]
:compiler {:output-to "main.js"
:main "env.expo.main"
:output-dir "target/expo"
:static-fns true
:externs ["js/externs.js"]
:infer-externs true
:parallel-build true
:optimize-constants true
:optimizations :advanced
:closure-defines {"goog.DEBUG" false}}}]}}})
and app.json to this
{
"expo": {
"name": "comp",
"description": "No description",
"slug": "comp",
"sdkVersion": "31.0.0",
"version": "1.0.0",
"orientation": "portrait",
"primaryColor": "#cccccc",
"privacy": "public",
"icon": "./assets/icons/app.png",
"splash": {
"image": "./assets/icons/loading.png",
"resizeMode": "contain",
"backgroundColor": "#ffffff"
},
"ios": {
"supportsTablet": true
}
}
}
rm -fr $TMPDIR/metro*
and yarn cache clean
before running yarn
lein prod-build
expo start -c
:simple
optimizations. However, what I really want from :advanced
optimizations is the dead code elimination and compactness because i am deploying on much older devices that may be more constrained in memory and space.please help if you can @seantempesta @expo @jigkoxsee
@jigkoxsee might have some information because that fork seems to be at SDK 30. What are you doing different ?
thanks
I've seen that type of error before and it's unrelated to Expo. Unless you are super careful it's really easy to break applications in general with advanced compilation. Are you using a library like cljs-oops
for accessing javascript objects?
I am using [binaryage/oops "0.6.4"] Can you describe the precise problem with these libraries..should I just remove them and find another way around doing what I wanted to do ?
Luckily it is only one place I am using the ocall function (right in my core.cljs file - to register the root component) . What other libraries might cause trouble... here is my project.clj file
(defproject giguptal "0.9.5"
:description "Test of RN"
:url "http://none.com"
:license {:name "No License - All rights Reserved"
:url "http://none.com"}
:dependencies [
[org.clojure/clojure "1.9.0"]
[org.clojure/clojurescript "1.10.439"]
[org.clojure/core.async "0.4.490"]
[com.andrewmcveigh/cljs-time "0.5.2"]
[com.lucasbradstreet/cljs-uuid-utils "1.0.2"]
[io.replikativ/hasch "0.3.5"]
[com.taoensso/timbre "4.10.0"]
[binaryage/oops "0.6.4"]
;;[cljs-info "1.0.0"]
[com.rpl/specter "1.1.2" :exclusions [org.clojure/clojure org.clojure/clojurescript]]
[reagent "0.7.0" :exclusions [cljsjs/react cljsjs/react-dom cljsjs/react-dom-server cljsjs/create-react-class]]
[reagent-utils "0.3.1"]
[re-frame "0.10.6"]
[posh "0.5.5"] ;; DO NOT UPGRADE> NULL exception in v5.6 beware
[datascript "0.17.0"]
[org.clojure/core.match "0.3.0-alpha5"]
[tongue "0.2.4"] ;; provides translation for i18n purposes
[cljs-react-navigation "0.1.3"]
[react-native-externs "0.2.0"]
[haslett "0.1.2"] ;; websocket library for CLJS
[re-frisk-remote "0.5.5"] ;; need this for viewing contents of the app db
[shodan "0.4.2"] ;; used to pretty print the logs
]
:plugins [[lein-cljsbuild "1.1.4"]
[lein-figwheel "0.5.14"]
[lein-kibit "0.1.5"]
[lein-ancient "0.6.15"]
[lein-re-frisk "0.5.8"]
;;we have lein-re-frisk in our ~/.lein/profiles.clj
]
:clean-targets ["target/" "main.js"]
:aliases {"figwheel" ["run" "-m" "user" "--figwheel"]
; TODO: Remove custom extern inference as it's unreliable
;"externs" ["do" "clean"
; ["run" "-m" "externs"]]
"rebuild-modules" ["run" "-m" "user" "--rebuild-modules"]
"prod-build" ^{:doc "Recompile code with prod profile."}
["with-profile" "prod" "cljsbuild" "once" "main"]}
;;do not change the dependencies below for figwheel. Seems to break something
:profiles {:dev {:dependencies [[figwheel-sidecar "0.5.14"]
[com.cemerick/piggieback "0.2.1"]]
:source-paths ["src" "env/dev"]
:cljsbuild {:builds [{:id "main"
:source-paths ["src" "env/dev"]
:figwheel true
:compiler {:output-to "target/expo/not-used.js"
:main "env.expo.main"
:output-dir "target/expo"
;;:recompile-dependents false
:preloads [re-frisk.preload]
:optimizations :none}}]}
:repl-options {:nrepl-middleware [cemerick.piggieback/wrap-cljs-repl]}}
:prod {:cljsbuild {:builds [{:id "main"
:source-paths ["src" "env/prod"]
:compiler {:output-to "main.js"
:main "env.expo.main"
:output-dir "target/expo"
:static-fns true
:externs ["js/prod_externs.js" "target/expo/inferred_externs.js"]
:infer-externs true
:parallel-build true
:optimize-constants true
;:source-map "main.js.map"
:pseudo-names true
:pretty-print true
:optimizations :simple
:closure-defines {"goog.DEBUG" false}}}]}}})
@seantempesta .. it also does not explain why a new application fails to load in the simulator with Expo 31 but is fine on Expo 26. I have also use the oops library since expo 26 and been able to publish just fine. I think it is a likely candidate for this failure but I can't help but feel there is something else that has happened. Anyway, .. give me some ideas of what you would try or if you know the fix.. super..
After investigating this a little further.. the following production profile seems to work. By work here I mean that you can run expo publish and you will be able to see your app on your mobile device in the expo client:
...
:prod {:cljsbuild {:builds [{:id "main"
:source-paths ["src" "env/prod"]
:compiler {:output-to "main.js"
:main "env.expo.main"
:output-dir "target/expo"
:static-fns true
:externs ["js/externs.js"]
:infer-externs true
:parallel-build true
:optimize-constants true
:optimizations :simple
:closure-defines {"goog.DEBUG" false}}}]}}})
When using the simulator, you need to have the Production mode set to DEV for the simulator to load your main.js if it has advanced optimizations.
I am truly at a loss here as to whether it is something on the @expo side or if this is something to do with clojurescript recent changes.
@seantempesta : if someone is running this application and it has simple compilations, do you know if there is any way they can get to the js code ? I just do not want someone being able to view and understand the google closure generated files.. or worse, I do not know if my cljs files converted into js files are also uploaded as part of the bundle..
Hi @jamesnyika I'm trying to update a cljs app from expo 26 -> 32 and the stuff you've found out has been invaluable. I'm also stuck at 'Can't find variable: a'.
If you want to find the bundled js code for your app, I managed to find it by running in the android studio emulator, and using adb logcat
to find
03-02 17:49:21.944 18675 19484 D b : Got cached OkHttp response for https://d1wp6m56sqw74a.cloudfront.net/%40XXXX%2FXXXXX%2F0.1.2%2Fd5ec14d0e914b44f476da6c62014bd51-32.0.0-android.js
Please do let me know if you make any more progress on this.
I think https://github.com/expo/expo/blob/master/CHANGELOG.md#-breaking-changes-2 might be involved, and that
(def expo (js/require "expo"))
(defn init []
(dispatch-sync [:initialize-db])
(ocall expo "registerRootComponent" (r/reactify-component app)))
isn't an acceptable way to call registerRootComponent any more
ok after some begging in the Expo Developers Slack, I discovered that changing node_modules/metro/src/JSTransformer/worker.js
with
--- worker.js 2018-11-21 14:46:01.271844624 -0700
+++ worker.js 2018-11-21 14:45:52.517615272 -0700
@@ -218,7 +218,7 @@
}
if (!options.transformOptions.dev) {
- plugins.push([constantFoldingPlugin, opts]);
+ // plugins.push([constantFoldingPlugin, opts]);
plugins.push([inlinePlugin, opts]);
}var _transformFromAstSync =
solves the prod-build 'Can't find variable: a'. problem @titonbarua
@a-j-douglass, @titonbarua I apologize for the delay... I was working some other stuff for a bit. I have not found a way past the problem of advanced compilation. I am stuck at deploying code that only uses :whitespace or :simple.
@seantempesta is probably the only one who can help. I even tried using shadow-cljs to compile - thought it might have to do with how dependencies were being included or arranged but no. Something changed.. but do not know what. Please post here if you find a solution.
@jamesnyika Just wanted to say huge thanks for meticulously detailing the fixes necessary for upgrading to Expo 31.0. I've just had to do it myself and wouldn't know where I'd be if I didn't come across this issue and your thorough investigation
@alexdao3 and @jamesnyika Is there any way you could please post an example project that works with Expo 31 SDK? That would be very helpful. Thank you.
@robert-Johansson I do not have one I can share because they were proprietary. Best suggestion is to use the project.clj file I posted and changes I suggested without advanced compilation and using a minimalist screen or page. However there is a better path... using shadow-cljs. Shadow now can generate output for react native and there is an example minimal app as part of his examples repo. That is the path I took
@jamesnyika That's a great suggestion! Thanks to your advice I found this repository too, looks very nice: https://github.com/PEZ/rn-rf-shadow
Hi @jamesnyika !
This issue can be closed since I have upgraded all dependencies in this PR https://github.com/seantempesta/expo-cljs-template/pull/81.
Best regards.
Fixed via #81. Thanks again @PrestanceDesign!
Thank you all!!!!
On upgrading to Expo 31 SDK, the following error occurs
Unable to resolve module
figwheel-bridge
from/Volumes/DEVSYS1/apps/giguptal/target/expo/env/index.js
: Modulefigwheel-bridge
does not exist in the Haste module mapThis might be related to https://github.com/facebook/react-native/issues/4968 To resolve try the following:
watchman watch-del-all
.node_modules
folder:rm -rf node_modules && npm install
.rm -rf /tmp/metro-bundler-cache-*
ornpm start -- --reset-cache
.rm -rf /tmp/haste-map-react-native-packager-*
.ABI31_0_0RCTFatal __37-[ABI31_0_0RCTCxxBridge handleError:]_block_invoke _dispatch_call_block_and_release _dispatch_client_callout _dispatch_main_queue_callback_4CF CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE __CFRunLoopRun CFRunLoopRunSpecific GSEventRunModal UIApplicationMain main start 0x0
While it looks like a classic cache clearing problem, it does not seem to be so. Any ideas on how it can be resolved ?
thanks