## Problem
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.
# Libraries get duplicated into multiple repositories.
# Libraries need to be manually registered with PHP code and conditionals. [Example 1](https://github.com/wikimedia/mediawiki-extensions-TemplateData/blob/84ef237bde0830653d7b483e82bf5c06533d39e8/TemplateDataHooks.php#L46-L62), [Example 2](https://github.com/wikimedia/mediawiki-extensions-VisualEditor/blob/3ccfacf7f9f5db9bd19413f49be3d3f0dfd61541/VisualEditor.hooks.php#L876-L886).
# It is hard to know which version is currently in Git (manually inspect source files and/or git commit log)
# Libraries are difficult to update (canonical 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 [[https://github.com/nodesecurity/nsp|nsp]])
## Requirements
**We want to:**need the following:**
# T# Method for tracking names and versions of 3rd-party javascript libraries. Something like //composer.json// or //package.json// or //extension.json//
# Fetch dependencies from their external source(s) in an automated fashion.
# Register modules (and possibly their dependencies) with ResourceLoader.
# (optional) Deduplicate libraries/flattened dependency trees.
# (optional) Pin versions - Predictable versions used of libraries based on something like a lock file or shrinkwrap file committed to Git.
**Use case:**
* Add two package names and versions to `<a file>`, where B depends on AMethod for fetching dependencies from their external source(s).
* Run `<some command>`# Decide whether to store them in Git, and whether to do so always and in local repos, or for production/tarball only in a central repo.
* (optional) R# Decide how to register names modules (and filespossibly their dependencies) with ResourceLoader.
* Package B can call `require('a')`.# (optional) deduplication of libraries/flattened dependency trees
* Our own code can call `require('b');
**We don't want:**
# Deployment can only depend upon stuff that's in git - nothing external.
# Tarball must not require running npm.
**Difficulties:**
1. Whether to store them in Git, and whether to do so always and in local repos, or for production/tarball only in a central repo# (optional) predictability of versions used of libraries based on something like a lock file or shrinkwrap file committed to Git.
**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.
See also: {T174922}