![Page 1: CODE TO TYPESCRIPT PORTING 100K LINES OF...We tried and rejected many frameworks We use functional programming So we wrote our own libraries and frameworks + Avoided upgrade problems](https://reader030.vdocument.in/reader030/viewer/2022041121/5f34d21ce2977c07891703e5/html5/thumbnails/1.jpg)
tiny.cloud
PORTING 100K LINES OF
CODE TO TYPESCRIPT
MILLIE MACDONALD
SOFTWARE ENGINEER @ TINY
![Page 2: CODE TO TYPESCRIPT PORTING 100K LINES OF...We tried and rejected many frameworks We use functional programming So we wrote our own libraries and frameworks + Avoided upgrade problems](https://reader030.vdocument.in/reader030/viewer/2022041121/5f34d21ce2977c07891703e5/html5/thumbnails/2.jpg)
The Talk
● About Tiny and me
● The Conversion Project:
○ Motivation
○ Why TypeScript?
○ The conversion
○ Benefits, lessons learned and ongoing work
TL;DR: Types help. Gradual typing really helps.
![Page 3: CODE TO TYPESCRIPT PORTING 100K LINES OF...We tried and rejected many frameworks We use functional programming So we wrote our own libraries and frameworks + Avoided upgrade problems](https://reader030.vdocument.in/reader030/viewer/2022041121/5f34d21ce2977c07891703e5/html5/thumbnails/3.jpg)
About Tiny
● TinyMCE is a popular open source project
● A rich text editing platform that helped launch and scale the adoption of Medium, WordPress, Shopify, Tumblr, Atlassian, EventBrite & more
● In 2015, we launched a startup with offices in Palo Alto, Australia and Sweden
By the numbers:
● 1 million+ users on Cloud
● 125,000 downloads/week
● 1,200 paying customers
● 270 contributors
![Page 4: CODE TO TYPESCRIPT PORTING 100K LINES OF...We tried and rejected many frameworks We use functional programming So we wrote our own libraries and frameworks + Avoided upgrade problems](https://reader030.vdocument.in/reader030/viewer/2022041121/5f34d21ce2977c07891703e5/html5/thumbnails/4.jpg)
About Me
● From Brisbane, Australia
● Bachelor of Engineering (Honours), Software Engineering
● QA Intern then QA Engineer then Software Engineer at Tiny
● @metricjs on Github and Twitter
![Page 5: CODE TO TYPESCRIPT PORTING 100K LINES OF...We tried and rejected many frameworks We use functional programming So we wrote our own libraries and frameworks + Avoided upgrade problems](https://reader030.vdocument.in/reader030/viewer/2022041121/5f34d21ce2977c07891703e5/html5/thumbnails/5.jpg)
“100k Lines of Code”?
At the time of the conversion, TinyMCE was:
● Core = ~30k LoC
● User Interface = ~30k LoC
● 44 core plugins + several
premium plugins = ~40k LoC
Plus various other projects and libraries that get bundled in…
JS -> TS
![Page 6: CODE TO TYPESCRIPT PORTING 100K LINES OF...We tried and rejected many frameworks We use functional programming So we wrote our own libraries and frameworks + Avoided upgrade problems](https://reader030.vdocument.in/reader030/viewer/2022041121/5f34d21ce2977c07891703e5/html5/thumbnails/6.jpg)
The Conversion Project
![Page 7: CODE TO TYPESCRIPT PORTING 100K LINES OF...We tried and rejected many frameworks We use functional programming So we wrote our own libraries and frameworks + Avoided upgrade problems](https://reader030.vdocument.in/reader030/viewer/2022041121/5f34d21ce2977c07891703e5/html5/thumbnails/7.jpg)
Before
● We tried and rejected many frameworks
● We use functional programming
● So we wrote our own libraries and frameworks
+ Avoided upgrade problems and framework churn
+ Easier for us to fix problems
− FP + JS means defensive code -> code size and runtime performance issues
● Then ES6 was announced...
![Page 8: CODE TO TYPESCRIPT PORTING 100K LINES OF...We tried and rejected many frameworks We use functional programming So we wrote our own libraries and frameworks + Avoided upgrade problems](https://reader030.vdocument.in/reader030/viewer/2022041121/5f34d21ce2977c07891703e5/html5/thumbnails/8.jpg)
Motivation for the Conversion Project
● Decided to convert to ES6 in 2017
● Had been discussing alternative JS languages for a while
● Decided to do both conversions at once
● Our original wish list for an alt JS was:
○ static typing
○ pattern matching
![Page 9: CODE TO TYPESCRIPT PORTING 100K LINES OF...We tried and rejected many frameworks We use functional programming So we wrote our own libraries and frameworks + Avoided upgrade problems](https://reader030.vdocument.in/reader030/viewer/2022041121/5f34d21ce2977c07891703e5/html5/thumbnails/9.jpg)
Why TypeScript?
● We looked at ReasonML, PureScript and TypeScript● For each language we considered:
○ how much of the feature set we needed○ the learning curve○ the upfront development cost to switch
![Page 10: CODE TO TYPESCRIPT PORTING 100K LINES OF...We tried and rejected many frameworks We use functional programming So we wrote our own libraries and frameworks + Avoided upgrade problems](https://reader030.vdocument.in/reader030/viewer/2022041121/5f34d21ce2977c07891703e5/html5/thumbnails/10.jpg)
Why TypeScript?
● ReasonML
○ Trialed it by rewriting our PowerPaste plugin for TinyMCE in ReasonML, replacing complicated regex with strong types and pattern matching
+ Syntax is similar to JS so easy to learn
− Requires a full rewrite
● PureScript:
○ Was already used for some of our internal prototypes
+ Side-effect tracking speeds up code reviews and training, and optics improve runtime efficiency
− Lots of FP features we don’t need on the client side
![Page 11: CODE TO TYPESCRIPT PORTING 100K LINES OF...We tried and rejected many frameworks We use functional programming So we wrote our own libraries and frameworks + Avoided upgrade problems](https://reader030.vdocument.in/reader030/viewer/2022041121/5f34d21ce2977c07891703e5/html5/thumbnails/11.jpg)
Why TypeScript?
● Typescript
− No pattern matching
+ Vanilla JS can be valid TypeScript
+ ES6 modules == TypeScript modules
+ We were already using our own module system with a strict syntax so conversion could be done with a script
+ Types! Even better: gradual types!
![Page 12: CODE TO TYPESCRIPT PORTING 100K LINES OF...We tried and rejected many frameworks We use functional programming So we wrote our own libraries and frameworks + Avoided upgrade problems](https://reader030.vdocument.in/reader030/viewer/2022041121/5f34d21ce2977c07891703e5/html5/thumbnails/12.jpg)
What is Gradual Typing?
● Start with minimal types and add more over time
● Requires static and dynamic types - like TypeScript
● Minimal initial cost of conversion
● Flexible ongoing time/dev investment
● Can start with simple types and improve later
![Page 13: CODE TO TYPESCRIPT PORTING 100K LINES OF...We tried and rejected many frameworks We use functional programming So we wrote our own libraries and frameworks + Avoided upgrade problems](https://reader030.vdocument.in/reader030/viewer/2022041121/5f34d21ce2977c07891703e5/html5/thumbnails/13.jpg)
The How
![Page 14: CODE TO TYPESCRIPT PORTING 100K LINES OF...We tried and rejected many frameworks We use functional programming So we wrote our own libraries and frameworks + Avoided upgrade problems](https://reader030.vdocument.in/reader030/viewer/2022041121/5f34d21ce2977c07891703e5/html5/thumbnails/14.jpg)
Conversion Process for each Library
1. Run script to convert modules to ES6/TypeScript syntax
2. Manually check the script converted each file correctly
3. Update with changes from already-converted dependencies
4. Fix TypeScript problems found
5. Run and fix tests
6. Update build process
![Page 15: CODE TO TYPESCRIPT PORTING 100K LINES OF...We tried and rejected many frameworks We use functional programming So we wrote our own libraries and frameworks + Avoided upgrade problems](https://reader030.vdocument.in/reader030/viewer/2022041121/5f34d21ce2977c07891703e5/html5/thumbnails/15.jpg)
The Conversion Script
1. Transpile modules using an Abstract Syntax Tree (AST)
a. Change import syntax
b. Format body of the file correctly
c. Change export syntax and apply export default <any>
2. Move files and rename to .ts
3. Copy templates for configuration files
4. Generate Main.ts from api folder
5. Update package.json and .gitignore
![Page 16: CODE TO TYPESCRIPT PORTING 100K LINES OF...We tried and rejected many frameworks We use functional programming So we wrote our own libraries and frameworks + Avoided upgrade problems](https://reader030.vdocument.in/reader030/viewer/2022041121/5f34d21ce2977c07891703e5/html5/thumbnails/16.jpg)
Module Conversion Example
define( 'Example Module', [ ‘example.Dependency' ], function (Dependency) {
var bar = 0; var foo = function () { … };
return { foo, bar };
});
import { Dependency } from 'example';
var bar = 0;
var foo = function () { … };
export default <any> {
foo,
bar
};
![Page 17: CODE TO TYPESCRIPT PORTING 100K LINES OF...We tried and rejected many frameworks We use functional programming So we wrote our own libraries and frameworks + Avoided upgrade problems](https://reader030.vdocument.in/reader030/viewer/2022041121/5f34d21ce2977c07891703e5/html5/thumbnails/17.jpg)
Adding Types
● The script doesn’t add types
● We gradually started adding types to libraries
● We add types with each PR
○ New code must be at least partially typed
○ “If you touch it, type it” was the rule
● Invested time to fully type our most used libraries
● Now, many of our libraries are fully or at least partially typed
![Page 18: CODE TO TYPESCRIPT PORTING 100K LINES OF...We tried and rejected many frameworks We use functional programming So we wrote our own libraries and frameworks + Avoided upgrade problems](https://reader030.vdocument.in/reader030/viewer/2022041121/5f34d21ce2977c07891703e5/html5/thumbnails/18.jpg)
Benefits of TypeScript and Gradual Typing
![Page 19: CODE TO TYPESCRIPT PORTING 100K LINES OF...We tried and rejected many frameworks We use functional programming So we wrote our own libraries and frameworks + Avoided upgrade problems](https://reader030.vdocument.in/reader030/viewer/2022041121/5f34d21ce2977c07891703e5/html5/thumbnails/19.jpg)
Types
● Gained type-based tools e.g. find all usages and automated refactoring
● Compile time type checking
● Even simple types caught some serious bugs
● Typing our most used dependencies caught many more
![Page 20: CODE TO TYPESCRIPT PORTING 100K LINES OF...We tried and rejected many frameworks We use functional programming So we wrote our own libraries and frameworks + Avoided upgrade problems](https://reader030.vdocument.in/reader030/viewer/2022041121/5f34d21ce2977c07891703e5/html5/thumbnails/20.jpg)
Example Bugs
Incorrect function argument list length
Missing comment resulted in accidental global
![Page 21: CODE TO TYPESCRIPT PORTING 100K LINES OF...We tried and rejected many frameworks We use functional programming So we wrote our own libraries and frameworks + Avoided upgrade problems](https://reader030.vdocument.in/reader030/viewer/2022041121/5f34d21ce2977c07891703e5/html5/thumbnails/21.jpg)
Gradual Typing
● Allowed the team to go back to normal tasks quickly
● Able to type modules slowly and methodically by gradually removing placeholder types
● Can leave adding types until we have spare time
● Can type new code without having to type the old code around it
● Type inference tools allow for some automated typing
● Types make it easier to read and debug code, and to train new devs
![Page 22: CODE TO TYPESCRIPT PORTING 100K LINES OF...We tried and rejected many frameworks We use functional programming So we wrote our own libraries and frameworks + Avoided upgrade problems](https://reader030.vdocument.in/reader030/viewer/2022041121/5f34d21ce2977c07891703e5/html5/thumbnails/22.jpg)
Lessons Learned
![Page 23: CODE TO TYPESCRIPT PORTING 100K LINES OF...We tried and rejected many frameworks We use functional programming So we wrote our own libraries and frameworks + Avoided upgrade problems](https://reader030.vdocument.in/reader030/viewer/2022041121/5f34d21ce2977c07891703e5/html5/thumbnails/23.jpg)
Convert Common Libraries First
● Our modular architecture means we have a lot of libraries and dependencies
● We mostly converted the most used dependencies first which allowed us to cascade their types and bug fixes through other libraries
● But some other libraries were done standalone and they have duplicate type definitions, clashing types, etc.
![Page 24: CODE TO TYPESCRIPT PORTING 100K LINES OF...We tried and rejected many frameworks We use functional programming So we wrote our own libraries and frameworks + Avoided upgrade problems](https://reader030.vdocument.in/reader030/viewer/2022041121/5f34d21ce2977c07891703e5/html5/thumbnails/24.jpg)
Gradually Introduce Compiler Features
A couple times we enabled multiple new compiler features without testing them properly on the libraries...
![Page 25: CODE TO TYPESCRIPT PORTING 100K LINES OF...We tried and rejected many frameworks We use functional programming So we wrote our own libraries and frameworks + Avoided upgrade problems](https://reader030.vdocument.in/reader030/viewer/2022041121/5f34d21ce2977c07891703e5/html5/thumbnails/25.jpg)
Write a Script to Test Everything
● Write a script that does every kind of check it can - types, linting, build, tests, etc.
● Run it when you make a big change
● Ours is called the Really Cool ScriptTM
○ Contains a list of all our libraries
○ Clones each one, installs its dependencies, runs tsc and npm test
![Page 26: CODE TO TYPESCRIPT PORTING 100K LINES OF...We tried and rejected many frameworks We use functional programming So we wrote our own libraries and frameworks + Avoided upgrade problems](https://reader030.vdocument.in/reader030/viewer/2022041121/5f34d21ce2977c07891703e5/html5/thumbnails/26.jpg)
Developer Adjustments
● Discuss changes in coding style, tools and processes
● Communicate changes and their impact
● Add scripts that check types, etc. without devs having to remember complicated commands
![Page 27: CODE TO TYPESCRIPT PORTING 100K LINES OF...We tried and rejected many frameworks We use functional programming So we wrote our own libraries and frameworks + Avoided upgrade problems](https://reader030.vdocument.in/reader030/viewer/2022041121/5f34d21ce2977c07891703e5/html5/thumbnails/27.jpg)
Continuing Work
![Page 28: CODE TO TYPESCRIPT PORTING 100K LINES OF...We tried and rejected many frameworks We use functional programming So we wrote our own libraries and frameworks + Avoided upgrade problems](https://reader030.vdocument.in/reader030/viewer/2022041121/5f34d21ce2977c07891703e5/html5/thumbnails/28.jpg)
Continuing Work
● More types!
● Enabling more compiler features
● Building a type definition file for TinyMCE’s editor API
![Page 29: CODE TO TYPESCRIPT PORTING 100K LINES OF...We tried and rejected many frameworks We use functional programming So we wrote our own libraries and frameworks + Avoided upgrade problems](https://reader030.vdocument.in/reader030/viewer/2022041121/5f34d21ce2977c07891703e5/html5/thumbnails/29.jpg)
After Typescript
● Typescript is great but it is still mostly Javascript● Sometimes you really need strict types, pattern matching,
etc. to ensure code quality● So...
![Page 30: CODE TO TYPESCRIPT PORTING 100K LINES OF...We tried and rejected many frameworks We use functional programming So we wrote our own libraries and frameworks + Avoided upgrade problems](https://reader030.vdocument.in/reader030/viewer/2022041121/5f34d21ce2977c07891703e5/html5/thumbnails/30.jpg)
RTC and ReasonML
● Tiny is working on Real Time Collaboration!● Client-side is entirely in ReasonML● More info coming soon!
![Page 31: CODE TO TYPESCRIPT PORTING 100K LINES OF...We tried and rejected many frameworks We use functional programming So we wrote our own libraries and frameworks + Avoided upgrade problems](https://reader030.vdocument.in/reader030/viewer/2022041121/5f34d21ce2977c07891703e5/html5/thumbnails/31.jpg)
Check out TinyMCE!
● tiny.cloud
● github.com/tinymce/tinymce
Keep in touch:
● metricjs on Twitter and Github
![Page 32: CODE TO TYPESCRIPT PORTING 100K LINES OF...We tried and rejected many frameworks We use functional programming So we wrote our own libraries and frameworks + Avoided upgrade problems](https://reader030.vdocument.in/reader030/viewer/2022041121/5f34d21ce2977c07891703e5/html5/thumbnails/32.jpg)
Thank you!
![Page 33: CODE TO TYPESCRIPT PORTING 100K LINES OF...We tried and rejected many frameworks We use functional programming So we wrote our own libraries and frameworks + Avoided upgrade problems](https://reader030.vdocument.in/reader030/viewer/2022041121/5f34d21ce2977c07891703e5/html5/thumbnails/33.jpg)
Questions?