forked from rollup/rollup
-
Notifications
You must be signed in to change notification settings - Fork 0
/
iife.js
140 lines (124 loc) · 4.59 KB
/
iife.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
const assert = require('node:assert');
const { rollup } = require('../../dist/rollup');
const { loader } = require('../utils.js');
const { compareError } = require('../utils.js');
function runTestCode(code, globals) {
const globalsWithAssert = { ...globals, assert };
const globalKeys = Object.keys(globalsWithAssert);
const function_ = new Function(globalKeys, code);
function_.apply(
globals,
globalKeys.map(key => globalsWithAssert[key])
);
}
function runIifeTest(code, outputOptions) {
const bundleName = outputOptions.name.split('.')[0];
const globals = { external: 'external', __exports: {} };
runTestCode(
bundleName && !bundleName.includes('@')
? `${code}if (typeof ${bundleName} !== 'undefined') __exports.${bundleName} = ${bundleName};`
: code,
globals
);
return getIifeExports(globals.__exports[bundleName] ? globals.__exports : globals, outputOptions);
}
function getIifeExports(global, outputOptions) {
if (outputOptions.name) {
return outputOptions.name
.split('.')
.reduce((currentVariable, nextKey) => currentVariable[nextKey] || {}, global);
}
return {};
}
function getIifeCode(inputCode, outputOptions) {
return rollup({
input: 'input',
external: ['external'],
plugins: [loader({ input: inputCode })]
})
.then(bundle =>
bundle.generate({ format: 'iife', globals: { external: 'external' }, ...outputOptions })
)
.then(({ output }) => output[0].code);
}
function runTestsWithCode(code, outputOptions, expectedExports) {
it('works with extend=false', () => {
const options = { extend: false, ...outputOptions };
return getIifeCode(code, options).then(code =>
assert.deepEqual(runIifeTest(code, options), expectedExports, 'expected exports are returned')
);
});
it('works with extend=true', () => {
const options = { extend: true, ...outputOptions };
return getIifeCode(code, options).then(code =>
assert.deepEqual(runIifeTest(code, options), expectedExports, 'expected exports are returned')
);
});
}
for (const name of ['bundle', '@my.@nested/value.bundle'])
for (const compact of [false, true])
describe(`The IIFE wrapper with name="${name}", compact=${compact}`, () => {
const outputOptions = { compact, name };
describe('creating a bundle with neither exports nor imports', () =>
runTestsWithCode('assert.ok(true);', outputOptions, {}));
describe('creating a bundle with named exports', () =>
runTestsWithCode('export const x = 42;', outputOptions, { x: 42 }));
describe('creating a bundle with a default export', () =>
runTestsWithCode('export default {value: 42};', outputOptions, { value: 42 }));
describe('creating a bundle with an external import', () =>
runTestsWithCode(
'import value from "external"; assert.equal(value, "external");',
outputOptions,
{}
));
describe('creating a bundle with an external import and named exports', () =>
runTestsWithCode('import value from "external"; export const x = value;', outputOptions, {
x: 'external'
}));
describe('creating a bundle with an external import and a default export', () =>
runTestsWithCode('import value from "external"; export default {value};', outputOptions, {
value: 'external'
}));
});
describe('The IIFE wrapper with an illegal name', () => {
it('fails if the name starts with a digit', () =>
getIifeCode('export const x = 42;', { name: '1name' })
.then(() => {
throw new Error('Expected an error to be thrown.');
})
.catch(error =>
compareError(error, {
code: 'ILLEGAL_IDENTIFIER_AS_NAME',
message:
'Given name "1name" is not a legal JS identifier. If you need this, you can try "output.extend: true".',
url: 'https://rollupjs.org/configuration-options/#output-extend'
})
));
it('fails if the name contains an illegal character', () =>
getIifeCode('export const x = 42;', { name: 'my=name' })
.then(() => {
throw new Error('Expected an error to be thrown.');
})
.catch(error =>
compareError(error, {
code: 'ILLEGAL_IDENTIFIER_AS_NAME',
message:
'Given name "my=name" is not a legal JS identifier. If you need this, you can try "output.extend: true".',
url: 'https://rollupjs.org/configuration-options/#output-extend'
})
));
it('does not fail for illegal characters if the extend option is used', () =>
getIifeCode('export const x = 42;', { name: 'my=name', extend: true }).then(code =>
assert.strictEqual(
code,
'(function (exports) {\n' +
"\t'use strict';\n" +
'\n' +
'\tconst x = 42;\n' +
'\n' +
'\texports.x = x;\n' +
'\n' +
'})(this["my=name"] = this["my=name"] || {});\n'
)
));
});