There are [[ https://www.mediawiki.org/wiki/Vue.js#Two_ways_to_parse_Vue.js_templates | two ways to process Vue.js templates ]] in MediaWiki: a build step and on-the-fly compilation. Which should we we use for this project? That's what this task decides.
== Acceptance criteria
- [] A decision to use a build step, on-the-fly compilation, or both is made.
- [] At least one new task is created to implement the choice(s) //and// add Vue.js as a dependency.
- [] [[ https://www.mediawiki.org/wiki/Vue.js | Documentation on wiki ]] is revised with any learnings.
- [] Feedback on this decision is solicited in the [[ https://phabricator.wikimedia.org/T249426 | developer survey]]. (This means adding some nicely formed question(s) to the survey task.)
== Build step
**Summary: the most performant, flexible, and least risky option, but more upfront work.**
=== Pros
- The most performant byte sizes and rendering. This derisks a major concern for the project as much as possible.
- Web has the experience (e.g., [[ https://gerrit.wikimedia.org/r/plugins/gitiles/mediawiki/extensions/Popups/+/a63a1cf/webpack.config.js | Popups ]], [[ https://gerrit.wikimedia.org/r/plugins/gitiles/mediawiki/extensions/MobileFrontend/+/01d3f48/webpack.config.js | MobileFrontend ]], and [[ https://gerrit.wikimedia.org/r/plugins/gitiles/mediawiki/skins/Vector/+/ea2bcd4/.storybook/webpack.config.js | Vector Storybook ]]) to define good patterns for the broader organization.
- Sharing the bundler configuration may allow some commonization of Web's existing six Webpack configs.
- Immense flexibility to leverage any tool in the JavaScript ecosystem. A build step, formal or otherwise, enables an extraordinarily useful abstraction between the code written by developers and the bytes shipped to users. A build step is a gateway to the entire wealth of tooling in the JavaScript ecosystem second only to `package.json` itself.
- Provides additional flexibility for aggregating and splitting dependencies within projects.
- There are no limitations on the Vue.js code written. That is, all source will be canonical Vue.js, not MediaWiki-specific Vue.js. This meets the expectations of newcomers and developers interested in using our components in non-MediaWiki contexts.
- Developer productivity boost via hot module replacement functionality. In @santhosh's words, "Cannot even compare it with the debug=true mode of development speed :-)"
- //Local// build steps have historically had excellent production success.
- SVGs can be optimized by Webpack before shipping ([[ https://wikimedia.slack.com/archives/G8QAPHCTT/p1581431206221200?thread_ts=1581384897.217200&cid=G8QAPHCTT | agreed upon internally as an understood expectation ]]).
- This is a non-binary decision. It's more accurately put ResourceLoader _and_ build step since the outputs of the build step just feed back into ResourceLoader.
=== Cons
- Clumsy asset versioning. Plain and simple: we know this song and dance well but it is a friction until [[ https://phabricator.wikimedia.org/T199004 | the build step RFC ]] is complete. More specifically, most JavaScript patches will create merge conflicts, we have to make another copy of our dist test script, and our Git history is polluted with build products. This friction hurts newcomers especially.
- Requires extra configuration by Web to set good patterns for other interested teams.
- Sharing the bundler configuration requires further additional work.
- Limited by whatever the MediaWiki ecosystem can provide.
- Requires additional consideration for sharing dependencies across projects (e.g., runtimes).
- Code has to be built before changes appear. If you forget or are unable to build the code, you don't get the code.
- If only a build step is used, no feedback is provided on the on-the-compilation implementation.
- The build step RFC isn't even done yet.
=== Example Webpack configuration
```lang=json
{
"entry": "./resources/skins.vector.js/skin.js",
"output": {
"filename": "skins.vector.js"
},
"externals": [
"mediawiki.page.ready"
]
}
```
== On-the-fly compilation
**Summary: less performant and inflexible, but very little upfront work.**
=== Pros
- Minimal configuration. Build step tooling is always a pain to configure properly but on-the-fly supports very little configuration.
- Less maintenance. Build-step specific tooling requires periodic upgrades. On-the-fly compilation is part of Core.
- All code written is most likely to work in any MediaWiki context.
- This workflow is supported by at least two Foundation developers and may be the mechanism used by gadgets and tools unable to use a build step.
- The version of Less used must match MediaWiki's version. Everything that works in normal MediaWiki styles works here (e.g., [[ https://www.mediawiki.org/wiki/CSSJanus | CSSJanus ]], relative URLs, imports, etc).
- Possibly the standard MediaWiki way to build Vue.js apps.
- Additional limitations for on-the-fly compilation may be uncovered during development. That's exactly the kind of thing FAWG should know about sooner rather than later.
=== Cons
- All code written is less likely to work in any non-MediaWiki context.
- [[ https://vue-loader.vuejs.org/guide/scoped-css.html | Scoped styles ]] are unsupported.
- What you write is what you ship--No ES6, TypeScript, or language compilation support. At time of writing, this means ES5 only.
- [[ https://vuejs.org/v2/guide/syntax.html#Shorthands | Vue.js directive shorthands ]] are unsupported `@` for `v-on` and `:` for `v-bind`.
- This tooling is early in development by and for MediaWiki, but not as well tested as Webpack.
- The version of Less used must match MediaWiki's version (very old).
- Definitely the non-standard way to build Vue.js apps for the rest of the world.
- Additional limitations for on-the-fly compilation may be uncovered during development. That hurts product development.
- If only on-the-fly compilation is used, no feedback is provided on the build step implementation.
- SVGs must be committed minified or delivered to the client in "debug mode."
=== Example ResourceLoader configuration
```lang=json
"skins.vector.js": {
"packageFiles": [
"resources/skins.vector.js/skin.js",
"resources/skins.vector.legacy.js/collapsibleTabs.js",
"resources/skins.vector.legacy.js/vector.js"
]
},
```
== References
- [[ https://docs.google.com/document/d/1SxjahOrPsVPGQAd_OYz3s_gw077XUHQFTNG8RzBnG_I | Front-end development environment ]]