It was very smooth for us because we prepared in advance. We followed the advice of the core team and didn’t use native code. Well, we had a native code but we abandoned it at an early stage. We used special functions instead of toString so we don’t have to change it at the upgrade stage. We wrote “future” functions to work with dates to have a smooth upgrade (Thank for @justinmimbsdate package). The only obstacle in our way was time to wait until all the dependencies are updated. The conclusion is if the future plan is known and the advice of the core team is followed then upgrade is straight forward.
Thank you @evancz, the core team and the community. It’s a pleasure to work with Elm and to be a part of the community.
Appendix
We use a slightly modified version of an outer message a.k.a. shared state, a.k.a Elm taco technique to manage common/shared functionality between pages. It’s really great. Please comment below or add a like if you would like us to share more about it.
It looks like a little over 50% of your Elm code is generated. What is the generated code used for?
Answer:
We have 6 generated Elm files.
We share enums between backend and frontend. In our case backend defines enums. Backend generates a JSON file and we use it on the frontend. For Elm, we convert the JSON file to an Elm module with generated custom types, decoders, encoders and functions to convert an enum to the enum value (e.g. string or integer)
We have a generated file with environment-dependent constants (e.g. API URL)
In our app, each page has a header with an icon. There is a generated Elm module with a custom type for header icons and a function to get an icon path. It’s just a way to have type-safe header icons.
There is a file with generated backend API endpoints. Backend exposes a JSON file with all the endpoints and we generate an Elm module from that. So we can be in sync with backend in term of API endpoints.
In our app, AngularJS manages the routing. There is a file with generated URLs and page names which we can use from Elm to communicate with AngularJS when we want to change a page.
There is a file with all the translations generated from JSON file so we can get type safety for translations.
We use elm-analyse at work but it does not have a way to extend it with custom rules. For company-specific rules, we wrote a simple linter. E.g. we have the rule to disallow usage of regex and force to make a parser instead. Or we disallow exposing for anything when importing a module to enforce developers to use module prefixes for functions (e.g. Html.div, Decode.string, etc…). Or we force every top-level function to have documentation.
The same question our manager asked me We had a talk with @stil4m (the author of elm-analyse) and as I remember a way to extend elm-analyse with custom rules may come in the future release. But if it’s interesting for the community we can open source it. I’ll open a separate thread for that.
How is the logic distributed between the (angular) js application and the elm application? What influenced that distribution the most? And are you planning to change that distribution in the future? (what parts of your application went where and why)
In short, the distribution is following, all new code is written in Elm and all serious refactoring of existing code is done in Elm as well. Where serious means e.g. new version of the component which requires a “fundamental” rewrite. So we maintain two code bases.
What influenced that distribution the most?
We don’t want to rewrite existing AngularJS application to Elm from scratch. We want to come to that point naturally.
And are you planning to change that distribution in the future?
Now we have pretty heavy communication between AngularJS and Elm. It works very well for us. And we are moving towards Elm in all possible ways.
What parts of your application went where and why?
Routing is done in AngularJS. Because Elm routing would require a significant rewrite. It would be possible to move the Elm routing sometime in the future I think. The rest is in short story below.
We started to integrate Elm when we had big AngularJS code base already. There was a task to create a new AngularJS component with autocompletion functionality. It was done in Elm and wrapped with AngularJS component. So it felt natural for AngularJS application.
Then there was a task to create a new page. A page in our app may have any of the following parts:
Header
Alert boxes for system notifications
Tabs
Modal dialogues
We created a page manager in Elm which manages all of the page parts and the page program itself only manages the page content. All new pages will be created in Elm from now on. I’ll create a separate thread about page manager. In AngularJS we have components for each part as well. In Elm, it’s more clear and easy though.
Then there was a task to reuse some of the existing AngularJS components in Elm. So we don’t have to spend time rewriting them. We created an AngularJS service to do so.
This is a current situation, please let me know if I answered your questions and if you have any other questions.
We are writing Gulp tasks ourselves because Gulp was used already for other parts of the app. Most of the time the process is the same. Read JSON file, take the information, construct an Elm module and write it to the file.