Skip to content

Commit 16acd18

Browse files
committed
Fixes #623, allow wrapShim build config
1 parent 84f325c commit 16acd18

8 files changed

Lines changed: 264 additions & 17 deletions

File tree

‎.gitignore‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ build/tests/lib/removeCombinedPaths/testcase/project/build/build_output
7676
build/tests/lib/requireHoist/perLayer/built
7777
build/tests/lib/rhino-186/built
7878
build/tests/lib/semicolonInsert/a-built.js
79+
build/tests/lib/shimBasicWrap/basic-tests-built.js
7980
build/tests/lib/shimFakeDefine/main-built.js
8081
build/tests/lib/sourcemap/www-built
8182
build/tests/lib/sourcemap/onejs/built.js

‎build/example.build.js‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,18 @@
6565
//inlined in the build config.
6666
shim: {},
6767

68+
//As of 2.1.11, shimmed dependencies can be wrapped in a define() wrapper
69+
//to help when intermediate dependencies are AMD have dependencies of their
70+
//own. The canonical example is a project using Backbone, which depends on
71+
//jQuery and Underscore. Shimmed dependencies that want Backbone available
72+
//immediately will not see it in a build, since AMD compatible versions of
73+
//Backbone will not execute the define() function until dependencies are
74+
//ready. By wrapping those shimmed dependencies, this can be avoided, but
75+
//it could introduce other errors if those shimmed dependencies use the
76+
//global scope in weird ways, so it is not the default behavior to wrap.
77+
//More notes in http://requirejs.org/docs/api.html#config-shim
78+
wrapShim: false,
79+
6880
//As of RequireJS 2.0.2, the dir above will be deleted before the
6981
//build starts again. If you have a big build and are not doing
7082
//source transforms with onBuildRead/onBuildWrite, then you can

‎build/jslib/build.js‎

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1796,11 +1796,25 @@ define(function (require) {
17961796
if (moduleName && falseProp(layer.modulesWithNames, moduleName) && !config.skipModuleInsertion) {
17971797
shim = config.shim && (getOwn(config.shim, moduleName) || (packageMain && getOwn(config.shim, moduleName) || getOwn(config.shim, packageName)));
17981798
if (shim) {
1799-
singleContents += '\n' + namespaceWithDot + 'define("' + moduleName + '", ' +
1800-
(shim.deps && shim.deps.length ?
1801-
build.makeJsArrayString(shim.deps) + ', ' : '') +
1802-
(shim.exportsFn ? shim.exportsFn() : 'function(){}') +
1803-
');\n';
1799+
if (config.wrapShim) {
1800+
singleContents = '(function(root) {' +
1801+
'\n' + namespaceWithDot + 'define("' + moduleName + '", ' +
1802+
(shim.deps && shim.deps.length ?
1803+
build.makeJsArrayString(shim.deps) + ', ' : '[], ') +
1804+
'function() {\n' +
1805+
' return (function() {\n' +
1806+
singleContents +
1807+
(shim.exportsFn ? shim.exportsFn() : '') +
1808+
' }).apply(root, arguments);\n' +
1809+
' });\n' +
1810+
'}(this));\n';
1811+
} else {
1812+
singleContents += '\n' + namespaceWithDot + 'define("' + moduleName + '", ' +
1813+
(shim.deps && shim.deps.length ?
1814+
build.makeJsArrayString(shim.deps) + ', ' : '') +
1815+
(shim.exportsFn ? shim.exportsFn() : 'function(){}') +
1816+
');\n';
1817+
}
18041818
} else {
18051819
singleContents += '\n' + namespaceWithDot + 'define("' + moduleName + '", function(){});\n';
18061820
}

‎build/jslib/requirePatch.js‎

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -121,18 +121,45 @@ define([ 'env!env/file', 'pragma', 'parse', 'lang', 'logger', 'commonJs', 'prim'
121121
//spit out strings that can be used in the stringified
122122
//build output.
123123
context.makeShimExports = function (value) {
124-
function fn() {
125-
return '(function (global) {\n' +
126-
' return function () {\n' +
127-
' var ret, fn;\n' +
128-
(value.init ?
129-
(' fn = ' + value.init.toString() + ';\n' +
130-
' ret = fn.apply(global, arguments);\n') : '') +
131-
(value.exports ?
132-
' return ret || global.' + value.exports + ';\n' :
133-
' return ret;\n') +
134-
' };\n' +
135-
'}(this))';
124+
var fn;
125+
if (context.config.wrapShim) {
126+
fn = function () {
127+
var str = 'return ';
128+
// If specifies an export that is just a global
129+
// name, no dot for a `this.` and such, then also
130+
// attach to the global, for `var a = {}` files
131+
// where the function closure would hide that from
132+
// the global object.
133+
if (value.exports && value.exports.indexOf('.') === -1) {
134+
str += 'root.' + value.exports + ' = ';
135+
}
136+
137+
if (value.init) {
138+
str += '(' + value.init.toString() + '.apply(this, arguments))';
139+
}
140+
if (value.init && value.exports) {
141+
str += ' || ';
142+
}
143+
if (value.exports) {
144+
str += value.exports;
145+
}
146+
str += ';';
147+
return str;
148+
};
149+
} else {
150+
fn = function () {
151+
return '(function (global) {\n' +
152+
' return function () {\n' +
153+
' var ret, fn;\n' +
154+
(value.init ?
155+
(' fn = ' + value.init.toString() + ';\n' +
156+
' ret = fn.apply(global, arguments);\n') : '') +
157+
(value.exports ?
158+
' return ret || global.' + value.exports + ';\n' :
159+
' return ret;\n') +
160+
' };\n' +
161+
'}(this))';
162+
};
136163
}
137164

138165
return fn;

‎build/tests/builds.js‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1277,6 +1277,30 @@ define(['build', 'env!env/file', 'env', 'lang'], function (build, file, env, lan
12771277
);
12781278
doh.run();
12791279

1280+
// test wrapShim: true config
1281+
//
1282+
doh.register("shimBasicWrap",
1283+
[
1284+
function shimBasicWrap(t) {
1285+
var outFile = "lib/shimBasicWrap/basic-tests-built.js";
1286+
1287+
file.deleteFile(outFile);
1288+
1289+
build(["lib/shimBasicWrap/build.js"]);
1290+
1291+
//Also remove spaces, since rhino and node differ on their
1292+
//Function.prototype.toString() output by whitespace, and
1293+
//the semicolon on end of A.name, and string quotes.
1294+
t.is(nol(c("lib/shimBasicWrap/expected.js")).replace(/\s+/g, '').replace(/A\.name\;/g, 'A.name'),
1295+
nol(c(outFile)).replace(/\s+/g, '').replace(/A\.name\;/g, 'A.name')
1296+
.replace(/['"]Modified["']/, "'Modified'"));
1297+
1298+
require._buildReset();
1299+
}
1300+
1301+
]
1302+
);
1303+
doh.run();
12801304

12811305
doh.register("shimFakeDefine",
12821306
[
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<title>require.js: Basic Wrap Shim Test</title>
5+
<script type="text/javascript" src="../../../../../requirejs/require.js"></script>
6+
<script type="text/javascript" src="../../../../../requirejs/tests/doh/runner.js"></script>
7+
<script type="text/javascript" src="../../../../../requirejs/tests/doh/_browserRunner.js"></script>
8+
<script type="text/javascript" src="basic-tests-built.js"></script>
9+
</head>
10+
<body>
11+
<h1>require.js: Basic Wrap Shim Test</h1>
12+
<p>Basic test of the shim config support.</p>
13+
<p>Check console for messages</p>
14+
</body>
15+
</html>
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
//baseUrl: '../../../../../requirejs/tests/shim',
3+
mainConfigFile: '../../../../../requirejs/tests/shim/basic-tests.js',
4+
wrapShim: true,
5+
6+
// Add a shim that was missing: need to make a global.
7+
shim: {
8+
'b': {
9+
deps: ['a', 'd'],
10+
exports: 'B'
11+
}
12+
},
13+
name: 'basic-tests',
14+
out: 'basic-tests-built.js',
15+
optimize: 'none'
16+
}
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
(function(root) {
2+
define("a", [], function() {
3+
return (function() {
4+
5+
(function (root) {
6+
root.A = {
7+
name: 'a'
8+
};
9+
}(this));
10+
return (function () {
11+
window.globalA = this.A.name;
12+
}.apply(this, arguments)) || A.name; }).apply(root, arguments);
13+
});
14+
}(this));
15+
16+
function D() {
17+
this.name = 'd';
18+
};
19+
20+
define("d", function(){});
21+
(function(root) {
22+
define("b", ["a","d"], function() {
23+
return (function() {
24+
25+
var B = {
26+
name: 'b',
27+
aValue: A.name,
28+
dValue: new D()
29+
};
30+
return root.B = B; }).apply(root, arguments);
31+
});
32+
}(this));
33+
(function(root) {
34+
define("c", ["a","b"], function() {
35+
return (function() {
36+
37+
var C = {
38+
name: 'c',
39+
a: A,
40+
b: B
41+
};
42+
return root.C = C; }).apply(root, arguments);
43+
});
44+
}(this));
45+
(function(root) {
46+
define("e", [], function() {
47+
return (function() {
48+
49+
var e = {
50+
nested: {
51+
e: {
52+
name: 'e'
53+
}
54+
}
55+
};
56+
return (function () {
57+
return {
58+
name: e.nested.e.name + 'Modified'
59+
};
60+
}.apply(this, arguments)) || e.nested.e; }).apply(root, arguments);
61+
});
62+
}(this));
63+
(function(root) {
64+
define("f", ["a"], function() {
65+
return (function() {
66+
67+
var FCAP = {
68+
name: 'FCAP',
69+
globalA: A
70+
};
71+
return (function (a) {
72+
return {
73+
name: FCAP.name,
74+
globalA: FCAP.globalA,
75+
a: a
76+
};
77+
}.apply(this, arguments)); }).apply(root, arguments);
78+
});
79+
}(this));
80+
81+
require({
82+
baseUrl: './',
83+
shim: {
84+
a: {
85+
exports: 'A.name',
86+
init: function () {
87+
window.globalA = this.A.name;
88+
}
89+
},
90+
'b': ['a', 'd'],
91+
'c': {
92+
deps: ['a', 'b'],
93+
exports: 'C'
94+
},
95+
'e': {
96+
exports: 'e.nested.e',
97+
init: function () {
98+
return {
99+
name: e.nested.e.name + 'Modified'
100+
};
101+
}
102+
},
103+
'f': {
104+
deps: ['a'],
105+
init: function (a) {
106+
return {
107+
name: FCAP.name,
108+
globalA: FCAP.globalA,
109+
a: a
110+
};
111+
}
112+
}
113+
}
114+
},
115+
['a', 'c', 'e', 'f'],
116+
function(a, c, e, f) {
117+
doh.register(
118+
'shimBasic',
119+
[
120+
function shimBasic(t){
121+
t.is('a', a);
122+
t.is('a', window.globalA);
123+
t.is('a', c.b.aValue);
124+
t.is('b', c.b.name);
125+
t.is('c', c.name);
126+
t.is('d', c.b.dValue.name);
127+
t.is('eModified', e.name);
128+
t.is('FCAP', f.name);
129+
t.is('a', f.globalA.name);
130+
t.is('a', f.a);
131+
}
132+
]
133+
);
134+
doh.run();
135+
}
136+
);
137+
138+
define("basic-tests", function(){});

0 commit comments

Comments
 (0)