UNPKG

14.8 kBJavaScriptView Raw
1// @flow
2
3import assert from 'assert';
4import path from 'path';
5import tempy from 'tempy';
6import {inputFS as fs} from '@parcel/test-utils';
7import {DEFAULT_OPTIONS} from './utils';
8
9import TargetResolver from '../src/TargetResolver';
10
11const COMMON_TARGETS_FIXTURE_PATH = path.join(
12 __dirname,
13 'fixtures/common-targets'
14);
15
16const CUSTOM_TARGETS_FIXTURE_PATH = path.join(
17 __dirname,
18 'fixtures/custom-targets'
19);
20
21const INVALID_TARGETS_FIXTURE_PATH = path.join(
22 __dirname,
23 'fixtures/invalid-targets'
24);
25
26const INVALID_ENGINES_FIXTURE_PATH = path.join(
27 __dirname,
28 'fixtures/invalid-engines'
29);
30
31const INVALID_DISTPATH_FIXTURE_PATH = path.join(
32 __dirname,
33 'fixtures/invalid-distpath'
34);
35
36const CONTEXT_FIXTURE_PATH = path.join(__dirname, 'fixtures/context');
37
38describe('TargetResolver', () => {
39 let cacheDir;
40 beforeEach(() => {
41 cacheDir = tempy.directory();
42 });
43
44 afterEach(() => {
45 return fs.rimraf(cacheDir);
46 });
47
48 it('resolves exactly specified targets', async () => {
49 let targetResolver = new TargetResolver({
50 ...DEFAULT_OPTIONS,
51 targets: {
52 customA: {
53 context: 'browser',
54 distDir: 'customA'
55 },
56 customB: {
57 distDir: 'customB',
58 engines: {
59 node: '>= 8.0.0'
60 }
61 }
62 }
63 });
64
65 assert.deepEqual(
66 await targetResolver.resolve(COMMON_TARGETS_FIXTURE_PATH),
67 {
68 files: [],
69 targets: [
70 {
71 name: 'customA',
72 publicUrl: undefined,
73 distDir: path.resolve('customA'),
74 env: {
75 context: 'browser',
76 includeNodeModules: true,
77 engines: {
78 browsers: ['> 0.25%']
79 },
80 outputFormat: 'global',
81 isLibrary: false
82 },
83 sourceMap: undefined
84 },
85 {
86 name: 'customB',
87 publicUrl: undefined,
88 distDir: path.resolve('customB'),
89 env: {
90 context: 'node',
91 includeNodeModules: false,
92 engines: {
93 node: '>= 8.0.0'
94 },
95 outputFormat: 'commonjs',
96 isLibrary: false
97 },
98 sourceMap: undefined
99 }
100 ]
101 }
102 );
103 });
104
105 it('resolves common targets from package.json', async () => {
106 let targetResolver = new TargetResolver(DEFAULT_OPTIONS);
107
108 assert.deepEqual(
109 await targetResolver.resolve(COMMON_TARGETS_FIXTURE_PATH),
110 {
111 files: [
112 {filePath: path.join(COMMON_TARGETS_FIXTURE_PATH, 'package.json')}
113 ],
114 targets: [
115 {
116 name: 'main',
117 distDir: path.join(__dirname, 'fixtures/common-targets/dist/main'),
118 distEntry: 'index.js',
119 publicUrl: '/',
120 env: {
121 context: 'node',
122 engines: {
123 node: '>= 8.0.0'
124 },
125 includeNodeModules: false,
126 outputFormat: 'commonjs',
127 isLibrary: true
128 },
129 sourceMap: undefined
130 },
131 {
132 name: 'module',
133 distDir: path.join(
134 __dirname,
135 'fixtures/common-targets/dist/module'
136 ),
137 distEntry: 'index.js',
138 publicUrl: '/',
139 env: {
140 context: 'browser',
141 engines: {
142 browsers: ['last 1 version']
143 },
144 includeNodeModules: false,
145 outputFormat: 'esmodule',
146 isLibrary: true
147 },
148 sourceMap: {
149 inlineSources: true
150 }
151 },
152 {
153 name: 'browser',
154 distDir: path.join(
155 __dirname,
156 'fixtures/common-targets/dist/browser'
157 ),
158 distEntry: 'index.js',
159 publicUrl: '/assets',
160 env: {
161 context: 'browser',
162 engines: {
163 browsers: ['last 1 version']
164 },
165 includeNodeModules: false,
166 outputFormat: 'commonjs',
167 isLibrary: true
168 },
169 sourceMap: undefined
170 }
171 ]
172 }
173 );
174 });
175
176 it('resolves custom targets from package.json', async () => {
177 let targetResolver = new TargetResolver(DEFAULT_OPTIONS);
178 assert.deepEqual(
179 await targetResolver.resolve(CUSTOM_TARGETS_FIXTURE_PATH),
180 {
181 files: [
182 {filePath: path.join(CUSTOM_TARGETS_FIXTURE_PATH, 'package.json')}
183 ],
184 targets: [
185 {
186 name: 'main',
187 distDir: path.join(__dirname, 'fixtures/custom-targets/dist/main'),
188 distEntry: 'index.js',
189 publicUrl: '/',
190 env: {
191 context: 'node',
192 engines: {
193 node: '>= 8.0.0'
194 },
195 includeNodeModules: false,
196 outputFormat: 'commonjs',
197 isLibrary: true
198 },
199 sourceMap: undefined
200 },
201 {
202 name: 'browserModern',
203 distDir: path.join(
204 __dirname,
205 'fixtures/custom-targets/dist/browserModern'
206 ),
207 distEntry: 'index.js',
208 publicUrl: '/',
209 env: {
210 context: 'browser',
211 engines: {
212 browsers: ['last 1 version']
213 },
214 includeNodeModules: true,
215 outputFormat: 'global',
216 isLibrary: false
217 },
218 sourceMap: undefined
219 },
220 {
221 name: 'browserLegacy',
222 distDir: path.join(
223 __dirname,
224 'fixtures/custom-targets/dist/browserLegacy'
225 ),
226 distEntry: 'index.js',
227 publicUrl: '/',
228 env: {
229 context: 'browser',
230 engines: {
231 browsers: ['ie11']
232 },
233 includeNodeModules: true,
234 outputFormat: 'global',
235 isLibrary: false
236 },
237 sourceMap: undefined
238 }
239 ]
240 }
241 );
242 });
243
244 it('resolves main target with context from package.json', async () => {
245 let targetResolver = new TargetResolver(DEFAULT_OPTIONS);
246 assert.deepEqual(await targetResolver.resolve(CONTEXT_FIXTURE_PATH), {
247 files: [{filePath: path.join(CONTEXT_FIXTURE_PATH, 'package.json')}],
248 targets: [
249 {
250 name: 'main',
251 distDir: path.join(__dirname, 'fixtures/context/dist/main'),
252 distEntry: 'index.js',
253 publicUrl: '/',
254 env: {
255 context: 'node',
256 engines: {
257 browsers: [
258 'last 1 Chrome version',
259 'last 1 Safari version',
260 'last 1 Firefox version',
261 'last 1 Edge version'
262 ]
263 },
264 includeNodeModules: false,
265 isLibrary: true,
266 outputFormat: 'commonjs'
267 },
268 sourceMap: undefined
269 }
270 ]
271 });
272 });
273
274 it('resolves a subset of package.json targets when given a list of names', async () => {
275 let targetResolver = new TargetResolver({
276 ...DEFAULT_OPTIONS,
277 targets: ['main', 'browser']
278 });
279
280 assert.deepEqual(
281 await targetResolver.resolve(COMMON_TARGETS_FIXTURE_PATH),
282 {
283 files: [
284 {filePath: path.join(COMMON_TARGETS_FIXTURE_PATH, 'package.json')}
285 ],
286 targets: [
287 {
288 name: 'main',
289 distDir: path.join(__dirname, 'fixtures/common-targets/dist/main'),
290 distEntry: 'index.js',
291 publicUrl: '/',
292 env: {
293 context: 'node',
294 engines: {
295 node: '>= 8.0.0'
296 },
297 includeNodeModules: false,
298 outputFormat: 'commonjs',
299 isLibrary: true
300 },
301 sourceMap: undefined
302 },
303 {
304 name: 'browser',
305 distDir: path.join(
306 __dirname,
307 'fixtures/common-targets/dist/browser'
308 ),
309 distEntry: 'index.js',
310 publicUrl: '/assets',
311 env: {
312 context: 'browser',
313 engines: {
314 browsers: ['last 1 version']
315 },
316 includeNodeModules: false,
317 outputFormat: 'commonjs',
318 isLibrary: true
319 },
320 sourceMap: undefined
321 }
322 ]
323 }
324 );
325 });
326
327 it('rejects invalid or unknown fields', async () => {
328 let code =
329 '{\n' +
330 '\t"targets": {\n' +
331 '\t\t"main": {\n' +
332 '\t\t\t"includeNodeModules": [\n' +
333 '\t\t\t\t"react",\n' +
334 '\t\t\t\ttrue\n' +
335 '\t\t\t],\n' +
336 '\t\t\t"context": "nodes",\n' +
337 '\t\t\t"outputFormat": "module",\n' +
338 '\t\t\t"sourceMap": {\n' +
339 '\t\t\t\t"sourceRoot": "asd",\n' +
340 '\t\t\t\t"inline": "false",\n' +
341 '\t\t\t\t"verbose": true\n' +
342 '\t\t\t},\n' +
343 '\t\t\t"engines": {\n' +
344 '\t\t\t\t"node": "12",\n' +
345 '\t\t\t\t"browser": "Chrome 70"\n' +
346 '\t\t\t}\n' +
347 '\t\t}\n' +
348 '\t}\n' +
349 '}';
350 let targetResolver = new TargetResolver({
351 ...DEFAULT_OPTIONS,
352 ...JSON.parse(code)
353 });
354
355 // $FlowFixMe assert.rejects is Node 10+
356 await assert.rejects(
357 () => targetResolver.resolve(COMMON_TARGETS_FIXTURE_PATH),
358 {
359 message: 'Invalid target descriptor for target "main"',
360 diagnostics: [
361 {
362 message: 'Invalid target descriptor for target "main"',
363 origin: '@parcel/core',
364 filePath: undefined,
365 language: 'json',
366 codeFrame: {
367 code,
368 codeHighlights: [
369 {
370 start: {line: 6, column: 5},
371 end: {line: 6, column: 8},
372 message: 'Expected a wildcard or filepath'
373 },
374 {
375 start: {line: 8, column: 15},
376 end: {line: 8, column: 21},
377 message: 'Did you mean "node"?'
378 },
379 {
380 start: {line: 9, column: 20},
381 end: {line: 9, column: 27},
382 message: 'Did you mean "esmodule"?'
383 },
384 {
385 start: {line: 12, column: 15},
386 end: {line: 12, column: 21},
387 message: 'Expected type boolean'
388 },
389 {
390 start: {line: 13, column: 5},
391 end: {line: 13, column: 13},
392 message: 'Possible values: "inlineSources"'
393 },
394 {
395 start: {line: 17, column: 5},
396 end: {line: 17, column: 13},
397 message: 'Did you mean "browsers"?'
398 }
399 ]
400 }
401 }
402 ]
403 }
404 );
405 });
406
407 it('rejects invalid or unknown fields in package.json', async () => {
408 let targetResolver = new TargetResolver(DEFAULT_OPTIONS);
409 let code = await fs.readFileSync(
410 path.join(INVALID_TARGETS_FIXTURE_PATH, 'package.json'),
411 'utf8'
412 );
413 // $FlowFixMe assert.rejects is Node 10+
414 await assert.rejects(
415 () => targetResolver.resolve(INVALID_TARGETS_FIXTURE_PATH),
416 {
417 diagnostics: [
418 {
419 message: 'Invalid target descriptor for target "module"',
420 origin: '@parcel/core',
421 filePath: path.join(INVALID_TARGETS_FIXTURE_PATH, 'package.json'),
422 language: 'json',
423 codeFrame: {
424 code,
425 codeHighlights: [
426 {
427 start: {line: 9, column: 29},
428 end: {line: 9, column: 35},
429 message: 'Expected type boolean'
430 },
431 {
432 start: {line: 11, column: 7},
433 end: {line: 11, column: 17},
434 message: 'Did you mean "publicUrl"?'
435 }
436 ]
437 }
438 }
439 ]
440 }
441 );
442 });
443
444 it('rejects invalid engines in package.json', async () => {
445 let targetResolver = new TargetResolver(DEFAULT_OPTIONS);
446 let code = await fs.readFileSync(
447 path.join(INVALID_ENGINES_FIXTURE_PATH, 'package.json'),
448 'utf8'
449 );
450 // $FlowFixMe assert.rejects is Node 10+
451 await assert.rejects(
452 () => targetResolver.resolve(INVALID_ENGINES_FIXTURE_PATH),
453 {
454 diagnostics: [
455 {
456 message: 'Invalid engines in package.json',
457 origin: '@parcel/core',
458 filePath: path.join(INVALID_ENGINES_FIXTURE_PATH, 'package.json'),
459 language: 'json',
460 codeFrame: {
461 code,
462 codeHighlights: [
463 {
464 end: {
465 column: 13,
466 line: 8
467 },
468 message: 'Did you mean "browsers"?',
469 start: {
470 column: 5,
471 line: 8
472 }
473 },
474 {
475 end: {
476 column: 5,
477 line: 7
478 },
479 message: 'Expected type string',
480 start: {
481 column: 13,
482 line: 5
483 }
484 }
485 ]
486 }
487 }
488 ]
489 }
490 );
491 });
492
493 it('rejects target distpath in package.json', async () => {
494 let targetResolver = new TargetResolver(DEFAULT_OPTIONS);
495 let code = await fs.readFileSync(
496 path.join(INVALID_DISTPATH_FIXTURE_PATH, 'package.json'),
497 'utf8'
498 );
499 // $FlowFixMe assert.rejects is Node 10+
500 await assert.rejects(
501 () => targetResolver.resolve(INVALID_DISTPATH_FIXTURE_PATH),
502 {
503 diagnostics: [
504 {
505 message: 'Invalid distPath for target "legacy"',
506 origin: '@parcel/core',
507 filePath: path.join(INVALID_DISTPATH_FIXTURE_PATH, 'package.json'),
508 language: 'json',
509 codeFrame: {
510 code,
511 codeHighlights: [
512 {
513 end: {
514 column: 13,
515 line: 2
516 },
517 message: 'Expected type string',
518 start: {
519 column: 13,
520 line: 2
521 }
522 }
523 ]
524 }
525 }
526 ]
527 }
528 );
529 });
530});