Google Summer of Code 2020 with Oppia
Tags: gsoc, opensource, typescript, webpack
Published: 2020-09-08 14:56:26

Oppia is a platform that enables anyone to learn and teach anything they want in an effective and enjoyable way. 

## About the project

Oppia was initially written in AngularJs (1.X) but as Angular was released, it was decided to migrate the application to Angular. Also, as Angular uses TypeScript instead of JavaScript all the content of JavaScript files was copied as it is. But as the main feature of TypeScript is `static typing`. A part of my project was to ensure type safety in the `ts` files with writing relevant unit tests and adding CI checks to ensure that this convention is followed in the future.

The other part of my project was related to webpack. In particular, the goal was to make the webpack build faster and moving some libraries currently imported using script imports to webpack


## Milestone 1

In particular, the work done in milestone 1 was

- Write type definitions for the third party libraries that didn’t have those.
- Coming up with a convention for declaring the types.
- Declare types for about 50% of the TypeScript files.

This also involved writing lint checks to ensure that the third party libs have type definitions and when a contributor upgrades the version of a library, they would also have to update the types if relevant.

The convention that was decided for naming i.e. camelCase and snake_case was the following two things

- HTTP requests should only be made only with the files suffixed with `backend-api-service.ts`
- All the HTTP backend api services should return domain objects instead of a backend dict.

So, in this milestone I covered the first part and also writing a lint check for ensuring that this convention is not broken.

### PRs involved
- [Milestone 1.1: Add a check restricting defining type as any](https://github.com/oppia/oppia/pull/9257)
- [Milestone 1.2: Type definitions for midi, skulpt, math expressions](https://github.com/oppia/oppia/pull/9266)
- [Milestone 1.3.1: Type definitions for guppy, removed blobbuilder](https://github.com/oppia/oppia/pull/9278)
- [Milestone 1.3.2: Import WaveSurfer using yarn and add typedefs for it](https://github.com/oppia/oppia/pull/9279)
- [Milestone 1.4.1: Remove some any types from typings directory](https://github.com/oppia/oppia/pull/9293)
- [Milestone 1.4.2: Split ICustomScope to respective directives](https://github.com/oppia/oppia/pull/9298)
- [Milestone 1.4.3: Add type definitions for \_\_fixtures\_\_ ](https://github.com/oppia/oppia/pull/9307)
- [Milestone 1.5: Add a check for checking the version of third party type defs](https://github.com/oppia/oppia/pull/9310)
- [Added typescript checks to pre push hook](https://github.com/oppia/oppia/pull/9334)
- [Add type definitions in some object factories](https://github.com/oppia/oppia/pull/9345)
- [Remove any types from some object factories - II](https://github.com/oppia/oppia/pull/9349)
- [Remove any from RuleObjectFactory and introduce TypeChangeService](https://github.com/oppia/oppia/pull/9365)
- [Remove any from some object factories - III](https://github.com/oppia/oppia/pull/9370)
- [Add WARNING_TYPE to interaction validation spec files](https://github.com/oppia/oppia/pull/9371)
- [Remove http requests from the files that are not backend api services](https://github.com/oppia/oppia/pull/9433)
- [Add types for Customization Args](https://github.com/oppia/oppia/pull/9463)
- [Disallow using eslint disable statement for camelcase](https://github.com/oppia/oppia/pull/9482)
- [Remove some more any types](https://github.com/oppia/oppia/pull/9544)


## Milestone 2

The work done in milestone 2 was

- Add types for other TypeScript files.
- Http backend api services should return domain objects instead of a backend dict.
- Write documentation on various TypeScript conventions used.

Along with these goals we also realised that the use of `ts-ignore` shoould also be restricted. So, I also added a lint check that restricted the use of `ts-ignore` and using `ts-expect-error` at relevant places.

Also, as the types would be in place I added the checks ensuring that `any` type is not used anymore.

### PRs involved
- [Refactor interaction type defs and some more remove any types](https://github.com/oppia/oppia/pull/9742)
- [Remove some more any types](https://github.com/oppia/oppia/pull/9754)
- [Refactor backend api services to return domain objects](https://github.com/oppia/oppia/pull/9798)
- [Upgrade version of wavesurfer and use type defs from DefinitelyTyped](https://github.com/oppia/oppia/pull/9831)
- [Remove some more any types](https://github.com/oppia/oppia/pull/9854)
- [Return a domain object in backend api services](https://github.com/oppia/oppia/pull/9883)
- [Refactor backend-api services to return domain objects](https://github.com/oppia/oppia/pull/9917)
- [Remove remaining any types and move any check to eslint](https://github.com/oppia/oppia/pull/9990)
- [Refactor backend api services and remove remaining any types](https://github.com/oppia/oppia/pull/10054)
- [Add a lint check for ts-ignore](https://github.com/oppia/oppia/pull/10088)

### Documentation
I wrote a guide on defining types and published it in Oppia wiki. You can read it [here](https://github.com/oppia/oppia/wiki/Google-Summer-of-Code-2020).

## Milestone 3

The work done in this milestone is

- Integrate dependencies into webpack.
- Increase the webpack compilation speed.
- Documentation on webpack config.
- Enable more TypeScript eslint rules.
- Setup strict type checks.

The main changes in webpack config for getting more speed were introducing `cache-loader` and use faster devtools in webpack. Also, I introduced a flag in the scripts so that developers would be still able to build using `source-maps` in webpack. The compilation time in production was reduced from around `600s` to around `300s` in Travis CI (production build). Also the compilation time for development build is less than `30s`. Due to `cache-loader` consecutive builds in both production and development evironment now take around `20s` only.

Also we thought that it would be nice to enable `strict` type checks in the TypeScript config. But the problem was the huge number of errors due to that. So, we decided to implement this rule gradually file by file. I set up that strict config and we plan to make this a `good first issue`. 

### PRs involved
- [Rename all .scripts.ts files to .import.ts](https://github.com/oppia/oppia/pull/10132)
- [Remove unneeded optional properties](https://github.com/oppia/oppia/pull/10093)
- [Move scripts imports in header to webpack](https://github.com/oppia/oppia/pull/10141)
- [Use cache-loader in webpack](https://github.com/oppia/oppia/pull/10155)
- [Introduce new eslint checks](https://github.com/oppia/oppia/pull/10187)
- [Loads libraries in manifest.json using webpack, Add a seperate light module for karma](https://github.com/oppia/oppia/pull/10223)
- [Use faster devtools in webpack](https://github.com/oppia/oppia/pull/10228)
- [Introduce more eslint checks](https://github.com/oppia/oppia/pull/10377)
- [Modifications so that guppy can be loaded using webpack](https://github.com/oppia/guppy/pull/1)
- [Modifications so that MIDI can be loaded using webpack](https://github.com/oppia/MIDI.js/pull/1)
- [Move libraries used for interactions to webpack](https://github.com/oppia/oppia/pull/10388)
- [Add some more eslint checks](https://github.com/oppia/oppia/pull/10414)
- [Add a new config for strict typescript checks](https://github.com/oppia/oppia/pull/10433)
- [Introduce new eslint rules](https://github.com/oppia/oppia/pull/10455)

### Documentation
There was documentation on webpack already. I extended it to explain how our webpack config works. You can read it [here](https://github.com/oppia/oppia/wiki/Webpack).

## Issues / Bugs found
I was also a part of release testing team in Oppia. Here are the various issues found by me while release testing and developing Oppia.

- [Drag and drop interaction doesn't work in skill preview tab](https://github.com/oppia/oppia/issues/10180)
- [Replace ngAudio with wavesurfer](https://github.com/oppia/oppia/issues/10167)
- [Irregularity in errorCallback in backend-api services](https://github.com/oppia/oppia/issues/9982)
- [Collection Editor doesn't show up correct messages](https://github.com/oppia/oppia/issues/9853)
- [Tweet has wrong text](https://github.com/oppia/oppia/issues/9708)
- [Music interaction doesn't work](https://github.com/oppia/oppia/issues/10385)
- [Question creation doesn't work](https://github.com/oppia/oppia/issues/10120)
- [Profile page doesn't sort the explorations correctly](https://github.com/oppia/oppia/issues/9914)
- [Subscriptions sort in learners dashboard doesn't work correctly](https://github.com/oppia/oppia/issues/9797)
- [Notification in preferences page](https://github.com/oppia/oppia/issues/9537)
- [Red text cannot be read in a collection when it overlaps the explo name](https://github.com/oppia/oppia/issues/9487)
- [Error while selecting to one of in param changes](https://github.com/oppia/oppia/issues/9480)

## Summary
This was an awesome learning experience working with Oppia this summer. Special thanks to [Vojtěch Jelínek](https://www.linkedin.com/in/vojtechjelinek/) who was my mentor for helping me whenever I faced any problem in completing this project. I would also like to thank Oppia for giving me this opportunity.

I would also like to acknowledge the help from other members of the community, who were always available whenever needed, just a small chat away. I strongly intend to continue contributing to Oppia.

Also, thanks to Google for this amazing program.

<hr>

### External Links

GSoC Project -> https://summerofcode.withgoogle.com/projects/#4778102950985728

Oppia Lightning Talks -> https://www.youtube.com/watch?v=9BEjYLbVyDs