- Affected components: TBD.
- Engineer(s) or team for initial implementation: TBD.
- Code steward: TBD.
Motivation
We should have an equivalent for JavaScript to what we have with Composer for PHP. A simple way to manage dependencies and fetch required JavaScript code automatically.
Both MediaWiki core and extensions depend upon various 3rd party javascript libraries. We currently don't have a way to manage those dependencies.
Who will benefit:
- Developers: Development efficiency
- More predictable and maintainable code due to reduced code complexity
- Less worries about conflicts across different MW extensions and a simple way to share JS code between them
- Security: Simpler to keep an eye on security issues in 3rd party libraries and to deal with them
- Possibly, WMF Deployment team.
Problems
- Libraries get duplicated into multiple repositories.
- Libraries need to be manually registered with PHP code and conditionals. Example 1, Example 2.
- It is hard to know the current version of a library in Git (manually inspect source files and/or git commit log)
- Libraries are difficult to update (location of external source varies, typically one or more JS files downloaded from the libraries' official web site)
- There is no easy way to automatically scan for vulnerabilities (via something like nsp)
- Libraries are hard to register with ResourceLoader (each shipped file needs to be listed)
Requirements
- Libraries should ideally be deduplicated libraries/flattened dependency trees.
- Library versions should be pinned, and not subject to a version range or dependency tree that is unpredictable or can vary over time, e.g. commit lock file or shrinkwrap file to Git.
- Deployment must only depend on stuff that's in git - nothing external.
- Tarball must not require running npm.
- We need to be able to patch libraries in cases of emergencies (or major regressions) without waiting on a new upstream release
User story: Add an external package with a dependency to MediaWiki core, or an extension, as follows:
- Add two package names and versions to <a file>, where B depends on A.
- Run <some command>.
- (optional) Register names and files with ResourceLoader.
- Package B can call require('a');.
- Our own code can call require('b');.
Exploration
(TBD: Use this space for data gathering, status quo, proposals, other considerations etc.)