1+ let { nollup, fs, expect, rollup } = require ( '../../nollup' ) ;
2+ let { executeChunkedFiles } = require ( './external-runtime.js' ) ;
3+
4+ describe ( 'External' , ( ) => {
5+ [ 'esm' , 'cjs' , 'iife' ] . forEach ( format => {
6+ describe ( format , ( ) => {
7+ it ( 'should allow external array to work' , async ( ) => {
8+ fs . stub ( './src/impl.js' , ( ) => `export default true;` )
9+ fs . stub ( './src/main.js' , ( ) => `
10+ import result from './impl';
11+ import fs from "fs";
12+ if (fs.readFileSync) {
13+ self.result = result
14+ }
15+ ` ) ;
16+
17+ let bundle = await nollup ( {
18+ input : './src/main.js' ,
19+ external : [ 'fs' ]
20+ } ) ;
21+
22+ let { output } = await bundle . generate ( { format } ) ;
23+ let result = await executeChunkedFiles ( format , 'main.js' , output ) ;
24+ expect ( result ) . to . equal ( true ) ;
25+ fs . reset ( ) ;
26+ } ) ;
27+
28+ it ( 'should allow external function to work' , async ( ) => {
29+ fs . stub ( './src/impl.js' , ( ) => `export default true;` )
30+ fs . stub ( './src/main.js' , ( ) => `
31+ import result from './impl';
32+ import fs from "fs";
33+ if (fs.readFileSync) {
34+ self.result = result
35+ }
36+ ` ) ;
37+
38+ let bundle = await nollup ( {
39+ input : './src/main.js' ,
40+ external : id => id === 'fs'
41+ } ) ;
42+
43+ let { output } = await bundle . generate ( { format } ) ;
44+ let result = await executeChunkedFiles ( format , 'main.js' , output ) ;
45+ expect ( result ) . to . equal ( true ) ;
46+ fs . reset ( ) ;
47+ } ) ;
48+
49+ it ( 'should allow external from resolveId to work' , async ( ) => {
50+ fs . stub ( './src/impl.js' , ( ) => `export default true;` )
51+ fs . stub ( './src/main.js' , ( ) => `
52+ import result from './impl';
53+ import fs from "fs";
54+ if (fs.readFileSync) {
55+ self.result = result
56+ }
57+ ` ) ;
58+
59+ let bundle = await nollup ( {
60+ input : './src/main.js' ,
61+ plugins : [ {
62+ resolveId ( id , parent ) {
63+ if ( id === 'fs' ) {
64+ return {
65+ id : 'fs' ,
66+ external : true
67+ }
68+ }
69+ }
70+ } ]
71+ } ) ;
72+
73+ let { output } = await bundle . generate ( { format } ) ;
74+ let result = await executeChunkedFiles ( format , 'main.js' , output ) ;
75+ expect ( result ) . to . equal ( true ) ;
76+ fs . reset ( ) ;
77+ } ) ;
78+
79+ it ( 'should allow default import for external' , async ( ) => {
80+ fs . stub ( './src/main.js' , ( ) => `
81+ import Default from "DefaultModule";
82+ if (Default.prop) {
83+ self.result = true;
84+ }
85+ ` ) ;
86+
87+ let bundle = await nollup ( {
88+ input : './src/main.js' ,
89+ external : [ 'DefaultModule' ]
90+ } ) ;
91+
92+ let { output } = await bundle . generate ( { format } ) ;
93+ let result = await executeChunkedFiles ( format , 'main.js' , output ) ;
94+ expect ( result ) . to . equal ( true ) ;
95+ fs . reset ( ) ;
96+ } ) ;
97+
98+ it ( 'should allow named import for external' , async ( ) => {
99+ fs . stub ( './src/main.js' , ( ) => `
100+ import { NamedExport1, NamedExport2 } from "NamedModule";
101+ if (NamedExport1 === 123 && NamedExport2 === 456) {
102+ self.result = true;
103+ }
104+ ` ) ;
105+
106+ let bundle = await nollup ( {
107+ input : './src/main.js' ,
108+ external : [ 'NamedModule' ]
109+ } ) ;
110+
111+ let { output } = await bundle . generate ( { format } ) ;
112+ let result = await executeChunkedFiles ( format , 'main.js' , output ) ;
113+ expect ( result ) . to . equal ( true ) ;
114+ fs . reset ( ) ;
115+ } ) ;
116+
117+ it ( 'should allow namespace import for external' , async ( ) => {
118+ fs . stub ( './src/main.js' , ( ) => `
119+ import * as Namespace from "NamedModule";
120+ if (Namespace.NamedExport1 === 123 && Namespace.NamedExport2 === 456) {
121+ self.result = true;
122+ }
123+ ` ) ;
124+
125+ let bundle = await nollup ( {
126+ input : './src/main.js' ,
127+ external : [ 'NamedModule' ]
128+ } ) ;
129+
130+ let { output } = await bundle . generate ( { format } ) ;
131+ let result = await executeChunkedFiles ( format , 'main.js' , output ) ;
132+ expect ( result ) . to . equal ( true ) ;
133+ fs . reset ( ) ;
134+ } ) ;
135+
136+ it ( 'should allow bare import for external' , async ( ) => {
137+ fs . stub ( './src/main.js' , ( ) => `
138+ import 'BareModule';
139+ if (self.BareModule.prop) {
140+ self.result = true;
141+ }
142+ ` ) ;
143+
144+ let bundle = await nollup ( {
145+ input : './src/main.js' ,
146+ external : [ 'BareModule' ]
147+ } ) ;
148+
149+ let { output } = await bundle . generate ( { format } ) ;
150+ let result = await executeChunkedFiles ( format , 'main.js' , output ) ;
151+ expect ( result ) . to . equal ( true ) ;
152+ fs . reset ( ) ;
153+ } ) ;
154+
155+ it ( 'should allow export from for default for external' , async ( ) => {
156+ fs . stub ( './src/impl.js' , ( ) => `export { default } from 'DefaultModule';` )
157+ fs . stub ( './src/main.js' , ( ) => `
158+ import Default from './impl';
159+ if (Default.prop) {
160+ self.result = true;
161+ }
162+ ` ) ;
163+
164+ let bundle = await nollup ( {
165+ input : './src/main.js' ,
166+ external : [ 'DefaultModule' ]
167+ } ) ;
168+
169+ let { output } = await bundle . generate ( { format } ) ;
170+ let result = await executeChunkedFiles ( format , 'main.js' , output ) ;
171+ expect ( result ) . to . equal ( true ) ;
172+ fs . reset ( ) ;
173+ } ) ;
174+
175+ it ( 'should allow export from for named for external' , async ( ) => {
176+ fs . stub ( './src/impl.js' , ( ) => `export { NamedExport1, NamedExport2 as Other } from 'NamedModule';` )
177+ fs . stub ( './src/main.js' , ( ) => `
178+ import { NamedExport1, Other } from './impl';
179+ if (NamedExport1 === 123 && Other === 456) {
180+ self.result = true;
181+ }
182+ ` ) ;
183+
184+ let bundle = await nollup ( {
185+ input : './src/main.js' ,
186+ external : [ 'NamedModule' ]
187+ } ) ;
188+
189+ let { output } = await bundle . generate ( { format } ) ;
190+ let result = await executeChunkedFiles ( format , 'main.js' , output ) ;
191+ expect ( result ) . to . equal ( true ) ;
192+ fs . reset ( ) ;
193+ } ) ;
194+
195+ it ( 'should allow export from for namespace for external' , async ( ) => {
196+ fs . stub ( './src/impl.js' , ( ) => `export * from 'NamedModule';` )
197+ fs . stub ( './src/main.js' , ( ) => `
198+ import { NamedExport1, NamedExport2 } from './impl';
199+ if (NamedExport1 === 123 && NamedExport2 === 456) {
200+ self.result = true;
201+ }
202+ ` ) ;
203+
204+ let bundle = await nollup ( {
205+ input : './src/main.js' ,
206+ external : [ 'NamedModule' ]
207+ } ) ;
208+
209+ let { output } = await bundle . generate ( { format } ) ;
210+ let result = await executeChunkedFiles ( format , 'main.js' , output ) ;
211+ expect ( result ) . to . equal ( true ) ;
212+ fs . reset ( ) ;
213+ } ) ;
214+ } ) ;
215+ } ) ;
216+
217+ describe ( 'Externals in Chunks' , ( ) => {
218+ [ 'esm' , 'cjs' ] . forEach ( format => {
219+ it ( 'should allow external imports for chunks (' + format + ')' , async ( ) => {
220+ fs . stub ( './src/chunk.js' , ( ) => `export { NamedExport1, NamedExport2 } from 'NamedModule';` )
221+ fs . stub ( './src/main.js' , ( ) => `
222+ import('./chunk').then(mod => {
223+ if (mod.NamedExport1 === 123 && mod.NamedExport2 === 456) {
224+ self.result = true;
225+ }
226+ });
227+ ` ) ;
228+
229+ let bundle = await nollup ( {
230+ input : './src/main.js' ,
231+ external : [ 'NamedModule' ]
232+ } ) ;
233+
234+ let { output } = await bundle . generate ( { format, chunkFileNames : '[name].js' } ) ;
235+ let result = await executeChunkedFiles ( format , 'main.js' , output , true ) ;
236+ expect ( result ) . to . equal ( true ) ;
237+ fs . reset ( ) ;
238+ } ) ;
239+ } )
240+ } )
241+
242+ describe ( 'Default Fallback' , ( ) => {
243+ [ 'cjs' , 'iife' ] . forEach ( format => {
244+ it ( 'should fallback if default import not found for external (' + format + ')' , async ( ) => {
245+ fs . stub ( './src/main.js' , ( ) => `
246+ import Default from "DefaultFallbackModule";
247+ if (Default.prop) {
248+ self.result = true;
249+ }
250+ ` ) ;
251+
252+ let bundle = await nollup ( {
253+ input : './src/main.js' ,
254+ external : [ 'DefaultFallbackModule' ]
255+ } ) ;
256+
257+ let { output } = await bundle . generate ( { format } ) ;
258+ let result = await executeChunkedFiles ( format , 'main.js' , output ) ;
259+ expect ( result ) . to . equal ( true ) ;
260+ fs . reset ( ) ;
261+ } ) ;
262+ } )
263+ } ) ;
264+
265+ describe ( 'IIFE Name Conversion' , ( ) => {
266+ it ( 'should convert special characters to underscore' , async ( ) => {
267+ fs . stub ( './src/main.js' , ( ) => `
268+ import { NamedExport1, NamedExport2 } from "+IIFE-Special-Characters$";
269+ if (NamedExport1 === 123 && NamedExport2 === 456) {
270+ self.result = true;
271+ }
272+ ` ) ;
273+
274+ let bundle = await nollup ( {
275+ input : './src/main.js' ,
276+ external : [ '+IIFE-Special-Characters$' ]
277+ } ) ;
278+
279+ let { output } = await bundle . generate ( { format : 'iife' } ) ;
280+ let result = await executeChunkedFiles ( 'iife' , 'main.js' , output ) ;
281+ expect ( result ) . to . equal ( true ) ;
282+ fs . reset ( ) ;
283+ } ) ;
284+
285+ it ( 'should use global object to determine variable name' , async ( ) => {
286+ fs . stub ( './src/main.js' , ( ) => `
287+ import { NamedExport1, NamedExport2 } from "+IIFE-Special-Characters$";
288+ if (NamedExport1 === 123 && NamedExport2 === 456) {
289+ self.result = true;
290+ }
291+ ` ) ;
292+
293+ let bundle = await nollup ( {
294+ input : './src/main.js' ,
295+ external : [ '+IIFE-Special-Characters$' ] ,
296+ output : {
297+ globals : {
298+ '+IIFE-Special-Characters$' : '__globalModule'
299+ }
300+ }
301+ } ) ;
302+
303+ let { output } = await bundle . generate ( { format : 'iife' } ) ;
304+ let result = await executeChunkedFiles ( 'iife' , 'main.js' , output ) ;
305+ expect ( result ) . to . equal ( true ) ;
306+ fs . reset ( ) ;
307+ } ) ;
308+ } )
309+
310+ } ) ;
0 commit comments