Skip to content

Commit 6345e5c

Browse files
refactor: add support __esModule expose && named expose
1 parent b2b0f32 commit 6345e5c

File tree

7 files changed

+190
-65
lines changed

7 files changed

+190
-65
lines changed

src/index.js

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import validateOptions from 'schema-utils';
1111

1212
import schema from './options.json';
1313

14+
import getExposes from './utils';
15+
1416
export default function loader(content, sourceMap) {
1517
const options = getOptions(this);
1618

@@ -21,6 +23,17 @@ export default function loader(content, sourceMap) {
2123

2224
const callback = this.async();
2325

26+
let exposes;
27+
28+
try {
29+
exposes = getExposes(options.exposes);
30+
} catch (error) {
31+
this.emitError(error);
32+
callback(null, content, sourceMap);
33+
34+
return;
35+
}
36+
2437
// Change the request from an /abolute/path.js to a relative ./path.js
2538
// This prevents [chunkhash] values from changing when running webpack
2639
// builds in different directories.
@@ -35,10 +48,6 @@ export default function loader(content, sourceMap) {
3548
*/
3649
this._module.userRequest = `${this._module.userRequest}-exposed`;
3750

38-
const exposes = Array.isArray(options.exposes)
39-
? options.exposes
40-
: [options.exposes];
41-
4251
let code = `var ___EXPOSE_LOADER_IMPORT___ = require(${JSON.stringify(
4352
`-!${newRequestPath}`
4453
)});\n`;
@@ -47,13 +56,15 @@ export default function loader(content, sourceMap) {
4756
require.resolve('./runtime/getGlobalThis.js')
4857
)});\n`;
4958
code += `var ___EXPOSE_LOADER_GLOBAL_THIS___ = ___EXPOSE_LOADER_GET_GLOBAL_THIS___();\n`;
50-
code += `var ___EXPOSE_LOADER_IMPORT_DEFAULT___ = ___EXPOSE_LOADER_IMPORT___.__esModule
51-
? ___EXPOSE_LOADER_IMPORT___.default\n || ___EXPOSE_LOADER_IMPORT___\n
52-
: ___EXPOSE_LOADER_IMPORT___\n`;
5359

5460
for (const expose of exposes) {
55-
const childProperties = expose.split('.');
61+
const childProperties = expose.globalName.split('.');
5662
const { length } = childProperties;
63+
const { packageName } = expose;
64+
65+
if (typeof packageName !== 'undefined') {
66+
code += `var ___EXPOSE_LOADER_IMPORT_NAMED___ = ___EXPOSE_LOADER_IMPORT___.${packageName}\n`;
67+
}
5768

5869
let propertyString = '___EXPOSE_LOADER_GLOBAL_THIS___';
5970

@@ -65,10 +76,11 @@ export default function loader(content, sourceMap) {
6576
propertyString += `[${JSON.stringify(childProperties[i])}]`;
6677
}
6778

68-
code += `${propertyString} = ___EXPOSE_LOADER_IMPORT_DEFAULT___;\n`;
79+
code +=
80+
typeof packageName !== 'undefined'
81+
? `${propertyString} = ___EXPOSE_LOADER_IMPORT_NAMED___;\n`
82+
: `${propertyString} = ___EXPOSE_LOADER_IMPORT___;\n`;
6983
}
7084

71-
code += `module.exports = ___EXPOSE_LOADER_IMPORT___;`;
72-
73-
callback(null, `${code}`, sourceMap);
85+
callback(null, `${content}\n${code}`, sourceMap);
7486
}

src/utils.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
function resolveExposes(item) {
2+
let result;
3+
4+
if (typeof item === 'string') {
5+
const splittedItem = item.split(' ');
6+
7+
if (splittedItem.length > 2) {
8+
throw new Error(`Invalid "${item}" for expose`);
9+
}
10+
11+
result = {
12+
globalName: splittedItem[0],
13+
packageName: splittedItem[1],
14+
};
15+
}
16+
17+
return result;
18+
}
19+
20+
function getExposes(items) {
21+
let result = [];
22+
23+
if (typeof imports === 'string') {
24+
result.push(resolveExposes(items));
25+
} else {
26+
result = [].concat(items).map((item) => resolveExposes(item));
27+
}
28+
29+
return result;
30+
}
31+
32+
export default getExposes;

test/__snapshots__/loader.test.js.snap

Lines changed: 100 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,16 @@
33
exports[`loader should work for a nested property for a global object: errors 1`] = `Array []`;
44

55
exports[`loader should work for a nested property for a global object: module 1`] = `
6-
"var ___EXPOSE_LOADER_IMPORT___ = require(\\"-!./global-commonjs2-single-export.js\\");
6+
"const globalObject4 = { foo: 'bar' };
7+
8+
module.exports = globalObject4;
9+
10+
var ___EXPOSE_LOADER_IMPORT___ = require(\\"-!./global-commonjs2-single-export.js\\");
711
var ___EXPOSE_LOADER_GET_GLOBAL_THIS___ = require(\\"../../src/runtime/getGlobalThis.js\\");
812
var ___EXPOSE_LOADER_GLOBAL_THIS___ = ___EXPOSE_LOADER_GET_GLOBAL_THIS___();
9-
var ___EXPOSE_LOADER_IMPORT_DEFAULT___ = ___EXPOSE_LOADER_IMPORT___.__esModule
10-
? ___EXPOSE_LOADER_IMPORT___.default
11-
|| ___EXPOSE_LOADER_IMPORT___
12-
13-
: ___EXPOSE_LOADER_IMPORT___
1413
if (!___EXPOSE_LOADER_GLOBAL_THIS___[\\"myGlobal\\"]) ___EXPOSE_LOADER_GLOBAL_THIS___[\\"myGlobal\\"] = {};
15-
___EXPOSE_LOADER_GLOBAL_THIS___[\\"myGlobal\\"][\\"nested\\"] = ___EXPOSE_LOADER_IMPORT_DEFAULT___;
16-
module.exports = ___EXPOSE_LOADER_IMPORT___;"
14+
___EXPOSE_LOADER_GLOBAL_THIS___[\\"myGlobal\\"][\\"nested\\"] = ___EXPOSE_LOADER_IMPORT___;
15+
"
1716
`;
1817

1918
exports[`loader should work for a nested property for a global object: result 1`] = `
@@ -31,25 +30,25 @@ Object {
3130

3231
exports[`loader should work for a nested property for a global object: warnings 1`] = `Array []`;
3332

34-
exports[`loader should work for nested preporties for a global object: errors 1`] = `Array []`;
33+
exports[`loader should work for nested properties for a global object: errors 1`] = `Array []`;
3534

36-
exports[`loader should work for nested preporties for a global object: module 1`] = `
37-
"var ___EXPOSE_LOADER_IMPORT___ = require(\\"-!./global-commonjs2-single-export.js\\");
35+
exports[`loader should work for nested properties for a global object: module 1`] = `
36+
"const globalObject4 = { foo: 'bar' };
37+
38+
module.exports = globalObject4;
39+
40+
var ___EXPOSE_LOADER_IMPORT___ = require(\\"-!./global-commonjs2-single-export.js\\");
3841
var ___EXPOSE_LOADER_GET_GLOBAL_THIS___ = require(\\"../../src/runtime/getGlobalThis.js\\");
3942
var ___EXPOSE_LOADER_GLOBAL_THIS___ = ___EXPOSE_LOADER_GET_GLOBAL_THIS___();
40-
var ___EXPOSE_LOADER_IMPORT_DEFAULT___ = ___EXPOSE_LOADER_IMPORT___.__esModule
41-
? ___EXPOSE_LOADER_IMPORT___.default
42-
|| ___EXPOSE_LOADER_IMPORT___
43-
44-
: ___EXPOSE_LOADER_IMPORT___
4543
if (!___EXPOSE_LOADER_GLOBAL_THIS___[\\"myGlobal\\"]) ___EXPOSE_LOADER_GLOBAL_THIS___[\\"myGlobal\\"] = {};
46-
___EXPOSE_LOADER_GLOBAL_THIS___[\\"myGlobal\\"][\\"nested\\"] = ___EXPOSE_LOADER_IMPORT_DEFAULT___;
44+
___EXPOSE_LOADER_GLOBAL_THIS___[\\"myGlobal\\"][\\"nested\\"] = ___EXPOSE_LOADER_IMPORT___;
45+
var ___EXPOSE_LOADER_IMPORT_NAMED___ = ___EXPOSE_LOADER_IMPORT___.foo
4746
if (!___EXPOSE_LOADER_GLOBAL_THIS___[\\"myOtherGlobal\\"]) ___EXPOSE_LOADER_GLOBAL_THIS___[\\"myOtherGlobal\\"] = {};
48-
___EXPOSE_LOADER_GLOBAL_THIS___[\\"myOtherGlobal\\"][\\"nested\\"] = ___EXPOSE_LOADER_IMPORT_DEFAULT___;
49-
module.exports = ___EXPOSE_LOADER_IMPORT___;"
47+
___EXPOSE_LOADER_GLOBAL_THIS___[\\"myOtherGlobal\\"][\\"nested\\"] = ___EXPOSE_LOADER_IMPORT_NAMED___;
48+
"
5049
`;
5150

52-
exports[`loader should work for nested preporties for a global object: result 1`] = `
51+
exports[`loader should work for nested properties for a global object: result 1`] = `
5352
Object {
5453
"ExposeLoader": Object {
5554
"foo": "bar",
@@ -60,28 +59,25 @@ Object {
6059
},
6160
},
6261
"myOtherGlobal": Object {
63-
"nested": Object {
64-
"foo": "bar",
65-
},
62+
"nested": "bar",
6663
},
6764
}
6865
`;
6966

70-
exports[`loader should work for nested preporties for a global object: warnings 1`] = `Array []`;
67+
exports[`loader should work for nested properties for a global object: warnings 1`] = `Array []`;
7168

7269
exports[`loader should work from esModule export: errors 1`] = `Array []`;
7370

7471
exports[`loader should work from esModule export: module 1`] = `
75-
"var ___EXPOSE_LOADER_IMPORT___ = require(\\"-!./global-module-default-export.js\\");
72+
"const globalObject5 = { foo: 'bar' };
73+
74+
export default globalObject5;
75+
76+
var ___EXPOSE_LOADER_IMPORT___ = require(\\"-!./global-module-default-export.js\\");
7677
var ___EXPOSE_LOADER_GET_GLOBAL_THIS___ = require(\\"../../src/runtime/getGlobalThis.js\\");
7778
var ___EXPOSE_LOADER_GLOBAL_THIS___ = ___EXPOSE_LOADER_GET_GLOBAL_THIS___();
78-
var ___EXPOSE_LOADER_IMPORT_DEFAULT___ = ___EXPOSE_LOADER_IMPORT___.__esModule
79-
? ___EXPOSE_LOADER_IMPORT___.default
80-
|| ___EXPOSE_LOADER_IMPORT___
81-
82-
: ___EXPOSE_LOADER_IMPORT___
83-
___EXPOSE_LOADER_GLOBAL_THIS___[\\"myGlobal\\"] = ___EXPOSE_LOADER_IMPORT_DEFAULT___;
84-
module.exports = ___EXPOSE_LOADER_IMPORT___;"
79+
___EXPOSE_LOADER_GLOBAL_THIS___[\\"myGlobal\\"] = ___EXPOSE_LOADER_IMPORT___;
80+
"
8581
`;
8682

8783
exports[`loader should work from esModule export: result 1`] = `
@@ -92,27 +88,82 @@ Object {
9288
},
9389
},
9490
"myGlobal": Object {
95-
"foo": "bar",
91+
"default": Object {
92+
"foo": "bar",
93+
},
9694
},
9795
}
9896
`;
9997

10098
exports[`loader should work from esModule export: warnings 1`] = `Array []`;
10199

100+
exports[`loader should work string config: errors 1`] = `Array []`;
101+
102+
exports[`loader should work string config: module 1`] = `
103+
"const globalObject6 = { foo: 'bar' };
104+
const globalObject7 = { bar: 'foo' };
105+
106+
export default function globalDef(){
107+
return { bar: 'foo' };
108+
};
109+
110+
export { globalObject6, globalObject7 };
111+
112+
var ___EXPOSE_LOADER_IMPORT___ = require(\\"-!./global-module-named-exports.js\\");
113+
var ___EXPOSE_LOADER_GET_GLOBAL_THIS___ = require(\\"../../src/runtime/getGlobalThis.js\\");
114+
var ___EXPOSE_LOADER_GLOBAL_THIS___ = ___EXPOSE_LOADER_GET_GLOBAL_THIS___();
115+
var ___EXPOSE_LOADER_IMPORT_NAMED___ = ___EXPOSE_LOADER_IMPORT___.globalObject6
116+
if (!___EXPOSE_LOADER_GLOBAL_THIS___[\\"myGlobal_alias\\"]) ___EXPOSE_LOADER_GLOBAL_THIS___[\\"myGlobal_alias\\"] = {};
117+
___EXPOSE_LOADER_GLOBAL_THIS___[\\"myGlobal_alias\\"][\\"globalObject6\\"] = ___EXPOSE_LOADER_IMPORT_NAMED___;
118+
var ___EXPOSE_LOADER_IMPORT_NAMED___ = ___EXPOSE_LOADER_IMPORT___.globalObject7
119+
if (!___EXPOSE_LOADER_GLOBAL_THIS___[\\"myGlobal_alias\\"]) ___EXPOSE_LOADER_GLOBAL_THIS___[\\"myGlobal_alias\\"] = {};
120+
___EXPOSE_LOADER_GLOBAL_THIS___[\\"myGlobal_alias\\"][\\"globalObject7\\"] = ___EXPOSE_LOADER_IMPORT_NAMED___;
121+
var ___EXPOSE_LOADER_IMPORT_NAMED___ = ___EXPOSE_LOADER_IMPORT___.default
122+
if (!___EXPOSE_LOADER_GLOBAL_THIS___[\\"myGlobal_alias\\"]) ___EXPOSE_LOADER_GLOBAL_THIS___[\\"myGlobal_alias\\"] = {};
123+
___EXPOSE_LOADER_GLOBAL_THIS___[\\"myGlobal_alias\\"][\\"default\\"] = ___EXPOSE_LOADER_IMPORT_NAMED___;
124+
"
125+
`;
126+
127+
exports[`loader should work string config: result 1`] = `
128+
Object {
129+
"ExposeLoader": Object {
130+
"default": Object {
131+
"default": [Function],
132+
"globalObject6": Object {
133+
"foo": "bar",
134+
},
135+
"globalObject7": Object {
136+
"bar": "foo",
137+
},
138+
},
139+
},
140+
"myGlobal_alias": Object {
141+
"default": [Function],
142+
"globalObject6": Object {
143+
"foo": "bar",
144+
},
145+
"globalObject7": Object {
146+
"bar": "foo",
147+
},
148+
},
149+
}
150+
`;
151+
152+
exports[`loader should work string config: warnings 1`] = `Array []`;
153+
102154
exports[`loader should work with multiple exposes: errors 1`] = `Array []`;
103155

104156
exports[`loader should work with multiple exposes: module 1`] = `
105-
"var ___EXPOSE_LOADER_IMPORT___ = require(\\"-!./global-commonjs2-single-export.js\\");
157+
"const globalObject4 = { foo: 'bar' };
158+
159+
module.exports = globalObject4;
160+
161+
var ___EXPOSE_LOADER_IMPORT___ = require(\\"-!./global-commonjs2-single-export.js\\");
106162
var ___EXPOSE_LOADER_GET_GLOBAL_THIS___ = require(\\"../../src/runtime/getGlobalThis.js\\");
107163
var ___EXPOSE_LOADER_GLOBAL_THIS___ = ___EXPOSE_LOADER_GET_GLOBAL_THIS___();
108-
var ___EXPOSE_LOADER_IMPORT_DEFAULT___ = ___EXPOSE_LOADER_IMPORT___.__esModule
109-
? ___EXPOSE_LOADER_IMPORT___.default
110-
|| ___EXPOSE_LOADER_IMPORT___
111-
112-
: ___EXPOSE_LOADER_IMPORT___
113-
___EXPOSE_LOADER_GLOBAL_THIS___[\\"myGlobal\\"] = ___EXPOSE_LOADER_IMPORT_DEFAULT___;
114-
___EXPOSE_LOADER_GLOBAL_THIS___[\\"myOtherGlobal\\"] = ___EXPOSE_LOADER_IMPORT_DEFAULT___;
115-
module.exports = ___EXPOSE_LOADER_IMPORT___;"
164+
___EXPOSE_LOADER_GLOBAL_THIS___[\\"myGlobal\\"] = ___EXPOSE_LOADER_IMPORT___;
165+
___EXPOSE_LOADER_GLOBAL_THIS___[\\"myOtherGlobal\\"] = ___EXPOSE_LOADER_IMPORT___;
166+
"
116167
`;
117168

118169
exports[`loader should work with multiple exposes: result 1`] = `
@@ -134,16 +185,15 @@ exports[`loader should work with multiple exposes: warnings 1`] = `Array []`;
134185
exports[`loader should work: errors 1`] = `Array []`;
135186

136187
exports[`loader should work: module 1`] = `
137-
"var ___EXPOSE_LOADER_IMPORT___ = require(\\"-!./global-commonjs2-single-export.js\\");
188+
"const globalObject4 = { foo: 'bar' };
189+
190+
module.exports = globalObject4;
191+
192+
var ___EXPOSE_LOADER_IMPORT___ = require(\\"-!./global-commonjs2-single-export.js\\");
138193
var ___EXPOSE_LOADER_GET_GLOBAL_THIS___ = require(\\"../../src/runtime/getGlobalThis.js\\");
139194
var ___EXPOSE_LOADER_GLOBAL_THIS___ = ___EXPOSE_LOADER_GET_GLOBAL_THIS___();
140-
var ___EXPOSE_LOADER_IMPORT_DEFAULT___ = ___EXPOSE_LOADER_IMPORT___.__esModule
141-
? ___EXPOSE_LOADER_IMPORT___.default
142-
|| ___EXPOSE_LOADER_IMPORT___
143-
144-
: ___EXPOSE_LOADER_IMPORT___
145-
___EXPOSE_LOADER_GLOBAL_THIS___[\\"myGlobal\\"] = ___EXPOSE_LOADER_IMPORT_DEFAULT___;
146-
module.exports = ___EXPOSE_LOADER_IMPORT___;"
195+
___EXPOSE_LOADER_GLOBAL_THIS___[\\"myGlobal\\"] = ___EXPOSE_LOADER_IMPORT___;
196+
"
147197
`;
148198

149199
exports[`loader should work: result 1`] = `
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
const globalObject6 = { foo: 'bar' };
22
const globalObject7 = { bar: 'foo' };
33

4+
export default function globalDef(){
5+
return { bar: 'foo' };
6+
};
7+
48
export { globalObject6, globalObject7 };
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import * as myExports from './global-module-named-exports';
2+
3+
export default myExports;

test/helpers/execute.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export default (code) => {
1616
module._compile(
1717
`
1818
const result = {};
19-
19+
2020
if (typeof myGlobal !== "undefined") {
2121
delete myGlobal;
2222
}
@@ -37,6 +37,10 @@ if (typeof myOtherGlobal !== "undefined") {
3737
result['myOtherGlobal'] = myOtherGlobal;
3838
}
3939
40+
if (typeof myGlobal_alias !== "undefined") {
41+
result['myGlobal_alias'] = myGlobal_alias;
42+
}
43+
4044
module.exports = result;`,
4145
resource
4246
);

test/loader.test.js

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,9 @@ describe('loader', () => {
5757
expect(getWarnings(stats)).toMatchSnapshot('warnings');
5858
});
5959

60-
it('should work for nested preporties for a global object', async () => {
60+
it('should work for nested properties for a global object', async () => {
6161
const compiler = getCompiler('simple-commonjs2-single-export.js', {
62-
exposes: ['myGlobal.nested', 'myOtherGlobal.nested'],
62+
exposes: ['myGlobal.nested', 'myOtherGlobal.nested foo'],
6363
});
6464
const stats = await compile(compiler);
6565

@@ -88,4 +88,24 @@ describe('loader', () => {
8888
expect(getErrors(stats)).toMatchSnapshot('errors');
8989
expect(getWarnings(stats)).toMatchSnapshot('warnings');
9090
});
91+
92+
it('should work string config', async () => {
93+
const compiler = getCompiler('simple-module-named-export.js', {
94+
exposes: [
95+
'myGlobal_alias.globalObject6 globalObject6',
96+
'myGlobal_alias.globalObject7 globalObject7',
97+
'myGlobal_alias.default default',
98+
],
99+
});
100+
const stats = await compile(compiler);
101+
102+
expect(
103+
getModuleSource('./global-module-named-exports.js-exposed', stats)
104+
).toMatchSnapshot('module');
105+
expect(
106+
execute(readAsset('main.bundle.js', compiler, stats))
107+
).toMatchSnapshot('result');
108+
expect(getErrors(stats)).toMatchSnapshot('errors');
109+
expect(getWarnings(stats)).toMatchSnapshot('warnings');
110+
});
91111
});

0 commit comments

Comments
 (0)