jenkins-bot has submitted this change and it was merged.
Change subject: resourceloader: Implement modern module loading (2/2)
......................................................................
resourceloader: Implement modern module loading (2/2)
* Send 'module' and 'require' parameters to module closures.
This depends on Ia925844cc22f143 being deployed one cycle earlier.
* Patch Moment and OOjs to ensure these libraries continue to expose
their module as globals as well. AMD/UMD-compatible libraries
only expose a global *OR* an export, not both. We need both
for back-compat.
* Update pluralRuleParser to make use of module export to allow
usage via require().
To test, check out the patch and run:
> mw.loader.load('moment');
> mw.loader.require('moment')()
> mw.loader.require('moment')('2011-04-01').fromNow()
Bug: T108655
Change-Id: Idbd054880ee70d659ec760aef8fcb38d0704a394
---
M includes/resourceloader/ResourceLoader.php
M resources/Resources.php
M resources/src/mediawiki.libs/CLDRPluralRuleParser.js
M resources/src/mediawiki/mediawiki.js
A resources/src/moment-global.js
A resources/src/oojs-global.js
M tests/phpunit/includes/OutputPageTest.php
M tests/phpunit/includes/resourceloader/ResourceLoaderTest.php
M tests/qunit/QUnitTestResources.php
A tests/qunit/data/defineCallMwLoaderTestCallback.js
A tests/qunit/data/requireCallMwLoaderTestCallback.js
M tests/qunit/suites/resources/mediawiki/mediawiki.test.js
A tests/qunit/suites/resources/test.sinonjs/index.js
13 files changed, 55 insertions(+), 7 deletions(-)
Approvals:
Krinkle: Looks good to me, approved
Adrian Heine: Looks good to me, but someone else must approve
Jdlrobson: Looks good to me, approved
jenkins-bot: Verified
diff --git a/includes/resourceloader/ResourceLoader.php
b/includes/resourceloader/ResourceLoader.php
index 0aa08be..086ab17 100644
--- a/includes/resourceloader/ResourceLoader.php
+++ b/includes/resourceloader/ResourceLoader.php
@@ -1098,7 +1098,7 @@
$scripts = self::filter( 'minify-js',
$scripts );
}
} else {
- $scripts = new XmlJsCode( "function ( $, jQuery
) {\n{$scripts}\n}" );
+ $scripts = new XmlJsCode( "function ( $,
jQuery, require, module ) {\n{$scripts}\n}" );
}
} elseif ( !is_array( $scripts ) ) {
throw new MWException( 'Invalid scripts error. Array of
URLs or string of code expected.' );
diff --git a/resources/Resources.php b/resources/Resources.php
index 42a0746..cb7adbe 100644
--- a/resources/Resources.php
+++ b/resources/Resources.php
@@ -734,6 +734,7 @@
'moment' => [
'scripts' => [
'resources/lib/moment/moment.js',
+ 'resources/src/moment-global.js',
'resources/src/moment-local-dmy.js',
],
'languageScripts' => [
@@ -2278,6 +2279,7 @@
'oojs' => [
'scripts' => [
'resources/lib/oojs/oojs.jquery.js',
+ 'resources/src/oojs-global.js',
],
'targets' => [ 'desktop', 'mobile' ],
'dependencies' => [
diff --git a/resources/src/mediawiki.libs/CLDRPluralRuleParser.js
b/resources/src/mediawiki.libs/CLDRPluralRuleParser.js
index 31c8fef..549a9ab 100644
--- a/resources/src/mediawiki.libs/CLDRPluralRuleParser.js
+++ b/resources/src/mediawiki.libs/CLDRPluralRuleParser.js
@@ -591,5 +591,6 @@
/* pluralRuleParser ends here */
mw.libs.pluralRuleParser = pluralRuleParser;
+module.exports = pluralRuleParser;
} )( mediaWiki );
diff --git a/resources/src/mediawiki/mediawiki.js
b/resources/src/mediawiki/mediawiki.js
index 9d799db..4aad2ba 100644
--- a/resources/src/mediawiki/mediawiki.js
+++ b/resources/src/mediawiki/mediawiki.js
@@ -1189,11 +1189,18 @@
* @param {string} [moduleName] Name of currently
executing module
* @return {jQuery.Promise}
*/
- function queueModuleScript( src ) {
+ function queueModuleScript( src, moduleName ) {
var r = $.Deferred();
pendingRequests.push( function () {
+ if ( moduleName && hasOwn.call(
registry, moduleName ) ) {
+ window.require =
mw.loader.require;
+ window.module = registry[
moduleName ].module;
+ }
addScript( src ).always( function () {
+ // Clear environment
+ delete window.require;
+ delete window.module;
r.resolve();
// Start the next one (if any)
diff --git a/resources/src/moment-global.js b/resources/src/moment-global.js
new file mode 100644
index 0000000..ba01a24
--- /dev/null
+++ b/resources/src/moment-global.js
@@ -0,0 +1,2 @@
+// Back-compat: Export module as global
+window.moment = module.exports;
diff --git a/resources/src/oojs-global.js b/resources/src/oojs-global.js
new file mode 100644
index 0000000..de156f0
--- /dev/null
+++ b/resources/src/oojs-global.js
@@ -0,0 +1,2 @@
+// Back-compat: Export module as global
+window.OO = module.exports;
diff --git a/tests/phpunit/includes/OutputPageTest.php
b/tests/phpunit/includes/OutputPageTest.php
index 2f63ca8..8d4a347 100644
--- a/tests/phpunit/includes/OutputPageTest.php
+++ b/tests/phpunit/includes/OutputPageTest.php
@@ -169,7 +169,7 @@
[
[ 'test.quux',
ResourceLoaderModule::TYPE_COMBINED ],
"<script>(window.RLQ=window.RLQ||[]).push(function(){"
- .
"mw.loader.implement(\"test.quux\",function($,jQuery){"
+ .
"mw.loader.implement(\"test.quux\",function($,jQuery,require,module){"
.
"mw.test.baz({token:123});},{\"css\":[\".mw-icon{transition:none}"
. "\"]});});</script>"
],
diff --git a/tests/phpunit/includes/resourceloader/ResourceLoaderTest.php
b/tests/phpunit/includes/resourceloader/ResourceLoaderTest.php
index 2dfed62..65cd6ed 100644
--- a/tests/phpunit/includes/resourceloader/ResourceLoaderTest.php
+++ b/tests/phpunit/includes/resourceloader/ResourceLoaderTest.php
@@ -188,7 +188,7 @@
'messages' => [ 'example' => '' ],
'templates' => [],
- 'expected' => 'mw.loader.implement(
"test.example", function ( $, jQuery ) {
+ 'expected' => 'mw.loader.implement(
"test.example", function ( $, jQuery, require, module ) {
mw.example();
}, {
"css": [
@@ -207,7 +207,7 @@
'messages' => new XmlJsCode( '{}' ),
'templates' => [],
- 'expected' => 'mw.loader.implement(
"test.example", function ( $, jQuery ) {
+ 'expected' => 'mw.loader.implement(
"test.example", function ( $, jQuery, require, module ) {
mw.example();
} );',
] ],
@@ -235,7 +235,7 @@
'messages' => [ 'example' => '' ],
'templates' => [],
- 'expected' => 'mw.loader.implement(
"test.example", function ( $, jQuery ) {
+ 'expected' => 'mw.loader.implement(
"test.example", function ( $, jQuery, require, module ) {
mw.example();
}, {}, {
"example": ""
@@ -250,7 +250,7 @@
'messages' => new XmlJsCode( '{}' ),
'templates' => [ 'example.html' => '' ],
- 'expected' => 'mw.loader.implement(
"test.example", function ( $, jQuery ) {
+ 'expected' => 'mw.loader.implement(
"test.example", function ( $, jQuery, require, module ) {
mw.example();
}, {}, {}, {
"example.html": ""
diff --git a/tests/qunit/QUnitTestResources.php
b/tests/qunit/QUnitTestResources.php
index b7161b1..a2d76e0 100644
--- a/tests/qunit/QUnitTestResources.php
+++ b/tests/qunit/QUnitTestResources.php
@@ -8,7 +8,15 @@
'test.sinonjs' => [
'scripts' => [
+ 'tests/qunit/suites/resources/test.sinonjs/index.js',
'resources/lib/sinonjs/sinon-1.17.3.js',
+ // We want tests to work in IE, but can't include this
as it
+ // will break the placeholders in Sinon because the
hack it uses
+ // to hijack IE globals relies on running in the global
scope
+ // and in ResourceLoader this won't be running in the
global scope.
+ // Including it results (among other things) in
sandboxed timers
+ // being broken due to Date inheritance being undefined.
+ // 'resources/lib/sinonjs/sinon-ie-1.15.4.js',
],
'targets' => [ 'desktop', 'mobile' ],
],
diff --git a/tests/qunit/data/defineCallMwLoaderTestCallback.js
b/tests/qunit/data/defineCallMwLoaderTestCallback.js
new file mode 100644
index 0000000..afd886c
--- /dev/null
+++ b/tests/qunit/data/defineCallMwLoaderTestCallback.js
@@ -0,0 +1 @@
+module.exports = 'Define worked.';
diff --git a/tests/qunit/data/requireCallMwLoaderTestCallback.js
b/tests/qunit/data/requireCallMwLoaderTestCallback.js
new file mode 100644
index 0000000..8bc087b
--- /dev/null
+++ b/tests/qunit/data/requireCallMwLoaderTestCallback.js
@@ -0,0 +1,2 @@
+var x = require( 'test.require.define' );
+module.exports = 'Require worked.' + x;
diff --git a/tests/qunit/suites/resources/mediawiki/mediawiki.test.js
b/tests/qunit/suites/resources/mediawiki/mediawiki.test.js
index ce4ea8b..dd43c55 100644
--- a/tests/qunit/suites/resources/mediawiki/mediawiki.test.js
+++ b/tests/qunit/suites/resources/mediawiki/mediawiki.test.js
@@ -1127,4 +1127,24 @@
}, /is not loaded/, 'Requesting non-existent modules throws
error.' );
} );
+ QUnit.asyncTest( 'mw.loader require in debug mode', 1, function (
assert ) {
+ var path = mw.config.get( 'wgScriptPath' );
+ mw.loader.register( [
+ [ 'test.require.define', '0' ],
+ [ 'test.require.callback', '0', [ 'test.require.define'
] ]
+ ] );
+ mw.loader.implement( 'test.require.callback', [ QUnit.fixurl(
path + '/tests/qunit/data/requireCallMwLoaderTestCallback.js' ) ] );
+ mw.loader.implement( 'test.require.define', [ QUnit.fixurl(
path + '/tests/qunit/data/defineCallMwLoaderTestCallback.js' ) ] );
+
+ mw.loader.using( 'test.require.callback', function () {
+ QUnit.start();
+ var exported = mw.loader.require(
'test.require.callback' );
+ assert.strictEqual( exported, 'Require worked.Define
worked.',
+ 'module.exports worked in debug mode' );
+ }, function () {
+ QUnit.start();
+ assert.ok( false, 'Error callback fired while
loader.using "test.require.callback" module' );
+ } );
+ } );
+
}( mediaWiki, jQuery ) );
diff --git a/tests/qunit/suites/resources/test.sinonjs/index.js
b/tests/qunit/suites/resources/test.sinonjs/index.js
new file mode 100644
index 0000000..b1be9d1
--- /dev/null
+++ b/tests/qunit/suites/resources/test.sinonjs/index.js
@@ -0,0 +1,3 @@
+// Hack: Disable 'module.exports' from ResourceLoader
+// (Otherwise Sinon assumes context as Node.js instead of a browser)
+module.exports = null;
--
To view, visit https://gerrit.wikimedia.org/r/265793
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: Idbd054880ee70d659ec760aef8fcb38d0704a394
Gerrit-PatchSet: 31
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Jdlrobson <[email protected]>
Gerrit-Reviewer: Adrian Heine <[email protected]>
Gerrit-Reviewer: Cscott <[email protected]>
Gerrit-Reviewer: Edokter <[email protected]>
Gerrit-Reviewer: Jack Phoenix <[email protected]>
Gerrit-Reviewer: Jackmcbarn <[email protected]>
Gerrit-Reviewer: Jdlrobson <[email protected]>
Gerrit-Reviewer: Krinkle <[email protected]>
Gerrit-Reviewer: Legoktm <[email protected]>
Gerrit-Reviewer: jenkins-bot <>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits