mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2026-05-30 01:02:17 +00:00
Make require() compliant with CommonJS 1.0
This includes potentially breaking changes.
Specifically, before this patch tiddlywiki would default to relative module identifiers
Now, tiddlywiki will only search relative paths if explicitly specified
Additionally, some "defaulted export contexts" were removed
(some modules may make assumptions about context)
Some unit tests were modified slightly from their originals
Tiddlywiki doesn't have a notion of a "main" program's path
Some require calls were explicitly made relative
None of these changes should affect the requirement under test in each case
This commit is contained in:
+39
-16
@@ -313,6 +313,7 @@ name `.` refers to the current directory
|
||||
*/
|
||||
$tw.utils.resolvePath = function(sourcepath,rootpath) {
|
||||
// If the source path starts with ./ or ../ then it is relative to the root
|
||||
|
||||
if(sourcepath.substr(0,2) === "./" || sourcepath.substr(0,3) === "../" ) {
|
||||
var src = sourcepath.split("/"),
|
||||
root = rootpath.split("/");
|
||||
@@ -332,7 +333,14 @@ $tw.utils.resolvePath = function(sourcepath,rootpath) {
|
||||
return root.join("/");
|
||||
} else {
|
||||
// If it isn't relative, just return the path
|
||||
return sourcepath;
|
||||
if(rootpath) {
|
||||
var root = rootpath.split("/");
|
||||
// Remove the filename part of the root
|
||||
root.splice(root.length-1,1);
|
||||
return root.join('/')+'/'+sourcepath
|
||||
} else {
|
||||
return sourcepath;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -362,9 +370,9 @@ $tw.utils.registerFileType = function(type,encoding,extension) {
|
||||
Run code globally with specified context variables in scope
|
||||
*/
|
||||
$tw.utils.evalGlobal = function(code,context,filename) {
|
||||
var contextCopy = $tw.utils.extend({},context,{
|
||||
var contextCopy = $tw.utils.extend({},context/*,{
|
||||
exports: {}
|
||||
});
|
||||
}*/);
|
||||
// Get the context variables as a pair of arrays of names and values
|
||||
var contextNames = [], contextValues = [];
|
||||
$tw.utils.each(contextCopy,function(value,name) {
|
||||
@@ -389,9 +397,9 @@ Run code in a sandbox with only the specified context variables in scope
|
||||
*/
|
||||
$tw.utils.evalSandboxed = $tw.browser ? $tw.utils.evalGlobal : function(code,context,filename) {
|
||||
var sandbox = $tw.utils.extend({},context);
|
||||
$tw.utils.extend(sandbox,{
|
||||
exports: {}
|
||||
});
|
||||
//$tw.utils.extend(sandbox,{
|
||||
// exports: {}
|
||||
//});
|
||||
vm.runInNewContext(code,sandbox,filename);
|
||||
return sandbox.exports;
|
||||
};
|
||||
@@ -540,12 +548,13 @@ $tw.utils.Crypto = function() {
|
||||
Execute the module named 'moduleName'. The name can optionally be relative to the module named 'moduleRoot'
|
||||
*/
|
||||
$tw.modules.execute = function(moduleName,moduleRoot) {
|
||||
var name = moduleRoot ? $tw.utils.resolvePath(moduleName,moduleRoot) : moduleName,
|
||||
moduleInfo = $tw.modules.titles[name],
|
||||
tiddler = $tw.wiki.getTiddler(name),
|
||||
var name = moduleName[0] == '.' ? $tw.utils.resolvePath(moduleName,moduleRoot) : moduleName,
|
||||
moduleInfo = $tw.modules.titles[name] || $tw.modules.titles[name+'.js'] || $tw.modules.titles[moduleName] || $tw.modules.titles[moduleName+'.js'] ,
|
||||
tiddler = $tw.wiki.getTiddler(name) || $tw.wiki.getTiddler(name+'.js') || $tw.wiki.getTiddler(moduleName) || $tw.wiki.getTiddler(moduleName+'.js') ,
|
||||
_exports = {},
|
||||
sandbox = {
|
||||
module: moduleInfo,
|
||||
exports: {},
|
||||
exports: _exports,
|
||||
console: console,
|
||||
setInterval: setInterval,
|
||||
clearInterval: clearInterval,
|
||||
@@ -553,7 +562,7 @@ $tw.modules.execute = function(moduleName,moduleRoot) {
|
||||
clearTimeout: clearTimeout,
|
||||
$tw: $tw,
|
||||
require: function(title) {
|
||||
return $tw.modules.execute(title,name);
|
||||
return $tw.modules.execute(title, name);
|
||||
}
|
||||
};
|
||||
if(!$tw.browser) {
|
||||
@@ -562,12 +571,19 @@ $tw.modules.execute = function(moduleName,moduleRoot) {
|
||||
});
|
||||
}
|
||||
if(!moduleInfo) {
|
||||
//we could not find the module on this path
|
||||
//try to defer to browserify etc, or node
|
||||
var deferredModule;
|
||||
if($tw.browser) {
|
||||
return $tw.utils.error("Cannot find module named '" + moduleName + "' required by module '" + moduleRoot + "', resolved to " + name);
|
||||
|
||||
if(window.require) {
|
||||
try {
|
||||
return window.require(moduleName)
|
||||
} catch(e) {}
|
||||
}
|
||||
throw "Cannot find module named '" + moduleName + "' required by module '" + moduleRoot + "', resolved to " + name;
|
||||
} else {
|
||||
// If we don't have a module with that name, let node.js try to find it
|
||||
return require(moduleName);
|
||||
return require(moduleName)
|
||||
}
|
||||
}
|
||||
// Execute the module if we haven't already done so
|
||||
@@ -575,10 +591,17 @@ $tw.modules.execute = function(moduleName,moduleRoot) {
|
||||
try {
|
||||
// Check the type of the definition
|
||||
if(typeof moduleInfo.definition === "function") { // Function
|
||||
moduleInfo.exports = {};
|
||||
moduleInfo.exports = _exports;
|
||||
moduleInfo.definition(moduleInfo,moduleInfo.exports,sandbox.require);
|
||||
} else if(typeof moduleInfo.definition === "string") { // String
|
||||
moduleInfo.exports = $tw.utils.evalSandboxed(moduleInfo.definition,sandbox,tiddler.fields.title);
|
||||
var temp;
|
||||
moduleInfo.exports = _exports;
|
||||
temp = $tw.utils.evalSandboxed(moduleInfo.definition,sandbox,tiddler.fields.title);
|
||||
for(var k in temp) {
|
||||
moduleInfo.exports[k] = temp[k]
|
||||
}
|
||||
//$tw.utils.extend(exports, temp)
|
||||
//moduleInfo.exports = temp;
|
||||
} else { // Object
|
||||
moduleInfo.exports = moduleInfo.definition;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
title: GettingStarted
|
||||
|
||||
This wiki instance contains the CommonJS Modules/1.0 unit tests.
|
||||
|
||||
To run them, open a console repl and execute "$tw.modules.execute('allTests')" there. You should see no exceptions or output starting with "FAIL" in the console.
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
/*\
|
||||
title: absolute/b.js
|
||||
type: application/javascript
|
||||
module-type: library
|
||||
|
||||
Absolute require test
|
||||
|
||||
\*/
|
||||
|
||||
|
||||
exports.foo = function() {};
|
||||
@@ -0,0 +1,16 @@
|
||||
/*\
|
||||
title: absolute/program.js
|
||||
type: application/javascript
|
||||
module-type: library
|
||||
|
||||
Absolute require test
|
||||
|
||||
\*/
|
||||
|
||||
|
||||
var test = require('test');
|
||||
var a = require('./submodule/a');
|
||||
var b = require('./b');
|
||||
test.assert(a.foo().foo === b.foo, 'require works with absolute identifiers');
|
||||
test.print('DONE', 'info');
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
/*\
|
||||
title: absolute/submodule/a.js
|
||||
type: application/javascript
|
||||
module-type: library
|
||||
|
||||
Absolute require test
|
||||
|
||||
\*/
|
||||
|
||||
|
||||
exports.foo = function () {
|
||||
return require('../b');
|
||||
};
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
/*\
|
||||
title: allTests.js
|
||||
type: application/javascript
|
||||
module-type: library
|
||||
|
||||
Runs all CommonJS Modules tests
|
||||
|
||||
\*/
|
||||
|
||||
$tw.modules.execute('absolute/program.js');
|
||||
$tw.modules.execute('cyclic/program.js');
|
||||
$tw.modules.execute('determinism/program.js');
|
||||
$tw.modules.execute('exactExports/program.js');
|
||||
$tw.modules.execute('hasOwnProperty/program.js');
|
||||
$tw.modules.execute('method/program.js');
|
||||
$tw.modules.execute('missing/program.js');
|
||||
$tw.modules.execute('monkeys/program.js');
|
||||
$tw.modules.execute('nested/program.js');
|
||||
$tw.modules.execute('relative/program.js');
|
||||
$tw.modules.execute('transitive/program.js');
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
/*\
|
||||
title: cyclic/a.js
|
||||
type: application/javascript
|
||||
module-type: library
|
||||
|
||||
Cycle require test A
|
||||
|
||||
\*/
|
||||
|
||||
exports.a = function () {
|
||||
return b;
|
||||
};
|
||||
var b = require('./b');
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
/*\
|
||||
title: cyclic/b.js
|
||||
type: application/javascript
|
||||
module-type: library
|
||||
|
||||
Cycle require test B
|
||||
|
||||
\*/
|
||||
|
||||
|
||||
|
||||
var a = require('./a');
|
||||
exports.b = function () {
|
||||
return a;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
/*\
|
||||
title: cyclic/program.js
|
||||
type: application/javascript
|
||||
module-type: library
|
||||
|
||||
Cycle require test
|
||||
|
||||
\*/
|
||||
|
||||
|
||||
|
||||
var test = require('test');
|
||||
var a = require('./a');
|
||||
var b = require('./b');
|
||||
|
||||
test.assert(a.a, 'a exists');
|
||||
test.assert(b.b, 'b exists')
|
||||
test.assert(a.a().b === b.b, 'a gets b');
|
||||
test.assert(b.b().a === a.a, 'b gets a');
|
||||
|
||||
test.print('DONE', 'info');
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
/*\
|
||||
title: determinism/program.js
|
||||
type: application/javascript
|
||||
module-type: library
|
||||
|
||||
Determinism test
|
||||
|
||||
\*/
|
||||
|
||||
|
||||
var test = require('test');
|
||||
require('submodule/a');
|
||||
test.print('DONE', 'info');
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
/*\
|
||||
title: determinism/submodule/a.js
|
||||
type: application/javascript
|
||||
module-type: library
|
||||
|
||||
Determinism require test A
|
||||
|
||||
\*/
|
||||
|
||||
|
||||
var test = require('test');
|
||||
var pass = false;
|
||||
var test = require('test');
|
||||
try {
|
||||
require('a');
|
||||
} catch (exception) {
|
||||
pass = true;
|
||||
}
|
||||
test.assert(pass, 'require does not fall back to relative modules when absolutes are not available.')
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
/*\
|
||||
title: exactExports/a.js
|
||||
type: application/javascript
|
||||
module-type: library
|
||||
|
||||
ExactExports test A
|
||||
|
||||
\*/
|
||||
|
||||
|
||||
exports.program = function () {
|
||||
return require('./program');
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
/*\
|
||||
title: exactExports/program.js
|
||||
type: application/javascript
|
||||
module-type: library
|
||||
|
||||
ExactExports test
|
||||
|
||||
\*/
|
||||
|
||||
|
||||
|
||||
var test = require('test');
|
||||
var a = require('./a');
|
||||
test.assert(a.program() === exports, 'exact exports');
|
||||
test.print('DONE', 'info');
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
/*\
|
||||
title: hasOwnProperty.js
|
||||
type: application/javascript
|
||||
module-type: library
|
||||
|
||||
\*/
|
||||
@@ -0,0 +1,15 @@
|
||||
/*\
|
||||
title: hasOwnProperty/program.js
|
||||
type: application/javascript
|
||||
module-type: library
|
||||
|
||||
OwnProperty test
|
||||
|
||||
\*/
|
||||
|
||||
var hasOwnProperty = require('hasOwnProperty');
|
||||
var toString = require('toString');
|
||||
var test = require('test');
|
||||
test.print('DONE', 'info');
|
||||
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
/*\
|
||||
title: toString.js
|
||||
type: application/javascript
|
||||
module-type: library
|
||||
|
||||
\*/
|
||||
@@ -0,0 +1,23 @@
|
||||
/*\
|
||||
title: method/a.js
|
||||
type: application/javascript
|
||||
module-type: library
|
||||
|
||||
Method test
|
||||
|
||||
\*/
|
||||
|
||||
|
||||
exports.foo = function () {
|
||||
return this;
|
||||
};
|
||||
exports.set = function (x) {
|
||||
this.x = x;
|
||||
};
|
||||
exports.get = function () {
|
||||
return this.x;
|
||||
};
|
||||
exports.getClosed = function () {
|
||||
return exports.x;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
/*\
|
||||
title: method/program.js
|
||||
type: application/javascript
|
||||
module-type: library
|
||||
|
||||
Method test
|
||||
|
||||
\*/
|
||||
|
||||
|
||||
var test = require('test');
|
||||
var a = require('./a');
|
||||
var foo = a.foo;
|
||||
test.assert(a.foo() == a, 'calling a module member');
|
||||
test.assert(foo() == (function (){return this})(), 'members not implicitly bound');
|
||||
a.set(10);
|
||||
test.assert(a.get() == 10, 'get and set')
|
||||
test.print('DONE', 'info');
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
/*\
|
||||
title: missing/program.js
|
||||
type: application/javascript
|
||||
module-type: library
|
||||
|
||||
Missing test
|
||||
|
||||
\*/
|
||||
|
||||
|
||||
var test = require('test');
|
||||
try {
|
||||
require('bogus');
|
||||
test.print('FAIL require throws error when module missing', 'fail');
|
||||
} catch (exception) {
|
||||
test.print('PASS require throws error when module missing', 'pass');
|
||||
}
|
||||
test.print('DONE', 'info');
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
/*\
|
||||
title: monkeys/a.js
|
||||
type: application/javascript
|
||||
module-type: library
|
||||
|
||||
Missing test A
|
||||
|
||||
\*/
|
||||
|
||||
require('./program').monkey = 10;
|
||||
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
/*\
|
||||
title: monkeys/program.js
|
||||
type: application/javascript
|
||||
module-type: library
|
||||
|
||||
Monkeys test
|
||||
|
||||
\*/
|
||||
|
||||
|
||||
var a = require('./a');
|
||||
var test = require('test');
|
||||
test.assert(exports.monkey == 10, 'monkeys permitted');
|
||||
test.print('DONE', 'info');
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
/*\
|
||||
title: a/b/c/d.js
|
||||
type: application/javascript
|
||||
module-type: library
|
||||
|
||||
Nested test
|
||||
|
||||
\*/
|
||||
|
||||
exports.foo = function () {
|
||||
return 1;
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
/*\
|
||||
title: nested/program.js
|
||||
type: application/javascript
|
||||
module-type: library
|
||||
|
||||
Nested test
|
||||
|
||||
\*/
|
||||
|
||||
|
||||
var test = require('test');
|
||||
test.assert(require('a/b/c/d').foo() == 1, 'nested module identifier');
|
||||
test.print('DONE', 'info');
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
/*\
|
||||
title: relative/program.js
|
||||
type: application/javascript
|
||||
module-type: library
|
||||
|
||||
Relative test
|
||||
|
||||
\*/
|
||||
|
||||
|
||||
var test = require('test');
|
||||
var a = require('submodule/a');
|
||||
var b = require('submodule/b');
|
||||
test.assert(a.foo == b.foo, 'a and b share foo through a relative require');
|
||||
test.print('DONE', 'info');
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
/*\
|
||||
title: submodule/a.js
|
||||
type: application/javascript
|
||||
module-type: library
|
||||
|
||||
Relative test A
|
||||
|
||||
\*/
|
||||
|
||||
|
||||
|
||||
exports.foo = require('./b').foo;
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
/*\
|
||||
title: submodule/b.js
|
||||
type: application/javascript
|
||||
module-type: library
|
||||
|
||||
Relative test B
|
||||
|
||||
\*/
|
||||
|
||||
exports.foo = function () {
|
||||
};
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
/*\
|
||||
title: test.js
|
||||
type: application/javascript
|
||||
module-type: library
|
||||
|
||||
testing lib
|
||||
|
||||
\*/
|
||||
|
||||
|
||||
exports.assert = function(cond, msg) {
|
||||
if(!cond) {
|
||||
if(msg) {
|
||||
throw msg
|
||||
} else {
|
||||
throw "ASSERT FAILED"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exports.print = function() {
|
||||
console.log.apply(console, arguments);
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
/*\
|
||||
title: transitive/a.js
|
||||
type: application/javascript
|
||||
module-type: library
|
||||
|
||||
Transitive test A
|
||||
|
||||
\*/
|
||||
|
||||
exports.foo = require('./b').foo;
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
/*\
|
||||
title: transitive/b.js
|
||||
type: application/javascript
|
||||
module-type: library
|
||||
|
||||
Transitive test B
|
||||
|
||||
\*/
|
||||
|
||||
|
||||
|
||||
exports.foo = require('./c').foo;
|
||||
@@ -0,0 +1,14 @@
|
||||
/*\
|
||||
title: transitive/c.js
|
||||
type: application/javascript
|
||||
module-type: library
|
||||
|
||||
Transitive test C
|
||||
|
||||
\*/
|
||||
|
||||
|
||||
exports.foo = function () {
|
||||
return 1;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
/*\
|
||||
title: transitive/program.js
|
||||
type: application/javascript
|
||||
module-type: library
|
||||
|
||||
Transitive test
|
||||
|
||||
\*/
|
||||
|
||||
var test = require('test');
|
||||
test.assert(require('./a').foo() == 1, 'transitive');
|
||||
test.print('DONE', 'info');
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"plugins": [
|
||||
"tiddlywiki/fullscreen"
|
||||
],
|
||||
"themes": [
|
||||
"tiddlywiki/snowwhite"
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user