Google Summer of Code 2020 with Oppia
— GSoC, Webpack, TypeScript, Oppia — 4 min read
Oppia
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 typescript 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
- Milestone 1.2: Type definitions for midi, skulpt, math expressions
- Milestone 1.3.1: Type definitions for guppy, removed blobbuilder
- Milestone 1.3.2: Import WaveSurfer using yarn and add typedefs for it
- Milestone 1.4.1: Remove some any types from typings directory
- Milestone 1.4.2: Split ICustomScope to respective directives
- Milestone 1.4.3: Add type definitions for __fixtures__
- Milestone 1.5: Add a check for checking the version of third party type defs
- Added typescript checks to pre push hook
- Add type definitions in some object factories
- Remove any types from some object factories - II
- Remove any from RuleObjectFactory and introduce TypeChangeService
- Remove any from some object factories - III
- Add WARNING_TYPE to interaction validation spec files
- Remove http requests from the files that are not backend api services
- Add types for Customization Args
- Disallow using eslint disable statement for camelcase
- Remove some more any types
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
- Remove some more any types
- Refactor backend api services to return domain objects
- Upgrade version of wavesurfer and use type defs from DefinitelyTyped
- Remove some more any types
- Return a domain object in backend api services
- Refactor backend-api services to return domain objects
- Remove remaining any types and move any check to eslint
- Refactor backend api services and remove remaining any types
- Add a lint check for ts-ignore
Documentation
I wrote a guide on defining types and published it in Oppia wiki. You can read it here.
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
- Remove unneeded optional properties
- Move scripts imports in header to webpack
- Use cache-loader in webpack
- Introduce new eslint checks
- Loads libraries in manifest.json using webpack, Add a seperate light module for karma
- Use faster devtools in webpack
- Introduce more eslint checks
- Modifications so that guppy can be loaded using webpack
- Modifications so that MIDI can be loaded using webpack
- Move libraries used for interactions to webpack
- Add some more eslint checks
- Add a new config for strict typescript checks
- Introduce new eslint rules
Documentation
There was documentation on webpack already. I extended it to explain how our webpack config works. You can read it here.
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
- Replace ngAudio with wavesurfer
- Irregularity in errorCallback in backend-api services
- Collection Editor doesn't show up correct messages
- Tweet has wrong text
- Music interaction doesn't work
- Question creation doesn't work
- Profile page doesn't sort the explorations correctly
- Subscriptions sort in learners dashboard doesn't work correctly
- Notification in preferences page
- Red text cannot be read in a collection when it overlaps the explo name
- Error while selecting to one of in param changes
Related Links
For those more curious about this project, do checkout the following links.
Summary
This was an awesome learning experience working with Oppia this summer. Special thanks to Vojtěch Jelínek 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.