Guest Post: Ionic 4.0 Migration Using TSLint Fixers
It was almost a year ago at Ng-Conf, when I sat in on a session about TypeScript. One of the speakers that caught my attention was Alex Eagle, a software engineer at Google on the angular-core team, who shared an update about Google’s plan to integrate a new version of TypeScript internally before releasing it to the public.
This was of particular interest to me at the time because I had been working with our architecture team at SpaceX and the adoption of new architecture components had always been a pain point for us. When I discussed this issue with Alex, he explained that his team had been using TSLint fixers (more on those in a bit) to roll out changes to their projects’ code, which got my wheels turning on how I could implement TSLint in my own projects.
During this time, Ionic 4 Beta had just been announced and while the breaking changes list wasn’t much compared to the Ionic 1 to 2 upgrade, it still took a few hours for the migration to complete and left a bit of room for error in what was a fairly small app. It was during this period that I decided to test out using TSLint fixers to perform this migration for me.
Using the fixers
I’m happy to say what came out of this endeavor was the creation of the Ionic 4 Migration tool, which you can use similarly to how you would use the normal TSLint rules. Here are the steps:
- Upgrade your project to use the latest Ionic version, which was RC1 at the time of this blog post draft. You should now have a bunch of errors if you try to compile.
- Install the rule-set using
npm i -D @ionic/v4-migration-tslint. You will also want to add a file to the root of your project named ionic-migration.json and add the configuration below.
- Run the analyzer to identify all of the changes you will need to make in your code using
tslint -c ionic-migration.json -p tsconfig.json. Bonus: We implemented a bunch of fixers to automatically correct most of the breaking changes, which you can use by adding the
--fixflag to the end of the command. (Tip: Be sure your project is backed up or stored in source control just in case anything unexpected occurs.)
Limitations of the tool
Unfortunately, there were still a few changes that we were unable to automate—A big chunk of which had to do with CSS changes. This is because stylesheets are a bit more flexible, making it hard to identify a common pattern to apply across the migration tool. We also had some cases like the Ion Menu Toggle where the DOM changes were incredibly complex and had to be fixed on a case by case basis.
Lastly, during this process, there were some breaking changes where methods returned promises. While the documentation specifies that async/await should be used to execute this, we found that people were using .then() instead or they would return the promise directly from their method instead of waiting and returning the result. Because the syntax for handling promises can be so varied, we decided to not implement a fixer for these rules, and instead rely on warnings.
Overall, we found these limitations to be pretty minor and most of the tedious changes should be covered with this tool. To see what changes are covered by fixers, head to the repo page to view all of the rules with each rule containing a link to its section of the Breaking Changes page.
How does it work?
This tool is built on top of TSLint which is a static analysis tool that takes advantage of the TypeScript AST(Abstract Syntax Tree) parser. We also used Codelyzer, which is an Angular-specific implementation of these rules and includes some very helpful utilities for parsing Angular-specific components, if needed.
Each rule generally has a single target. For example: In the case of ion-button, we had to find places where ion-button existed as an attribute and then replace the element on which it was annotated. We did this by first visiting every element in the DOM tree and looked for any attributes that matched ion-button. If we found a match, we extracted the element’s content and replaced the element with a new ion-button, which had the contents of the previous element.
Ready, set, go (upgrade your app)!
I look forward to seeing how others use this tool and hope it will help you or your team’s projects when converting to Ionic 4.0. And, if you’re interested in trying to build out some of the remaining fixers, please check out the repo and feel free to submit a PR!
I’d like to thank Dan Imhoff and Mike Hartington for their help on this project—Thanks to them, our team was able to get this project over the finish line quickly and easily. Can’t wait to see what you guys build. Happy coding!