github.com/evanw/esbuild@v0.21.4/internal/bundler_tests/bundler_packagejson_test.go (about) 1 package bundler_tests 2 3 import ( 4 "testing" 5 6 "github.com/evanw/esbuild/internal/config" 7 ) 8 9 var packagejson_suite = suite{ 10 name: "packagejson", 11 } 12 13 func TestPackageJsonMain(t *testing.T) { 14 packagejson_suite.expectBundled(t, bundled{ 15 files: map[string]string{ 16 "/Users/user/project/src/entry.js": ` 17 import fn from 'demo-pkg' 18 console.log(fn()) 19 `, 20 "/Users/user/project/node_modules/demo-pkg/package.json": ` 21 { 22 "main": "./custom-main.js" 23 } 24 `, 25 "/Users/user/project/node_modules/demo-pkg/custom-main.js": ` 26 module.exports = function() { 27 return 123 28 } 29 `, 30 }, 31 entryPaths: []string{"/Users/user/project/src/entry.js"}, 32 options: config.Options{ 33 Mode: config.ModeBundle, 34 AbsOutputFile: "/Users/user/project/out.js", 35 }, 36 }) 37 } 38 39 func TestPackageJsonBadMain(t *testing.T) { 40 packagejson_suite.expectBundled(t, bundled{ 41 files: map[string]string{ 42 "/Users/user/project/src/entry.js": ` 43 import fn from 'demo-pkg' 44 console.log(fn()) 45 `, 46 "/Users/user/project/node_modules/demo-pkg/package.json": ` 47 { 48 "main": "./does-not-exist.js" 49 } 50 `, 51 "/Users/user/project/node_modules/demo-pkg/index.js": ` 52 module.exports = function() { 53 return 123 54 } 55 `, 56 }, 57 entryPaths: []string{"/Users/user/project/src/entry.js"}, 58 options: config.Options{ 59 Mode: config.ModeBundle, 60 AbsOutputFile: "/Users/user/project/out.js", 61 }, 62 }) 63 } 64 65 func TestPackageJsonSyntaxErrorComment(t *testing.T) { 66 packagejson_suite.expectBundled(t, bundled{ 67 files: map[string]string{ 68 "/Users/user/project/src/entry.js": ` 69 import fn from 'demo-pkg' 70 console.log(fn()) 71 `, 72 "/Users/user/project/node_modules/demo-pkg/package.json": ` 73 { 74 // Single-line comment 75 "a": 1 76 } 77 `, 78 "/Users/user/project/node_modules/demo-pkg/index.js": ` 79 module.exports = function() { 80 return 123 81 } 82 `, 83 }, 84 entryPaths: []string{"/Users/user/project/src/entry.js"}, 85 options: config.Options{ 86 Mode: config.ModeBundle, 87 AbsOutputFile: "/Users/user/project/out.js", 88 }, 89 expectedScanLog: `Users/user/project/node_modules/demo-pkg/package.json: ERROR: JSON does not support comments 90 `, 91 }) 92 } 93 94 func TestPackageJsonSyntaxErrorTrailingComma(t *testing.T) { 95 packagejson_suite.expectBundled(t, bundled{ 96 files: map[string]string{ 97 "/Users/user/project/src/entry.js": ` 98 import fn from 'demo-pkg' 99 console.log(fn()) 100 `, 101 "/Users/user/project/node_modules/demo-pkg/package.json": ` 102 { 103 "a": 1, 104 "b": 2, 105 } 106 `, 107 "/Users/user/project/node_modules/demo-pkg/index.js": ` 108 module.exports = function() { 109 return 123 110 } 111 `, 112 }, 113 entryPaths: []string{"/Users/user/project/src/entry.js"}, 114 options: config.Options{ 115 Mode: config.ModeBundle, 116 AbsOutputFile: "/Users/user/project/out.js", 117 }, 118 expectedScanLog: `Users/user/project/node_modules/demo-pkg/package.json: ERROR: JSON does not support trailing commas 119 `, 120 }) 121 } 122 123 func TestPackageJsonModule(t *testing.T) { 124 packagejson_suite.expectBundled(t, bundled{ 125 files: map[string]string{ 126 "/Users/user/project/src/entry.js": ` 127 import fn from 'demo-pkg' 128 console.log(fn()) 129 `, 130 "/Users/user/project/node_modules/demo-pkg/package.json": ` 131 { 132 "main": "./main.js", 133 "module": "./main.esm.js" 134 } 135 `, 136 "/Users/user/project/node_modules/demo-pkg/main.js": ` 137 module.exports = function() { 138 return 123 139 } 140 `, 141 "/Users/user/project/node_modules/demo-pkg/main.esm.js": ` 142 export default function() { 143 return 123 144 } 145 `, 146 }, 147 entryPaths: []string{"/Users/user/project/src/entry.js"}, 148 options: config.Options{ 149 Mode: config.ModeBundle, 150 AbsOutputFile: "/Users/user/project/out.js", 151 }, 152 }) 153 } 154 155 func TestPackageJsonBrowserString(t *testing.T) { 156 packagejson_suite.expectBundled(t, bundled{ 157 files: map[string]string{ 158 "/Users/user/project/src/entry.js": ` 159 import fn from 'demo-pkg' 160 console.log(fn()) 161 `, 162 "/Users/user/project/node_modules/demo-pkg/package.json": ` 163 { 164 "browser": "./browser" 165 } 166 `, 167 "/Users/user/project/node_modules/demo-pkg/browser.js": ` 168 module.exports = function() { 169 return 123 170 } 171 `, 172 }, 173 entryPaths: []string{"/Users/user/project/src/entry.js"}, 174 options: config.Options{ 175 Mode: config.ModeBundle, 176 AbsOutputFile: "/Users/user/project/out.js", 177 }, 178 }) 179 } 180 181 func TestPackageJsonBrowserMapRelativeToRelative(t *testing.T) { 182 packagejson_suite.expectBundled(t, bundled{ 183 files: map[string]string{ 184 "/Users/user/project/src/entry.js": ` 185 import fn from 'demo-pkg' 186 console.log(fn()) 187 `, 188 "/Users/user/project/node_modules/demo-pkg/package.json": ` 189 { 190 "main": "./main", 191 "browser": { 192 "./main.js": "./main-browser", 193 "./lib/util.js": "./lib/util-browser" 194 } 195 } 196 `, 197 "/Users/user/project/node_modules/demo-pkg/main.js": ` 198 const util = require('./lib/util') 199 module.exports = function() { 200 return ['main', util] 201 } 202 `, 203 "/Users/user/project/node_modules/demo-pkg/main-browser.js": ` 204 const util = require('./lib/util') 205 module.exports = function() { 206 return ['main-browser', util] 207 } 208 `, 209 "/Users/user/project/node_modules/demo-pkg/lib/util.js": ` 210 module.exports = 'util' 211 `, 212 "/Users/user/project/node_modules/demo-pkg/lib/util-browser.js": ` 213 module.exports = 'util-browser' 214 `, 215 }, 216 entryPaths: []string{"/Users/user/project/src/entry.js"}, 217 options: config.Options{ 218 Mode: config.ModeBundle, 219 AbsOutputFile: "/Users/user/project/out.js", 220 }, 221 }) 222 } 223 224 func TestPackageJsonBrowserMapRelativeToModule(t *testing.T) { 225 packagejson_suite.expectBundled(t, bundled{ 226 files: map[string]string{ 227 "/Users/user/project/src/entry.js": ` 228 import fn from 'demo-pkg' 229 console.log(fn()) 230 `, 231 "/Users/user/project/node_modules/demo-pkg/package.json": ` 232 { 233 "main": "./main", 234 "browser": { 235 "./util.js": "util-browser" 236 } 237 } 238 `, 239 "/Users/user/project/node_modules/demo-pkg/main.js": ` 240 const util = require('./util') 241 module.exports = function() { 242 return ['main', util] 243 } 244 `, 245 "/Users/user/project/node_modules/demo-pkg/util.js": ` 246 module.exports = 'util' 247 `, 248 "/Users/user/project/node_modules/util-browser/index.js": ` 249 module.exports = 'util-browser' 250 `, 251 }, 252 entryPaths: []string{"/Users/user/project/src/entry.js"}, 253 options: config.Options{ 254 Mode: config.ModeBundle, 255 AbsOutputFile: "/Users/user/project/out.js", 256 }, 257 }) 258 } 259 260 func TestPackageJsonBrowserMapRelativeDisabled(t *testing.T) { 261 packagejson_suite.expectBundled(t, bundled{ 262 files: map[string]string{ 263 "/Users/user/project/src/entry.js": ` 264 import fn from 'demo-pkg' 265 console.log(fn()) 266 `, 267 "/Users/user/project/node_modules/demo-pkg/package.json": ` 268 { 269 "main": "./main", 270 "browser": { 271 "./util-node.js": false 272 } 273 } 274 `, 275 "/Users/user/project/node_modules/demo-pkg/main.js": ` 276 const util = require('./util-node') 277 module.exports = function(obj) { 278 return util.inspect(obj) 279 } 280 `, 281 "/Users/user/project/node_modules/demo-pkg/util-node.js": ` 282 module.exports = require('util') 283 `, 284 }, 285 entryPaths: []string{"/Users/user/project/src/entry.js"}, 286 options: config.Options{ 287 Mode: config.ModeBundle, 288 AbsOutputFile: "/Users/user/project/out.js", 289 }, 290 }) 291 } 292 293 func TestPackageJsonBrowserMapModuleToRelative(t *testing.T) { 294 packagejson_suite.expectBundled(t, bundled{ 295 files: map[string]string{ 296 "/Users/user/project/src/entry.js": ` 297 import fn from 'demo-pkg' 298 console.log(fn()) 299 `, 300 "/Users/user/project/node_modules/demo-pkg/package.json": ` 301 { 302 "browser": { 303 "node-pkg": "./node-pkg-browser" 304 } 305 } 306 `, 307 "/Users/user/project/node_modules/demo-pkg/node-pkg-browser.js": ` 308 module.exports = function() { 309 return 123 310 } 311 `, 312 "/Users/user/project/node_modules/demo-pkg/index.js": ` 313 const fn = require('node-pkg') 314 module.exports = function() { 315 return fn() 316 } 317 `, 318 "/Users/user/project/node_modules/node-pkg/index.js": ` 319 module.exports = function() { 320 return 234 321 } 322 `, 323 }, 324 entryPaths: []string{"/Users/user/project/src/entry.js"}, 325 options: config.Options{ 326 Mode: config.ModeBundle, 327 AbsOutputFile: "/Users/user/project/out.js", 328 }, 329 }) 330 } 331 332 func TestPackageJsonBrowserMapModuleToModule(t *testing.T) { 333 packagejson_suite.expectBundled(t, bundled{ 334 files: map[string]string{ 335 "/Users/user/project/src/entry.js": ` 336 import fn from 'demo-pkg' 337 console.log(fn()) 338 `, 339 "/Users/user/project/node_modules/demo-pkg/package.json": ` 340 { 341 "browser": { 342 "node-pkg": "node-pkg-browser" 343 } 344 } 345 `, 346 "/Users/user/project/node_modules/node-pkg-browser/index.js": ` 347 module.exports = function() { 348 return 123 349 } 350 `, 351 "/Users/user/project/node_modules/demo-pkg/index.js": ` 352 const fn = require('node-pkg') 353 module.exports = function() { 354 return fn() 355 } 356 `, 357 "/Users/user/project/node_modules/node-pkg/index.js": ` 358 module.exports = function() { 359 return 234 360 } 361 `, 362 }, 363 entryPaths: []string{"/Users/user/project/src/entry.js"}, 364 options: config.Options{ 365 Mode: config.ModeBundle, 366 AbsOutputFile: "/Users/user/project/out.js", 367 }, 368 }) 369 } 370 371 func TestPackageJsonBrowserMapModuleDisabled(t *testing.T) { 372 packagejson_suite.expectBundled(t, bundled{ 373 files: map[string]string{ 374 "/Users/user/project/src/entry.js": ` 375 import fn from 'demo-pkg' 376 console.log(fn()) 377 `, 378 "/Users/user/project/node_modules/demo-pkg/package.json": ` 379 { 380 "browser": { 381 "node-pkg": false 382 } 383 } 384 `, 385 "/Users/user/project/node_modules/demo-pkg/index.js": ` 386 const fn = require('node-pkg') 387 module.exports = function() { 388 return fn() 389 } 390 `, 391 "/Users/user/project/node_modules/node-pkg/index.js": ` 392 module.exports = function() { 393 return 234 394 } 395 `, 396 }, 397 entryPaths: []string{"/Users/user/project/src/entry.js"}, 398 options: config.Options{ 399 Mode: config.ModeBundle, 400 AbsOutputFile: "/Users/user/project/out.js", 401 }, 402 }) 403 } 404 405 func TestPackageJsonBrowserMapNativeModuleDisabled(t *testing.T) { 406 packagejson_suite.expectBundled(t, bundled{ 407 files: map[string]string{ 408 "/Users/user/project/src/entry.js": ` 409 import fn from 'demo-pkg' 410 console.log(fn()) 411 `, 412 "/Users/user/project/node_modules/demo-pkg/package.json": ` 413 { 414 "browser": { 415 "fs": false 416 } 417 } 418 `, 419 "/Users/user/project/node_modules/demo-pkg/index.js": ` 420 const fs = require('fs') 421 module.exports = function() { 422 return fs.readFile() 423 } 424 `, 425 }, 426 entryPaths: []string{"/Users/user/project/src/entry.js"}, 427 options: config.Options{ 428 Mode: config.ModeBundle, 429 AbsOutputFile: "/Users/user/project/out.js", 430 }, 431 }) 432 } 433 434 func TestPackageJsonBrowserMapAvoidMissing(t *testing.T) { 435 packagejson_suite.expectBundled(t, bundled{ 436 files: map[string]string{ 437 "/Users/user/project/src/entry.js": ` 438 import 'component-classes' 439 `, 440 "/Users/user/project/node_modules/component-classes/package.json": ` 441 { 442 "browser": { 443 "indexof": "component-indexof" 444 } 445 } 446 `, 447 "/Users/user/project/node_modules/component-classes/index.js": ` 448 try { 449 var index = require('indexof'); 450 } catch (err) { 451 var index = require('component-indexof'); 452 } 453 `, 454 "/Users/user/project/node_modules/component-indexof/index.js": ` 455 module.exports = function() { 456 return 234 457 } 458 `, 459 }, 460 entryPaths: []string{"/Users/user/project/src/entry.js"}, 461 options: config.Options{ 462 Mode: config.ModeBundle, 463 AbsOutputFile: "/Users/user/project/out.js", 464 }, 465 }) 466 } 467 468 func TestPackageJsonBrowserOverModuleBrowser(t *testing.T) { 469 packagejson_suite.expectBundled(t, bundled{ 470 files: map[string]string{ 471 "/Users/user/project/src/entry.js": ` 472 import fn from 'demo-pkg' 473 console.log(fn()) 474 `, 475 "/Users/user/project/node_modules/demo-pkg/package.json": ` 476 { 477 "main": "./main.js", 478 "module": "./main.esm.js", 479 "browser": "./main.browser.js" 480 } 481 `, 482 "/Users/user/project/node_modules/demo-pkg/main.js": ` 483 module.exports = function() { 484 return 123 485 } 486 `, 487 "/Users/user/project/node_modules/demo-pkg/main.esm.js": ` 488 export default function() { 489 return 123 490 } 491 `, 492 "/Users/user/project/node_modules/demo-pkg/main.browser.js": ` 493 module.exports = function() { 494 return 123 495 } 496 `, 497 }, 498 entryPaths: []string{"/Users/user/project/src/entry.js"}, 499 options: config.Options{ 500 Mode: config.ModeBundle, 501 Platform: config.PlatformBrowser, 502 AbsOutputFile: "/Users/user/project/out.js", 503 }, 504 }) 505 } 506 507 func TestPackageJsonBrowserOverMainNode(t *testing.T) { 508 packagejson_suite.expectBundled(t, bundled{ 509 files: map[string]string{ 510 "/Users/user/project/src/entry.js": ` 511 import fn from 'demo-pkg' 512 console.log(fn()) 513 `, 514 "/Users/user/project/node_modules/demo-pkg/package.json": ` 515 { 516 "main": "./main.js", 517 "module": "./main.esm.js", 518 "browser": "./main.browser.js" 519 } 520 `, 521 "/Users/user/project/node_modules/demo-pkg/main.js": ` 522 module.exports = function() { 523 return 123 524 } 525 `, 526 "/Users/user/project/node_modules/demo-pkg/main.esm.js": ` 527 export default function() { 528 return 123 529 } 530 `, 531 "/Users/user/project/node_modules/demo-pkg/main.browser.js": ` 532 module.exports = function() { 533 return 123 534 } 535 `, 536 }, 537 entryPaths: []string{"/Users/user/project/src/entry.js"}, 538 options: config.Options{ 539 Mode: config.ModeBundle, 540 Platform: config.PlatformNode, 541 AbsOutputFile: "/Users/user/project/out.js", 542 }, 543 }) 544 } 545 546 func TestPackageJsonBrowserWithModuleBrowser(t *testing.T) { 547 packagejson_suite.expectBundled(t, bundled{ 548 files: map[string]string{ 549 "/Users/user/project/src/entry.js": ` 550 import fn from 'demo-pkg' 551 console.log(fn()) 552 `, 553 "/Users/user/project/node_modules/demo-pkg/package.json": ` 554 { 555 "main": "./main.js", 556 "module": "./main.esm.js", 557 "browser": { 558 "./main.js": "./main.browser.js", 559 "./main.esm.js": "./main.browser.esm.js" 560 } 561 } 562 `, 563 "/Users/user/project/node_modules/demo-pkg/main.js": ` 564 module.exports = function() { 565 return 123 566 } 567 `, 568 "/Users/user/project/node_modules/demo-pkg/main.esm.js": ` 569 export default function() { 570 return 123 571 } 572 `, 573 "/Users/user/project/node_modules/demo-pkg/main.browser.js": ` 574 module.exports = function() { 575 return 123 576 } 577 `, 578 "/Users/user/project/node_modules/demo-pkg/main.browser.esm.js": ` 579 export default function() { 580 return 123 581 } 582 `, 583 }, 584 entryPaths: []string{"/Users/user/project/src/entry.js"}, 585 options: config.Options{ 586 Mode: config.ModeBundle, 587 Platform: config.PlatformBrowser, 588 AbsOutputFile: "/Users/user/project/out.js", 589 }, 590 }) 591 } 592 593 func TestPackageJsonBrowserWithMainNode(t *testing.T) { 594 packagejson_suite.expectBundled(t, bundled{ 595 files: map[string]string{ 596 "/Users/user/project/src/entry.js": ` 597 import fn from 'demo-pkg' 598 console.log(fn()) 599 `, 600 "/Users/user/project/node_modules/demo-pkg/package.json": ` 601 { 602 "main": "./main.js", 603 "module": "./main.esm.js", 604 "browser": { 605 "./main.js": "./main.browser.js", 606 "./main.esm.js": "./main.browser.esm.js" 607 } 608 } 609 `, 610 "/Users/user/project/node_modules/demo-pkg/main.js": ` 611 module.exports = function() { 612 return 123 613 } 614 `, 615 "/Users/user/project/node_modules/demo-pkg/main.esm.js": ` 616 export default function() { 617 return 123 618 } 619 `, 620 "/Users/user/project/node_modules/demo-pkg/main.browser.js": ` 621 module.exports = function() { 622 return 123 623 } 624 `, 625 "/Users/user/project/node_modules/demo-pkg/main.browser.esm.js": ` 626 export default function() { 627 return 123 628 } 629 `, 630 }, 631 entryPaths: []string{"/Users/user/project/src/entry.js"}, 632 options: config.Options{ 633 Mode: config.ModeBundle, 634 Platform: config.PlatformNode, 635 AbsOutputFile: "/Users/user/project/out.js", 636 }, 637 }) 638 } 639 640 func TestPackageJsonBrowserNodeModulesNoExt(t *testing.T) { 641 packagejson_suite.expectBundled(t, bundled{ 642 files: map[string]string{ 643 "/Users/user/project/src/entry.js": ` 644 import {browser as a} from 'demo-pkg/no-ext' 645 import {node as b} from 'demo-pkg/no-ext.js' 646 import {browser as c} from 'demo-pkg/ext' 647 import {browser as d} from 'demo-pkg/ext.js' 648 console.log(a) 649 console.log(b) 650 console.log(c) 651 console.log(d) 652 `, 653 "/Users/user/project/node_modules/demo-pkg/package.json": ` 654 { 655 "browser": { 656 "./no-ext": "./no-ext-browser.js", 657 "./ext.js": "./ext-browser.js" 658 } 659 } 660 `, 661 "/Users/user/project/node_modules/demo-pkg/no-ext.js": ` 662 export let node = 'node' 663 `, 664 "/Users/user/project/node_modules/demo-pkg/no-ext-browser.js": ` 665 export let browser = 'browser' 666 `, 667 "/Users/user/project/node_modules/demo-pkg/ext.js": ` 668 export let node = 'node' 669 `, 670 "/Users/user/project/node_modules/demo-pkg/ext-browser.js": ` 671 export let browser = 'browser' 672 `, 673 }, 674 entryPaths: []string{"/Users/user/project/src/entry.js"}, 675 options: config.Options{ 676 Mode: config.ModeBundle, 677 AbsOutputFile: "/Users/user/project/out.js", 678 }, 679 }) 680 } 681 682 func TestPackageJsonBrowserNodeModulesIndexNoExt(t *testing.T) { 683 packagejson_suite.expectBundled(t, bundled{ 684 files: map[string]string{ 685 "/Users/user/project/src/entry.js": ` 686 import {browser as a} from 'demo-pkg/no-ext' 687 import {node as b} from 'demo-pkg/no-ext/index.js' 688 import {browser as c} from 'demo-pkg/ext' 689 import {browser as d} from 'demo-pkg/ext/index.js' 690 console.log(a) 691 console.log(b) 692 console.log(c) 693 console.log(d) 694 `, 695 "/Users/user/project/node_modules/demo-pkg/package.json": ` 696 { 697 "browser": { 698 "./no-ext": "./no-ext-browser/index.js", 699 "./ext/index.js": "./ext-browser/index.js" 700 } 701 } 702 `, 703 "/Users/user/project/node_modules/demo-pkg/no-ext/index.js": ` 704 export let node = 'node' 705 `, 706 "/Users/user/project/node_modules/demo-pkg/no-ext-browser/index.js": ` 707 export let browser = 'browser' 708 `, 709 "/Users/user/project/node_modules/demo-pkg/ext/index.js": ` 710 export let node = 'node' 711 `, 712 "/Users/user/project/node_modules/demo-pkg/ext-browser/index.js": ` 713 export let browser = 'browser' 714 `, 715 }, 716 entryPaths: []string{"/Users/user/project/src/entry.js"}, 717 options: config.Options{ 718 Mode: config.ModeBundle, 719 AbsOutputFile: "/Users/user/project/out.js", 720 }, 721 }) 722 } 723 724 func TestPackageJsonBrowserNoExt(t *testing.T) { 725 packagejson_suite.expectBundled(t, bundled{ 726 files: map[string]string{ 727 "/Users/user/project/src/entry.js": ` 728 import {browser as a} from './demo-pkg/no-ext' 729 import {node as b} from './demo-pkg/no-ext.js' 730 import {browser as c} from './demo-pkg/ext' 731 import {browser as d} from './demo-pkg/ext.js' 732 console.log(a) 733 console.log(b) 734 console.log(c) 735 console.log(d) 736 `, 737 "/Users/user/project/src/demo-pkg/package.json": ` 738 { 739 "browser": { 740 "./no-ext": "./no-ext-browser.js", 741 "./ext.js": "./ext-browser.js" 742 } 743 } 744 `, 745 "/Users/user/project/src/demo-pkg/no-ext.js": ` 746 export let node = 'node' 747 `, 748 "/Users/user/project/src/demo-pkg/no-ext-browser.js": ` 749 export let browser = 'browser' 750 `, 751 "/Users/user/project/src/demo-pkg/ext.js": ` 752 export let node = 'node' 753 `, 754 "/Users/user/project/src/demo-pkg/ext-browser.js": ` 755 export let browser = 'browser' 756 `, 757 }, 758 entryPaths: []string{"/Users/user/project/src/entry.js"}, 759 options: config.Options{ 760 Mode: config.ModeBundle, 761 AbsOutputFile: "/Users/user/project/out.js", 762 }, 763 }) 764 } 765 766 func TestPackageJsonBrowserIndexNoExt(t *testing.T) { 767 packagejson_suite.expectBundled(t, bundled{ 768 files: map[string]string{ 769 "/Users/user/project/src/entry.js": ` 770 import {browser as a} from './demo-pkg/no-ext' 771 import {node as b} from './demo-pkg/no-ext/index.js' 772 import {browser as c} from './demo-pkg/ext' 773 import {browser as d} from './demo-pkg/ext/index.js' 774 console.log(a) 775 console.log(b) 776 console.log(c) 777 console.log(d) 778 `, 779 "/Users/user/project/src/demo-pkg/package.json": ` 780 { 781 "browser": { 782 "./no-ext": "./no-ext-browser/index.js", 783 "./ext/index.js": "./ext-browser/index.js" 784 } 785 } 786 `, 787 "/Users/user/project/src/demo-pkg/no-ext/index.js": ` 788 export let node = 'node' 789 `, 790 "/Users/user/project/src/demo-pkg/no-ext-browser/index.js": ` 791 export let browser = 'browser' 792 `, 793 "/Users/user/project/src/demo-pkg/ext/index.js": ` 794 export let node = 'node' 795 `, 796 "/Users/user/project/src/demo-pkg/ext-browser/index.js": ` 797 export let browser = 'browser' 798 `, 799 }, 800 entryPaths: []string{"/Users/user/project/src/entry.js"}, 801 options: config.Options{ 802 Mode: config.ModeBundle, 803 AbsOutputFile: "/Users/user/project/out.js", 804 }, 805 }) 806 } 807 808 // See https://github.com/evanw/esbuild/issues/2002 809 func TestPackageJsonBrowserIssue2002A(t *testing.T) { 810 packagejson_suite.expectBundled(t, bundled{ 811 files: map[string]string{ 812 "/Users/user/project/src/entry.js": `require('pkg/sub')`, 813 "/Users/user/project/src/node_modules/pkg/package.json": `{ 814 "browser": { 815 "./sub": "./sub/foo.js" 816 } 817 }`, 818 "/Users/user/project/src/node_modules/pkg/sub/foo.js": `require('sub')`, 819 "/Users/user/project/src/node_modules/sub/package.json": `{ "main": "./bar" }`, 820 "/Users/user/project/src/node_modules/sub/bar.js": `works()`, 821 }, 822 entryPaths: []string{"/Users/user/project/src/entry.js"}, 823 options: config.Options{ 824 Mode: config.ModeBundle, 825 AbsOutputFile: "/Users/user/project/out.js", 826 }, 827 }) 828 } 829 830 func TestPackageJsonBrowserIssue2002B(t *testing.T) { 831 packagejson_suite.expectBundled(t, bundled{ 832 files: map[string]string{ 833 "/Users/user/project/src/entry.js": `require('pkg/sub')`, 834 "/Users/user/project/src/node_modules/pkg/package.json": `{ 835 "browser": { 836 "./sub": "./sub/foo.js", 837 "./sub/sub": "./sub/bar.js" 838 } 839 }`, 840 "/Users/user/project/src/node_modules/pkg/sub/foo.js": `require('sub')`, 841 "/Users/user/project/src/node_modules/pkg/sub/bar.js": `works()`, 842 }, 843 entryPaths: []string{"/Users/user/project/src/entry.js"}, 844 options: config.Options{ 845 Mode: config.ModeBundle, 846 AbsOutputFile: "/Users/user/project/out.js", 847 }, 848 }) 849 } 850 851 // See https://github.com/evanw/esbuild/issues/2239 852 func TestPackageJsonBrowserIssue2002C(t *testing.T) { 853 packagejson_suite.expectBundled(t, bundled{ 854 files: map[string]string{ 855 "/Users/user/project/src/entry.js": `require('pkg/sub')`, 856 "/Users/user/project/src/node_modules/pkg/package.json": `{ 857 "browser": { 858 "./sub": "./sub/foo.js", 859 "./sub/sub.js": "./sub/bar.js" 860 } 861 }`, 862 "/Users/user/project/src/node_modules/pkg/sub/foo.js": `require('sub')`, 863 "/Users/user/project/src/node_modules/sub/index.js": `works()`, 864 }, 865 entryPaths: []string{"/Users/user/project/src/entry.js"}, 866 options: config.Options{ 867 Mode: config.ModeBundle, 868 AbsOutputFile: "/Users/user/project/out.js", 869 }, 870 }) 871 } 872 873 func TestPackageJsonDualPackageHazardImportOnly(t *testing.T) { 874 packagejson_suite.expectBundled(t, bundled{ 875 files: map[string]string{ 876 "/Users/user/project/src/entry.js": ` 877 import value from 'demo-pkg' 878 console.log(value) 879 `, 880 "/Users/user/project/node_modules/demo-pkg/package.json": ` 881 { 882 "main": "./main.js", 883 "module": "./module.js" 884 } 885 `, 886 "/Users/user/project/node_modules/demo-pkg/main.js": ` 887 module.exports = 'main' 888 `, 889 "/Users/user/project/node_modules/demo-pkg/module.js": ` 890 export default 'module' 891 `, 892 }, 893 entryPaths: []string{"/Users/user/project/src/entry.js"}, 894 options: config.Options{ 895 Mode: config.ModeBundle, 896 AbsOutputFile: "/Users/user/project/out.js", 897 }, 898 }) 899 } 900 901 func TestPackageJsonDualPackageHazardRequireOnly(t *testing.T) { 902 packagejson_suite.expectBundled(t, bundled{ 903 files: map[string]string{ 904 "/Users/user/project/src/entry.js": ` 905 console.log(require('demo-pkg')) 906 `, 907 "/Users/user/project/node_modules/demo-pkg/package.json": ` 908 { 909 "main": "./main.js", 910 "module": "./module.js" 911 } 912 `, 913 "/Users/user/project/node_modules/demo-pkg/main.js": ` 914 module.exports = 'main' 915 `, 916 "/Users/user/project/node_modules/demo-pkg/module.js": ` 917 export default 'module' 918 `, 919 }, 920 entryPaths: []string{"/Users/user/project/src/entry.js"}, 921 options: config.Options{ 922 Mode: config.ModeBundle, 923 AbsOutputFile: "/Users/user/project/out.js", 924 }, 925 }) 926 } 927 928 func TestPackageJsonDualPackageHazardImportAndRequireSameFile(t *testing.T) { 929 packagejson_suite.expectBundled(t, bundled{ 930 files: map[string]string{ 931 "/Users/user/project/src/entry.js": ` 932 import value from 'demo-pkg' 933 console.log(value, require('demo-pkg')) 934 `, 935 "/Users/user/project/node_modules/demo-pkg/package.json": ` 936 { 937 "main": "./main.js", 938 "module": "./module.js" 939 } 940 `, 941 "/Users/user/project/node_modules/demo-pkg/main.js": ` 942 module.exports = 'main' 943 `, 944 "/Users/user/project/node_modules/demo-pkg/module.js": ` 945 export default 'module' 946 `, 947 }, 948 entryPaths: []string{"/Users/user/project/src/entry.js"}, 949 options: config.Options{ 950 Mode: config.ModeBundle, 951 AbsOutputFile: "/Users/user/project/out.js", 952 }, 953 }) 954 } 955 956 func TestPackageJsonDualPackageHazardImportAndRequireSeparateFiles(t *testing.T) { 957 packagejson_suite.expectBundled(t, bundled{ 958 files: map[string]string{ 959 "/Users/user/project/src/entry.js": ` 960 import './test-main' 961 import './test-module' 962 `, 963 "/Users/user/project/src/test-main.js": ` 964 console.log(require('demo-pkg')) 965 `, 966 "/Users/user/project/src/test-module.js": ` 967 import value from 'demo-pkg' 968 console.log(value) 969 `, 970 "/Users/user/project/node_modules/demo-pkg/package.json": ` 971 { 972 "main": "./main.js", 973 "module": "./module.js" 974 } 975 `, 976 "/Users/user/project/node_modules/demo-pkg/main.js": ` 977 module.exports = 'main' 978 `, 979 "/Users/user/project/node_modules/demo-pkg/module.js": ` 980 export default 'module' 981 `, 982 }, 983 entryPaths: []string{"/Users/user/project/src/entry.js"}, 984 options: config.Options{ 985 Mode: config.ModeBundle, 986 AbsOutputFile: "/Users/user/project/out.js", 987 }, 988 }) 989 } 990 991 func TestPackageJsonDualPackageHazardImportAndRequireForceModuleBeforeMain(t *testing.T) { 992 packagejson_suite.expectBundled(t, bundled{ 993 files: map[string]string{ 994 "/Users/user/project/src/entry.js": ` 995 import './test-main' 996 import './test-module' 997 `, 998 "/Users/user/project/src/test-main.js": ` 999 console.log(require('demo-pkg')) 1000 `, 1001 "/Users/user/project/src/test-module.js": ` 1002 import value from 'demo-pkg' 1003 console.log(value) 1004 `, 1005 "/Users/user/project/node_modules/demo-pkg/package.json": ` 1006 { 1007 "main": "./main.js", 1008 "module": "./module.js" 1009 } 1010 `, 1011 "/Users/user/project/node_modules/demo-pkg/main.js": ` 1012 module.exports = 'main' 1013 `, 1014 "/Users/user/project/node_modules/demo-pkg/module.js": ` 1015 export default 'module' 1016 `, 1017 }, 1018 entryPaths: []string{"/Users/user/project/src/entry.js"}, 1019 options: config.Options{ 1020 Mode: config.ModeBundle, 1021 MainFields: []string{"module", "main"}, 1022 AbsOutputFile: "/Users/user/project/out.js", 1023 }, 1024 }) 1025 } 1026 1027 func TestPackageJsonDualPackageHazardImportAndRequireImplicitMain(t *testing.T) { 1028 packagejson_suite.expectBundled(t, bundled{ 1029 files: map[string]string{ 1030 "/Users/user/project/src/entry.js": ` 1031 import './test-index' 1032 import './test-module' 1033 `, 1034 "/Users/user/project/src/test-index.js": ` 1035 console.log(require('demo-pkg')) 1036 `, 1037 "/Users/user/project/src/test-module.js": ` 1038 import value from 'demo-pkg' 1039 console.log(value) 1040 `, 1041 "/Users/user/project/node_modules/demo-pkg/package.json": ` 1042 { 1043 "module": "./module.js" 1044 } 1045 `, 1046 "/Users/user/project/node_modules/demo-pkg/index.js": ` 1047 module.exports = 'index' 1048 `, 1049 "/Users/user/project/node_modules/demo-pkg/module.js": ` 1050 export default 'module' 1051 `, 1052 }, 1053 entryPaths: []string{"/Users/user/project/src/entry.js"}, 1054 options: config.Options{ 1055 Mode: config.ModeBundle, 1056 AbsOutputFile: "/Users/user/project/out.js", 1057 }, 1058 }) 1059 } 1060 1061 func TestPackageJsonDualPackageHazardImportAndRequireImplicitMainForceModuleBeforeMain(t *testing.T) { 1062 packagejson_suite.expectBundled(t, bundled{ 1063 files: map[string]string{ 1064 "/Users/user/project/src/entry.js": ` 1065 import './test-index' 1066 import './test-module' 1067 `, 1068 "/Users/user/project/src/test-index.js": ` 1069 console.log(require('demo-pkg')) 1070 `, 1071 "/Users/user/project/src/test-module.js": ` 1072 import value from 'demo-pkg' 1073 console.log(value) 1074 `, 1075 "/Users/user/project/node_modules/demo-pkg/package.json": ` 1076 { 1077 "module": "./module.js" 1078 } 1079 `, 1080 "/Users/user/project/node_modules/demo-pkg/index.js": ` 1081 module.exports = 'index' 1082 `, 1083 "/Users/user/project/node_modules/demo-pkg/module.js": ` 1084 export default 'module' 1085 `, 1086 }, 1087 entryPaths: []string{"/Users/user/project/src/entry.js"}, 1088 options: config.Options{ 1089 Mode: config.ModeBundle, 1090 MainFields: []string{"module", "main"}, 1091 AbsOutputFile: "/Users/user/project/out.js", 1092 }, 1093 }) 1094 } 1095 1096 func TestPackageJsonDualPackageHazardImportAndRequireBrowser(t *testing.T) { 1097 packagejson_suite.expectBundled(t, bundled{ 1098 files: map[string]string{ 1099 "/Users/user/project/src/entry.js": ` 1100 import './test-main' 1101 import './test-module' 1102 `, 1103 "/Users/user/project/src/test-main.js": ` 1104 console.log(require('demo-pkg')) 1105 `, 1106 "/Users/user/project/src/test-module.js": ` 1107 import value from 'demo-pkg' 1108 console.log(value) 1109 `, 1110 "/Users/user/project/node_modules/demo-pkg/package.json": ` 1111 { 1112 "main": "./main.js", 1113 "module": "./module.js", 1114 "browser": { 1115 "./main.js": "./main.browser.js", 1116 "./module.js": "./module.browser.js" 1117 } 1118 } 1119 `, 1120 "/Users/user/project/node_modules/demo-pkg/main.js": ` 1121 module.exports = 'main' 1122 `, 1123 "/Users/user/project/node_modules/demo-pkg/module.js": ` 1124 export default 'module' 1125 `, 1126 "/Users/user/project/node_modules/demo-pkg/main.browser.js": ` 1127 module.exports = 'browser main' 1128 `, 1129 "/Users/user/project/node_modules/demo-pkg/module.browser.js": ` 1130 export default 'browser module' 1131 `, 1132 }, 1133 entryPaths: []string{"/Users/user/project/src/entry.js"}, 1134 options: config.Options{ 1135 Mode: config.ModeBundle, 1136 AbsOutputFile: "/Users/user/project/out.js", 1137 }, 1138 }) 1139 } 1140 1141 func TestPackageJsonMainFieldsA(t *testing.T) { 1142 packagejson_suite.expectBundled(t, bundled{ 1143 files: map[string]string{ 1144 "/Users/user/project/src/entry.js": ` 1145 import value from 'demo-pkg' 1146 console.log(value) 1147 `, 1148 "/Users/user/project/node_modules/demo-pkg/package.json": ` 1149 { 1150 "a": "./a.js", 1151 "b": "./b.js" 1152 } 1153 `, 1154 "/Users/user/project/node_modules/demo-pkg/a.js": ` 1155 module.exports = 'a' 1156 `, 1157 "/Users/user/project/node_modules/demo-pkg/b.js": ` 1158 export default 'b' 1159 `, 1160 }, 1161 entryPaths: []string{"/Users/user/project/src/entry.js"}, 1162 options: config.Options{ 1163 Mode: config.ModeBundle, 1164 MainFields: []string{"a", "b"}, 1165 AbsOutputFile: "/Users/user/project/out.js", 1166 }, 1167 }) 1168 } 1169 1170 func TestPackageJsonMainFieldsB(t *testing.T) { 1171 packagejson_suite.expectBundled(t, bundled{ 1172 files: map[string]string{ 1173 "/Users/user/project/src/entry.js": ` 1174 import value from 'demo-pkg' 1175 console.log(value) 1176 `, 1177 "/Users/user/project/node_modules/demo-pkg/package.json": ` 1178 { 1179 "a": "./a.js", 1180 "b": "./b.js" 1181 } 1182 `, 1183 "/Users/user/project/node_modules/demo-pkg/a.js": ` 1184 module.exports = 'a' 1185 `, 1186 "/Users/user/project/node_modules/demo-pkg/b.js": ` 1187 export default 'b' 1188 `, 1189 }, 1190 entryPaths: []string{"/Users/user/project/src/entry.js"}, 1191 options: config.Options{ 1192 Mode: config.ModeBundle, 1193 MainFields: []string{"b", "a"}, 1194 AbsOutputFile: "/Users/user/project/out.js", 1195 }, 1196 }) 1197 } 1198 1199 func TestPackageJsonNeutralNoDefaultMainFields(t *testing.T) { 1200 packagejson_suite.expectBundled(t, bundled{ 1201 files: map[string]string{ 1202 "/Users/user/project/src/entry.js": ` 1203 import fn from 'demo-pkg' 1204 console.log(fn()) 1205 `, 1206 "/Users/user/project/node_modules/demo-pkg/package.json": ` 1207 { 1208 "main": "./main.js", 1209 "module": "./main.esm.js" 1210 } 1211 `, 1212 "/Users/user/project/node_modules/demo-pkg/main.js": ` 1213 module.exports = function() { 1214 return 123 1215 } 1216 `, 1217 "/Users/user/project/node_modules/demo-pkg/main.esm.js": ` 1218 export default function() { 1219 return 123 1220 } 1221 `, 1222 }, 1223 entryPaths: []string{"/Users/user/project/src/entry.js"}, 1224 options: config.Options{ 1225 Mode: config.ModeBundle, 1226 Platform: config.PlatformNeutral, 1227 AbsOutputFile: "/Users/user/project/out.js", 1228 }, 1229 expectedScanLog: `Users/user/project/src/entry.js: ERROR: Could not resolve "demo-pkg" 1230 Users/user/project/node_modules/demo-pkg/package.json: NOTE: The "main" field here was ignored. Main fields must be configured explicitly when using the "neutral" platform. 1231 NOTE: You can mark the path "demo-pkg" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle. 1232 `, 1233 }) 1234 } 1235 1236 func TestPackageJsonNeutralExplicitMainFields(t *testing.T) { 1237 packagejson_suite.expectBundled(t, bundled{ 1238 files: map[string]string{ 1239 "/Users/user/project/src/entry.js": ` 1240 import fn from 'demo-pkg' 1241 console.log(fn()) 1242 `, 1243 "/Users/user/project/node_modules/demo-pkg/package.json": ` 1244 { 1245 "hello": "./main.js", 1246 "module": "./main.esm.js" 1247 } 1248 `, 1249 "/Users/user/project/node_modules/demo-pkg/main.js": ` 1250 module.exports = function() { 1251 return 123 1252 } 1253 `, 1254 }, 1255 entryPaths: []string{"/Users/user/project/src/entry.js"}, 1256 options: config.Options{ 1257 Mode: config.ModeBundle, 1258 Platform: config.PlatformNeutral, 1259 MainFields: []string{"hello"}, 1260 AbsOutputFile: "/Users/user/project/out.js", 1261 }, 1262 }) 1263 } 1264 1265 func TestPackageJsonExportsErrorInvalidModuleSpecifier(t *testing.T) { 1266 packagejson_suite.expectBundled(t, bundled{ 1267 files: map[string]string{ 1268 "/Users/user/project/src/entry.js": ` 1269 import 'pkg1' 1270 import 'pkg2' 1271 import 'pkg3' 1272 import 'pkg4' 1273 import 'pkg5' 1274 import 'pkg6' 1275 `, 1276 "/Users/user/project/node_modules/pkg1/package.json": ` 1277 { "exports": { ".": "./%%" } } 1278 `, 1279 "/Users/user/project/node_modules/pkg2/package.json": ` 1280 { "exports": { ".": "./%2f" } } 1281 `, 1282 "/Users/user/project/node_modules/pkg3/package.json": ` 1283 { "exports": { ".": "./%2F" } } 1284 `, 1285 "/Users/user/project/node_modules/pkg4/package.json": ` 1286 { "exports": { ".": "./%5c" } } 1287 `, 1288 "/Users/user/project/node_modules/pkg5/package.json": ` 1289 { "exports": { ".": "./%5C" } } 1290 `, 1291 "/Users/user/project/node_modules/pkg6/package.json": ` 1292 { "exports": { ".": "./%31.js" } } 1293 `, 1294 "/Users/user/project/node_modules/pkg6/1.js": ` 1295 console.log(1) 1296 `, 1297 }, 1298 entryPaths: []string{"/Users/user/project/src/entry.js"}, 1299 options: config.Options{ 1300 Mode: config.ModeBundle, 1301 AbsOutputFile: "/Users/user/project/out.js", 1302 }, 1303 expectedScanLog: `Users/user/project/src/entry.js: ERROR: Could not resolve "pkg1" 1304 Users/user/project/node_modules/pkg1/package.json: NOTE: The module specifier "./%%" is invalid: 1305 NOTE: You can mark the path "pkg1" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle. 1306 Users/user/project/src/entry.js: ERROR: Could not resolve "pkg2" 1307 Users/user/project/node_modules/pkg2/package.json: NOTE: The module specifier "./%2f" is invalid: 1308 NOTE: You can mark the path "pkg2" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle. 1309 Users/user/project/src/entry.js: ERROR: Could not resolve "pkg3" 1310 Users/user/project/node_modules/pkg3/package.json: NOTE: The module specifier "./%2F" is invalid: 1311 NOTE: You can mark the path "pkg3" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle. 1312 Users/user/project/src/entry.js: ERROR: Could not resolve "pkg4" 1313 Users/user/project/node_modules/pkg4/package.json: NOTE: The module specifier "./%5c" is invalid: 1314 NOTE: You can mark the path "pkg4" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle. 1315 Users/user/project/src/entry.js: ERROR: Could not resolve "pkg5" 1316 Users/user/project/node_modules/pkg5/package.json: NOTE: The module specifier "./%5C" is invalid: 1317 NOTE: You can mark the path "pkg5" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle. 1318 `, 1319 }) 1320 } 1321 1322 func TestPackageJsonExportsErrorInvalidPackageConfiguration(t *testing.T) { 1323 packagejson_suite.expectBundled(t, bundled{ 1324 files: map[string]string{ 1325 "/Users/user/project/src/entry.js": ` 1326 import 'pkg1' 1327 import 'pkg2/foo' 1328 `, 1329 "/Users/user/project/node_modules/pkg1/package.json": ` 1330 { "exports": { ".": false } } 1331 `, 1332 "/Users/user/project/node_modules/pkg2/package.json": ` 1333 { "exports": { "./foo": false } } 1334 `, 1335 }, 1336 entryPaths: []string{"/Users/user/project/src/entry.js"}, 1337 options: config.Options{ 1338 Mode: config.ModeBundle, 1339 AbsOutputFile: "/Users/user/project/out.js", 1340 }, 1341 expectedScanLog: `Users/user/project/node_modules/pkg1/package.json: WARNING: This value must be a string, an object, an array, or null 1342 Users/user/project/node_modules/pkg2/package.json: WARNING: This value must be a string, an object, an array, or null 1343 Users/user/project/src/entry.js: ERROR: Could not resolve "pkg1" 1344 Users/user/project/node_modules/pkg1/package.json: NOTE: The package configuration has an invalid value here: 1345 NOTE: You can mark the path "pkg1" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle. 1346 Users/user/project/src/entry.js: ERROR: Could not resolve "pkg2/foo" 1347 Users/user/project/node_modules/pkg2/package.json: NOTE: The package configuration has an invalid value here: 1348 NOTE: You can mark the path "pkg2/foo" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle. 1349 `, 1350 }) 1351 } 1352 1353 func TestPackageJsonExportsErrorInvalidPackageTarget(t *testing.T) { 1354 packagejson_suite.expectBundled(t, bundled{ 1355 files: map[string]string{ 1356 "/Users/user/project/src/entry.js": ` 1357 import 'pkg1' 1358 import 'pkg2' 1359 import 'pkg3' 1360 `, 1361 "/Users/user/project/node_modules/pkg1/package.json": ` 1362 { "exports": { ".": "invalid" } } 1363 `, 1364 "/Users/user/project/node_modules/pkg2/package.json": ` 1365 { "exports": { ".": "./../pkg3" } } 1366 `, 1367 "/Users/user/project/node_modules/pkg3/package.json": ` 1368 { "exports": { ".": "./node_modules/pkg" } } 1369 `, 1370 }, 1371 entryPaths: []string{"/Users/user/project/src/entry.js"}, 1372 options: config.Options{ 1373 Mode: config.ModeBundle, 1374 AbsOutputFile: "/Users/user/project/out.js", 1375 }, 1376 expectedScanLog: `Users/user/project/src/entry.js: ERROR: Could not resolve "pkg1" 1377 Users/user/project/node_modules/pkg1/package.json: NOTE: The package target "invalid" is invalid because it doesn't start with "./": 1378 NOTE: You can mark the path "pkg1" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle. 1379 Users/user/project/src/entry.js: ERROR: Could not resolve "pkg2" 1380 Users/user/project/node_modules/pkg2/package.json: NOTE: The package target "./../pkg3" is invalid because it contains invalid segment "..": 1381 NOTE: You can mark the path "pkg2" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle. 1382 Users/user/project/src/entry.js: ERROR: Could not resolve "pkg3" 1383 Users/user/project/node_modules/pkg3/package.json: NOTE: The package target "./node_modules/pkg" is invalid because it contains invalid segment "node_modules": 1384 NOTE: You can mark the path "pkg3" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle. 1385 `, 1386 }) 1387 } 1388 1389 func TestPackageJsonExportsErrorPackagePathNotExported(t *testing.T) { 1390 packagejson_suite.expectBundled(t, bundled{ 1391 files: map[string]string{ 1392 "/Users/user/project/src/entry.js": ` 1393 import 'pkg1/foo' 1394 `, 1395 "/Users/user/project/node_modules/pkg1/package.json": ` 1396 { "exports": { ".": {} } } 1397 `, 1398 }, 1399 entryPaths: []string{"/Users/user/project/src/entry.js"}, 1400 options: config.Options{ 1401 Mode: config.ModeBundle, 1402 AbsOutputFile: "/Users/user/project/out.js", 1403 }, 1404 expectedScanLog: `Users/user/project/src/entry.js: ERROR: Could not resolve "pkg1/foo" 1405 Users/user/project/node_modules/pkg1/package.json: NOTE: The path "./foo" is not exported by package "pkg1": 1406 NOTE: You can mark the path "pkg1/foo" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle. 1407 `, 1408 }) 1409 } 1410 1411 func TestPackageJsonExportsErrorModuleNotFound(t *testing.T) { 1412 packagejson_suite.expectBundled(t, bundled{ 1413 files: map[string]string{ 1414 "/Users/user/project/src/entry.js": ` 1415 import 'pkg1' 1416 `, 1417 "/Users/user/project/node_modules/pkg1/package.json": ` 1418 { "exports": { ".": "./foo.js" } } 1419 `, 1420 }, 1421 entryPaths: []string{"/Users/user/project/src/entry.js"}, 1422 options: config.Options{ 1423 Mode: config.ModeBundle, 1424 AbsOutputFile: "/Users/user/project/out.js", 1425 }, 1426 expectedScanLog: `Users/user/project/src/entry.js: ERROR: Could not resolve "pkg1" 1427 Users/user/project/node_modules/pkg1/package.json: NOTE: The module "./foo.js" was not found on the file system: 1428 NOTE: You can mark the path "pkg1" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle. 1429 `, 1430 }) 1431 } 1432 1433 func TestPackageJsonExportsErrorUnsupportedDirectoryImport(t *testing.T) { 1434 packagejson_suite.expectBundled(t, bundled{ 1435 files: map[string]string{ 1436 "/Users/user/project/src/entry.js": ` 1437 import 'pkg1' 1438 import 'pkg2' 1439 `, 1440 "/Users/user/project/node_modules/pkg1/package.json": ` 1441 { "exports": { ".": "./foo/" } } 1442 `, 1443 "/Users/user/project/node_modules/pkg2/package.json": ` 1444 { "exports": { ".": "./foo" } } 1445 `, 1446 "/Users/user/project/node_modules/pkg2/foo/bar.js": ` 1447 console.log(bar) 1448 `, 1449 }, 1450 entryPaths: []string{"/Users/user/project/src/entry.js"}, 1451 options: config.Options{ 1452 Mode: config.ModeBundle, 1453 AbsOutputFile: "/Users/user/project/out.js", 1454 }, 1455 expectedScanLog: `Users/user/project/src/entry.js: ERROR: Could not resolve "pkg1" 1456 Users/user/project/node_modules/pkg1/package.json: NOTE: The module "./foo" was not found on the file system: 1457 NOTE: You can mark the path "pkg1" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle. 1458 Users/user/project/src/entry.js: ERROR: Could not resolve "pkg2" 1459 Users/user/project/node_modules/pkg2/package.json: NOTE: Importing the directory "./foo" is forbidden by this package: 1460 Users/user/project/node_modules/pkg2/package.json: NOTE: The presence of "exports" here makes importing a directory forbidden: 1461 NOTE: You can mark the path "pkg2" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle. 1462 `, 1463 }) 1464 } 1465 1466 func TestPackageJsonImportsErrorUnsupportedDirectoryImport(t *testing.T) { 1467 packagejson_suite.expectBundled(t, bundled{ 1468 files: map[string]string{ 1469 "/Users/user/project/src/entry.js": ` 1470 import '#foo1/bar' 1471 import '#foo2/bar' 1472 `, 1473 "/Users/user/project/package.json": ` 1474 { 1475 "imports": { 1476 "#foo1/*": "./foo1/*", 1477 "#foo2/bar": "./foo2/bar" 1478 } 1479 } 1480 `, 1481 "/Users/user/project/foo1/bar/index.js": ` 1482 console.log(bar) 1483 `, 1484 "/Users/user/project/foo2/bar/index.js": ` 1485 console.log(bar) 1486 `, 1487 }, 1488 entryPaths: []string{"/Users/user/project/src/entry.js"}, 1489 options: config.Options{ 1490 Mode: config.ModeBundle, 1491 AbsOutputFile: "/Users/user/project/out.js", 1492 }, 1493 expectedScanLog: `Users/user/project/src/entry.js: ERROR: Could not resolve "#foo1/bar" 1494 Users/user/project/package.json: NOTE: Importing the directory "./foo1/bar" is forbidden by this package: 1495 Users/user/project/package.json: NOTE: The presence of "imports" here makes importing a directory forbidden: 1496 Users/user/project/src/entry.js: NOTE: Import from "/index.js" to get the file "Users/user/project/foo1/bar/index.js": 1497 NOTE: You can mark the path "#foo1/bar" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle. 1498 Users/user/project/src/entry.js: ERROR: Could not resolve "#foo2/bar" 1499 Users/user/project/package.json: NOTE: Importing the directory "./foo2/bar" is forbidden by this package: 1500 Users/user/project/package.json: NOTE: The presence of "imports" here makes importing a directory forbidden: 1501 NOTE: You can mark the path "#foo2/bar" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle. 1502 `, 1503 }) 1504 } 1505 1506 func TestPackageJsonExportsRequireOverImport(t *testing.T) { 1507 packagejson_suite.expectBundled(t, bundled{ 1508 files: map[string]string{ 1509 "/Users/user/project/src/entry.js": ` 1510 require('pkg') 1511 `, 1512 "/Users/user/project/node_modules/pkg/package.json": ` 1513 { 1514 "exports": { 1515 "import": "./import.js", 1516 "require": "./require.js", 1517 "default": "./default.js" 1518 } 1519 } 1520 `, 1521 "/Users/user/project/node_modules/pkg/import.js": ` 1522 console.log('FAILURE') 1523 `, 1524 "/Users/user/project/node_modules/pkg/require.js": ` 1525 console.log('SUCCESS') 1526 `, 1527 }, 1528 entryPaths: []string{"/Users/user/project/src/entry.js"}, 1529 options: config.Options{ 1530 Mode: config.ModeBundle, 1531 AbsOutputFile: "/Users/user/project/out.js", 1532 }, 1533 }) 1534 } 1535 1536 func TestPackageJsonExportsImportOverRequire(t *testing.T) { 1537 packagejson_suite.expectBundled(t, bundled{ 1538 files: map[string]string{ 1539 "/Users/user/project/src/entry.js": ` 1540 import 'pkg' 1541 `, 1542 "/Users/user/project/node_modules/pkg/package.json": ` 1543 { 1544 "exports": { 1545 "require": "./require.js", 1546 "import": "./import.js", 1547 "default": "./default.js" 1548 } 1549 } 1550 `, 1551 "/Users/user/project/node_modules/pkg/require.js": ` 1552 console.log('FAILURE') 1553 `, 1554 "/Users/user/project/node_modules/pkg/import.js": ` 1555 console.log('SUCCESS') 1556 `, 1557 }, 1558 entryPaths: []string{"/Users/user/project/src/entry.js"}, 1559 options: config.Options{ 1560 Mode: config.ModeBundle, 1561 AbsOutputFile: "/Users/user/project/out.js", 1562 }, 1563 }) 1564 } 1565 1566 func TestPackageJsonExportsDefaultOverImportAndRequire(t *testing.T) { 1567 packagejson_suite.expectBundled(t, bundled{ 1568 files: map[string]string{ 1569 "/Users/user/project/src/entry.js": ` 1570 import 'pkg' 1571 `, 1572 "/Users/user/project/node_modules/pkg/package.json": ` 1573 { 1574 "exports": { 1575 "default": "./default.js", 1576 "import": "./import.js", 1577 "require": "./require.js" 1578 } 1579 } 1580 `, 1581 "/Users/user/project/node_modules/pkg/require.js": ` 1582 console.log('FAILURE') 1583 `, 1584 "/Users/user/project/node_modules/pkg/import.js": ` 1585 console.log('FAILURE') 1586 `, 1587 "/Users/user/project/node_modules/pkg/default.js": ` 1588 console.log('SUCCESS') 1589 `, 1590 }, 1591 entryPaths: []string{"/Users/user/project/src/entry.js"}, 1592 options: config.Options{ 1593 Mode: config.ModeBundle, 1594 AbsOutputFile: "/Users/user/project/out.js", 1595 }, 1596 }) 1597 } 1598 1599 func TestPackageJsonExportsEntryPointImportOverRequire(t *testing.T) { 1600 packagejson_suite.expectBundled(t, bundled{ 1601 files: map[string]string{ 1602 "/node_modules/pkg/package.json": ` 1603 { 1604 "exports": { 1605 "import": "./import.js", 1606 "require": "./require.js" 1607 }, 1608 "module": "./module.js", 1609 "main": "./main.js" 1610 } 1611 `, 1612 "/node_modules/pkg/import.js": ` 1613 console.log('SUCCESS') 1614 `, 1615 "/node_modules/pkg/require.js": ` 1616 console.log('FAILURE') 1617 `, 1618 "/node_modules/pkg/module.js": ` 1619 console.log('FAILURE') 1620 `, 1621 "/node_modules/pkg/main.js": ` 1622 console.log('FAILURE') 1623 `, 1624 }, 1625 entryPaths: []string{"pkg"}, 1626 options: config.Options{ 1627 Mode: config.ModeBundle, 1628 AbsOutputFile: "/out.js", 1629 }, 1630 }) 1631 } 1632 1633 func TestPackageJsonExportsEntryPointRequireOnly(t *testing.T) { 1634 packagejson_suite.expectBundled(t, bundled{ 1635 files: map[string]string{ 1636 "/node_modules/pkg/package.json": ` 1637 { 1638 "exports": { 1639 "require": "./require.js" 1640 }, 1641 "module": "./module.js", 1642 "main": "./main.js" 1643 } 1644 `, 1645 "/node_modules/pkg/require.js": ` 1646 console.log('FAILURE') 1647 `, 1648 "/node_modules/pkg/module.js": ` 1649 console.log('FAILURE') 1650 `, 1651 "/node_modules/pkg/main.js": ` 1652 console.log('FAILURE') 1653 `, 1654 }, 1655 entryPaths: []string{"pkg"}, 1656 options: config.Options{ 1657 Mode: config.ModeBundle, 1658 AbsOutputFile: "/out.js", 1659 }, 1660 expectedScanLog: `ERROR: Could not resolve "pkg" 1661 node_modules/pkg/package.json: NOTE: The path "." is not currently exported by package "pkg": 1662 node_modules/pkg/package.json: NOTE: None of the conditions in the package definition ("require") match any of the currently active conditions ("browser", "default", "import"): 1663 `, 1664 }) 1665 } 1666 1667 func TestPackageJsonExportsEntryPointModuleOverMain(t *testing.T) { 1668 packagejson_suite.expectBundled(t, bundled{ 1669 files: map[string]string{ 1670 "/node_modules/pkg/package.json": ` 1671 { 1672 "module": "./module.js", 1673 "main": "./main.js" 1674 } 1675 `, 1676 "/node_modules/pkg/module.js": ` 1677 console.log('SUCCESS') 1678 `, 1679 "/node_modules/pkg/main.js": ` 1680 console.log('FAILURE') 1681 `, 1682 }, 1683 entryPaths: []string{"pkg"}, 1684 options: config.Options{ 1685 Mode: config.ModeBundle, 1686 AbsOutputFile: "/out.js", 1687 }, 1688 }) 1689 } 1690 1691 func TestPackageJsonExportsEntryPointMainOnly(t *testing.T) { 1692 packagejson_suite.expectBundled(t, bundled{ 1693 files: map[string]string{ 1694 "/node_modules/pkg/package.json": ` 1695 { 1696 "main": "./main.js" 1697 } 1698 `, 1699 "/node_modules/pkg/main.js": ` 1700 console.log('SUCCESS') 1701 `, 1702 }, 1703 entryPaths: []string{"pkg"}, 1704 options: config.Options{ 1705 Mode: config.ModeBundle, 1706 AbsOutputFile: "/out.js", 1707 }, 1708 }) 1709 } 1710 1711 func TestPackageJsonExportsBrowser(t *testing.T) { 1712 packagejson_suite.expectBundled(t, bundled{ 1713 files: map[string]string{ 1714 "/Users/user/project/src/entry.js": ` 1715 import 'pkg' 1716 `, 1717 "/Users/user/project/node_modules/pkg/package.json": ` 1718 { 1719 "exports": { 1720 "node": "./node.js", 1721 "browser": "./browser.js", 1722 "default": "./default.js" 1723 } 1724 } 1725 `, 1726 "/Users/user/project/node_modules/pkg/node.js": ` 1727 console.log('FAILURE') 1728 `, 1729 "/Users/user/project/node_modules/pkg/browser.js": ` 1730 console.log('SUCCESS') 1731 `, 1732 }, 1733 entryPaths: []string{"/Users/user/project/src/entry.js"}, 1734 options: config.Options{ 1735 Mode: config.ModeBundle, 1736 AbsOutputFile: "/Users/user/project/out.js", 1737 Platform: config.PlatformBrowser, 1738 }, 1739 }) 1740 } 1741 1742 func TestPackageJsonExportsNode(t *testing.T) { 1743 packagejson_suite.expectBundled(t, bundled{ 1744 files: map[string]string{ 1745 "/Users/user/project/src/entry.js": ` 1746 import 'pkg' 1747 `, 1748 "/Users/user/project/node_modules/pkg/package.json": ` 1749 { 1750 "exports": { 1751 "browser": "./browser.js", 1752 "node": "./node.js", 1753 "default": "./default.js" 1754 } 1755 } 1756 `, 1757 "/Users/user/project/node_modules/pkg/browser.js": ` 1758 console.log('FAILURE') 1759 `, 1760 "/Users/user/project/node_modules/pkg/node.js": ` 1761 console.log('SUCCESS') 1762 `, 1763 }, 1764 entryPaths: []string{"/Users/user/project/src/entry.js"}, 1765 options: config.Options{ 1766 Mode: config.ModeBundle, 1767 AbsOutputFile: "/Users/user/project/out.js", 1768 Platform: config.PlatformNode, 1769 }, 1770 }) 1771 } 1772 1773 func TestPackageJsonExportsNeutral(t *testing.T) { 1774 packagejson_suite.expectBundled(t, bundled{ 1775 files: map[string]string{ 1776 "/Users/user/project/src/entry.js": ` 1777 import 'pkg' 1778 `, 1779 "/Users/user/project/node_modules/pkg/package.json": ` 1780 { 1781 "exports": { 1782 "node": "./node.js", 1783 "browser": "./browser.js", 1784 "default": "./default.js" 1785 } 1786 } 1787 `, 1788 "/Users/user/project/node_modules/pkg/node.js": ` 1789 console.log('FAILURE') 1790 `, 1791 "/Users/user/project/node_modules/pkg/browser.js": ` 1792 console.log('FAILURE') 1793 `, 1794 "/Users/user/project/node_modules/pkg/default.js": ` 1795 console.log('SUCCESS') 1796 `, 1797 }, 1798 entryPaths: []string{"/Users/user/project/src/entry.js"}, 1799 options: config.Options{ 1800 Mode: config.ModeBundle, 1801 AbsOutputFile: "/Users/user/project/out.js", 1802 Platform: config.PlatformNeutral, 1803 }, 1804 }) 1805 } 1806 1807 func TestPackageJsonExportsOrderIndependent(t *testing.T) { 1808 packagejson_suite.expectBundled(t, bundled{ 1809 files: map[string]string{ 1810 "/Users/user/project/src/entry.js": ` 1811 import 'pkg1/foo/bar.js' 1812 import 'pkg2/foo/bar.js' 1813 `, 1814 "/Users/user/project/node_modules/pkg1/package.json": ` 1815 { 1816 "exports": { 1817 "./": "./1/", 1818 "./foo/": "./2/" 1819 } 1820 } 1821 `, 1822 "/Users/user/project/node_modules/pkg1/1/foo/bar.js": ` 1823 console.log('FAILURE') 1824 `, 1825 "/Users/user/project/node_modules/pkg1/2/bar.js": ` 1826 console.log('SUCCESS') 1827 `, 1828 "/Users/user/project/node_modules/pkg2/package.json": ` 1829 { 1830 "exports": { 1831 "./foo/": "./1/", 1832 "./": "./2/" 1833 } 1834 } 1835 `, 1836 "/Users/user/project/node_modules/pkg2/1/bar.js": ` 1837 console.log('SUCCESS') 1838 `, 1839 "/Users/user/project/node_modules/pkg2/2/foo/bar.js": ` 1840 console.log('FAILURE') 1841 `, 1842 }, 1843 entryPaths: []string{"/Users/user/project/src/entry.js"}, 1844 options: config.Options{ 1845 Mode: config.ModeBundle, 1846 AbsOutputFile: "/Users/user/project/out.js", 1847 }, 1848 }) 1849 } 1850 1851 func TestPackageJsonExportsWildcard(t *testing.T) { 1852 packagejson_suite.expectBundled(t, bundled{ 1853 files: map[string]string{ 1854 "/Users/user/project/src/entry.js": ` 1855 import 'pkg1/foo' 1856 import 'pkg1/foo2' 1857 `, 1858 "/Users/user/project/node_modules/pkg1/package.json": ` 1859 { 1860 "exports": { 1861 "./foo*": "./file*.js" 1862 } 1863 } 1864 `, 1865 "/Users/user/project/node_modules/pkg1/file.js": ` 1866 console.log('SUCCESS') 1867 `, 1868 "/Users/user/project/node_modules/pkg1/file2.js": ` 1869 console.log('SUCCESS') 1870 `, 1871 }, 1872 entryPaths: []string{"/Users/user/project/src/entry.js"}, 1873 options: config.Options{ 1874 Mode: config.ModeBundle, 1875 AbsOutputFile: "/Users/user/project/out.js", 1876 }, 1877 }) 1878 } 1879 1880 func TestPackageJsonExportsErrorMissingTrailingSlash(t *testing.T) { 1881 packagejson_suite.expectBundled(t, bundled{ 1882 files: map[string]string{ 1883 "/Users/user/project/src/entry.js": ` 1884 import 'pkg1/foo/bar' 1885 `, 1886 "/Users/user/project/node_modules/pkg1/package.json": ` 1887 { "exports": { "./foo/": "./test" } } 1888 `, 1889 }, 1890 entryPaths: []string{"/Users/user/project/src/entry.js"}, 1891 options: config.Options{ 1892 Mode: config.ModeBundle, 1893 AbsOutputFile: "/Users/user/project/out.js", 1894 }, 1895 expectedScanLog: `Users/user/project/src/entry.js: ERROR: Could not resolve "pkg1/foo/bar" 1896 Users/user/project/node_modules/pkg1/package.json: NOTE: The module specifier "./test" is invalid because it doesn't end in "/": 1897 NOTE: You can mark the path "pkg1/foo/bar" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle. 1898 `, 1899 }) 1900 } 1901 1902 func TestPackageJsonExportsCustomConditions(t *testing.T) { 1903 packagejson_suite.expectBundled(t, bundled{ 1904 files: map[string]string{ 1905 "/Users/user/project/src/entry.js": ` 1906 import 'pkg1' 1907 `, 1908 "/Users/user/project/node_modules/pkg1/package.json": ` 1909 { 1910 "exports": { 1911 "custom1": "./custom1.js", 1912 "custom2": "./custom2.js", 1913 "default": "./default.js" 1914 } 1915 } 1916 `, 1917 "/Users/user/project/node_modules/pkg1/custom2.js": ` 1918 console.log('SUCCESS') 1919 `, 1920 }, 1921 entryPaths: []string{"/Users/user/project/src/entry.js"}, 1922 options: config.Options{ 1923 Mode: config.ModeBundle, 1924 AbsOutputFile: "/Users/user/project/out.js", 1925 Conditions: []string{"custom2"}, 1926 }, 1927 }) 1928 } 1929 1930 func TestPackageJsonExportsNotExactMissingExtension(t *testing.T) { 1931 packagejson_suite.expectBundled(t, bundled{ 1932 files: map[string]string{ 1933 "/Users/user/project/src/entry.js": ` 1934 import 'pkg1/foo/bar' 1935 `, 1936 "/Users/user/project/node_modules/pkg1/package.json": ` 1937 { 1938 "exports": { 1939 "./foo/": "./dir/" 1940 } 1941 } 1942 `, 1943 "/Users/user/project/node_modules/pkg1/dir/bar.js": ` 1944 console.log('SUCCESS') 1945 `, 1946 }, 1947 entryPaths: []string{"/Users/user/project/src/entry.js"}, 1948 options: config.Options{ 1949 Mode: config.ModeBundle, 1950 AbsOutputFile: "/Users/user/project/out.js", 1951 }, 1952 }) 1953 } 1954 1955 func TestPackageJsonExportsNotExactMissingExtensionPattern(t *testing.T) { 1956 packagejson_suite.expectBundled(t, bundled{ 1957 files: map[string]string{ 1958 "/Users/user/project/src/entry.js": ` 1959 import 'pkg1/foo/bar' 1960 `, 1961 "/Users/user/project/node_modules/pkg1/package.json": ` 1962 { 1963 "exports": { 1964 "./foo/*": "./dir/*" 1965 } 1966 } 1967 `, 1968 "/Users/user/project/node_modules/pkg1/dir/bar.js": ` 1969 console.log('SUCCESS') 1970 `, 1971 }, 1972 entryPaths: []string{"/Users/user/project/src/entry.js"}, 1973 options: config.Options{ 1974 Mode: config.ModeBundle, 1975 AbsOutputFile: "/Users/user/project/out.js", 1976 }, 1977 expectedScanLog: `Users/user/project/src/entry.js: ERROR: Could not resolve "pkg1/foo/bar" 1978 Users/user/project/node_modules/pkg1/package.json: NOTE: The module "./dir/bar" was not found on the file system: 1979 Users/user/project/src/entry.js: NOTE: Import from "pkg1/foo/bar.js" to get the file "Users/user/project/node_modules/pkg1/dir/bar.js": 1980 NOTE: You can mark the path "pkg1/foo/bar" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle. 1981 `, 1982 }) 1983 } 1984 1985 func TestPackageJsonExportsExactMissingExtension(t *testing.T) { 1986 packagejson_suite.expectBundled(t, bundled{ 1987 files: map[string]string{ 1988 "/Users/user/project/src/entry.js": ` 1989 import 'pkg1/foo/bar' 1990 `, 1991 "/Users/user/project/node_modules/pkg1/package.json": ` 1992 { 1993 "exports": { 1994 "./foo/bar": "./dir/bar" 1995 } 1996 } 1997 `, 1998 "/Users/user/project/node_modules/pkg1/dir/bar.js": ` 1999 console.log('SUCCESS') 2000 `, 2001 }, 2002 entryPaths: []string{"/Users/user/project/src/entry.js"}, 2003 options: config.Options{ 2004 Mode: config.ModeBundle, 2005 AbsOutputFile: "/Users/user/project/out.js", 2006 }, 2007 expectedScanLog: `Users/user/project/src/entry.js: ERROR: Could not resolve "pkg1/foo/bar" 2008 Users/user/project/node_modules/pkg1/package.json: NOTE: The module "./dir/bar" was not found on the file system: 2009 NOTE: You can mark the path "pkg1/foo/bar" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle. 2010 `, 2011 }) 2012 } 2013 2014 func TestPackageJsonExportsNoConditionsMatch(t *testing.T) { 2015 packagejson_suite.expectBundled(t, bundled{ 2016 files: map[string]string{ 2017 "/Users/user/project/src/entry.js": ` 2018 import 'pkg1' 2019 import 'pkg1/foo.js' 2020 `, 2021 "/Users/user/project/node_modules/pkg1/package.json": ` 2022 { 2023 "exports": { 2024 ".": { 2025 "what": "./foo.js" 2026 }, 2027 "./foo.js": { 2028 "what": "./foo.js" 2029 } 2030 } 2031 } 2032 `, 2033 "/Users/user/project/node_modules/pkg1/foo.js": ` 2034 console.log('FAILURE') 2035 `, 2036 }, 2037 entryPaths: []string{"/Users/user/project/src/entry.js"}, 2038 options: config.Options{ 2039 Mode: config.ModeBundle, 2040 AbsOutputFile: "/Users/user/project/out.js", 2041 }, 2042 expectedScanLog: `Users/user/project/src/entry.js: ERROR: Could not resolve "pkg1" 2043 Users/user/project/node_modules/pkg1/package.json: NOTE: The path "." is not currently exported by package "pkg1": 2044 Users/user/project/node_modules/pkg1/package.json: NOTE: None of the conditions in the package definition ("what") match any of the currently active conditions ("browser", "default", "import"): 2045 Users/user/project/node_modules/pkg1/package.json: NOTE: Consider enabling the "what" condition if this package expects it to be enabled. You can use 'Conditions: []string{"what"}' to do that: 2046 NOTE: You can mark the path "pkg1" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle. 2047 Users/user/project/src/entry.js: ERROR: Could not resolve "pkg1/foo.js" 2048 Users/user/project/node_modules/pkg1/package.json: NOTE: The path "./foo.js" is not currently exported by package "pkg1": 2049 Users/user/project/node_modules/pkg1/package.json: NOTE: None of the conditions in the package definition ("what") match any of the currently active conditions ("browser", "default", "import"): 2050 Users/user/project/node_modules/pkg1/package.json: NOTE: Consider enabling the "what" condition if this package expects it to be enabled. You can use 'Conditions: []string{"what"}' to do that: 2051 NOTE: You can mark the path "pkg1/foo.js" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle. 2052 `, 2053 }) 2054 } 2055 2056 func TestPackageJsonExportsMustUseRequire(t *testing.T) { 2057 packagejson_suite.expectBundled(t, bundled{ 2058 files: map[string]string{ 2059 "/Users/user/project/src/entry.js": ` 2060 import 'pkg1' 2061 import 'pkg1/foo.js' 2062 `, 2063 "/Users/user/project/node_modules/pkg1/package.json": ` 2064 { 2065 "exports": { 2066 ".": { 2067 "require": "./foo.js" 2068 }, 2069 "./foo.js": { 2070 "require": "./foo.js" 2071 } 2072 } 2073 } 2074 `, 2075 "/Users/user/project/node_modules/pkg1/foo.js": ` 2076 console.log('FAILURE') 2077 `, 2078 }, 2079 entryPaths: []string{"/Users/user/project/src/entry.js"}, 2080 options: config.Options{ 2081 Mode: config.ModeBundle, 2082 AbsOutputFile: "/Users/user/project/out.js", 2083 }, 2084 expectedScanLog: `Users/user/project/src/entry.js: ERROR: Could not resolve "pkg1" 2085 Users/user/project/node_modules/pkg1/package.json: NOTE: The path "." is not currently exported by package "pkg1": 2086 Users/user/project/node_modules/pkg1/package.json: NOTE: None of the conditions in the package definition ("require") match any of the currently active conditions ("browser", "default", "import"): 2087 Users/user/project/src/entry.js: NOTE: Consider using a "require()" call to import this file, which will work because the "require" condition is supported by this package: 2088 NOTE: You can mark the path "pkg1" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle. 2089 Users/user/project/src/entry.js: ERROR: Could not resolve "pkg1/foo.js" 2090 Users/user/project/node_modules/pkg1/package.json: NOTE: The path "./foo.js" is not currently exported by package "pkg1": 2091 Users/user/project/node_modules/pkg1/package.json: NOTE: None of the conditions in the package definition ("require") match any of the currently active conditions ("browser", "default", "import"): 2092 Users/user/project/src/entry.js: NOTE: Consider using a "require()" call to import this file, which will work because the "require" condition is supported by this package: 2093 NOTE: You can mark the path "pkg1/foo.js" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle. 2094 `, 2095 }) 2096 } 2097 2098 func TestPackageJsonExportsMustUseImport(t *testing.T) { 2099 packagejson_suite.expectBundled(t, bundled{ 2100 files: map[string]string{ 2101 "/Users/user/project/src/entry.js": ` 2102 require('pkg1') 2103 require('pkg1/foo.js') 2104 `, 2105 "/Users/user/project/node_modules/pkg1/package.json": ` 2106 { 2107 "exports": { 2108 ".": { 2109 "import": "./foo.js" 2110 }, 2111 "./foo.js": { 2112 "import": "./foo.js" 2113 } 2114 } 2115 } 2116 `, 2117 "/Users/user/project/node_modules/pkg1/foo.js": ` 2118 console.log('FAILURE') 2119 `, 2120 }, 2121 entryPaths: []string{"/Users/user/project/src/entry.js"}, 2122 options: config.Options{ 2123 Mode: config.ModeBundle, 2124 AbsOutputFile: "/Users/user/project/out.js", 2125 }, 2126 expectedScanLog: `Users/user/project/src/entry.js: ERROR: Could not resolve "pkg1" 2127 Users/user/project/node_modules/pkg1/package.json: NOTE: The path "." is not currently exported by package "pkg1": 2128 Users/user/project/node_modules/pkg1/package.json: NOTE: None of the conditions in the package definition ("import") match any of the currently active conditions ("browser", "default", "require"): 2129 Users/user/project/src/entry.js: NOTE: Consider using an "import" statement to import this file, which will work because the "import" condition is supported by this package: 2130 NOTE: You can mark the path "pkg1" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle. You can also surround this "require" call with a try/catch block to handle this failure at run-time instead of bundle-time. 2131 Users/user/project/src/entry.js: ERROR: Could not resolve "pkg1/foo.js" 2132 Users/user/project/node_modules/pkg1/package.json: NOTE: The path "./foo.js" is not currently exported by package "pkg1": 2133 Users/user/project/node_modules/pkg1/package.json: NOTE: None of the conditions in the package definition ("import") match any of the currently active conditions ("browser", "default", "require"): 2134 Users/user/project/src/entry.js: NOTE: Consider using an "import" statement to import this file, which will work because the "import" condition is supported by this package: 2135 NOTE: You can mark the path "pkg1/foo.js" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle. You can also surround this "require" call with a try/catch block to handle this failure at run-time instead of bundle-time. 2136 `, 2137 }) 2138 } 2139 2140 func TestPackageJsonExportsReverseLookup(t *testing.T) { 2141 packagejson_suite.expectBundled(t, bundled{ 2142 files: map[string]string{ 2143 "/Users/user/project/src/entry.js": ` 2144 require('pkg/path/to/real/file') 2145 require('pkg/path/to/other/file') 2146 `, 2147 "/Users/user/project/node_modules/pkg/package.json": ` 2148 { 2149 "exports": { 2150 "./lib/te*": { 2151 "default": "./path/to/re*.js" 2152 }, 2153 "./extra/": { 2154 "default": "./path/to/" 2155 } 2156 } 2157 } 2158 `, 2159 "/Users/user/project/node_modules/pkg/path/to/real/file.js": ``, 2160 "/Users/user/project/node_modules/pkg/path/to/other/file.js": ``, 2161 }, 2162 entryPaths: []string{"/Users/user/project/src/entry.js"}, 2163 options: config.Options{ 2164 Mode: config.ModeBundle, 2165 AbsOutputFile: "/Users/user/project/out.js", 2166 }, 2167 expectedScanLog: `Users/user/project/src/entry.js: ERROR: Could not resolve "pkg/path/to/real/file" 2168 Users/user/project/node_modules/pkg/package.json: NOTE: The path "./path/to/real/file" is not exported by package "pkg": 2169 Users/user/project/node_modules/pkg/package.json: NOTE: The file "./path/to/real/file.js" is exported at path "./lib/teal/file": 2170 Users/user/project/src/entry.js: NOTE: Import from "pkg/lib/teal/file" to get the file "Users/user/project/node_modules/pkg/path/to/real/file.js": 2171 NOTE: You can mark the path "pkg/path/to/real/file" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle. You can also surround this "require" call with a try/catch block to handle this failure at run-time instead of bundle-time. 2172 Users/user/project/src/entry.js: ERROR: Could not resolve "pkg/path/to/other/file" 2173 Users/user/project/node_modules/pkg/package.json: NOTE: The path "./path/to/other/file" is not exported by package "pkg": 2174 Users/user/project/node_modules/pkg/package.json: NOTE: The file "./path/to/other/file.js" is exported at path "./extra/other/file.js": 2175 Users/user/project/src/entry.js: NOTE: Import from "pkg/extra/other/file.js" to get the file "Users/user/project/node_modules/pkg/path/to/other/file.js": 2176 NOTE: You can mark the path "pkg/path/to/other/file" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle. You can also surround this "require" call with a try/catch block to handle this failure at run-time instead of bundle-time. 2177 `, 2178 }) 2179 } 2180 2181 func TestPackageJsonExportsPatternTrailers(t *testing.T) { 2182 packagejson_suite.expectBundled(t, bundled{ 2183 files: map[string]string{ 2184 "/Users/user/project/src/entry.js": ` 2185 import 'pkg/path/foo.js/bar.js' 2186 import 'pkg2/features/abc' 2187 import 'pkg2/features/xyz.js' 2188 `, 2189 "/Users/user/project/node_modules/pkg/package.json": ` 2190 { 2191 "exports": { 2192 "./path/*/bar.js": "./dir/baz-*" 2193 } 2194 } 2195 `, 2196 "/Users/user/project/node_modules/pkg/dir/baz-foo.js": ` 2197 console.log('works') 2198 `, 2199 "/Users/user/project/node_modules/pkg2/package.json": ` 2200 { 2201 "exports": { 2202 "./features/*": "./public/*.js", 2203 "./features/*.js": "./public/*.js" 2204 } 2205 } 2206 `, 2207 "/Users/user/project/node_modules/pkg2/public/abc.js": ` 2208 console.log('abc') 2209 `, 2210 "/Users/user/project/node_modules/pkg2/public/xyz.js": ` 2211 console.log('xyz') 2212 `, 2213 }, 2214 entryPaths: []string{"/Users/user/project/src/entry.js"}, 2215 options: config.Options{ 2216 Mode: config.ModeBundle, 2217 AbsOutputFile: "/Users/user/project/out.js", 2218 }, 2219 }) 2220 } 2221 2222 // Node's package.json format for "exports" allows for arrays to be used as map 2223 // values, like in the example below. Webpack's implementation interprets this 2224 // as a way to specify several alternative directories to search for packages. 2225 // See: https://webpack.js.org/guides/package-exports/#alternatives. However, 2226 // this doesn't follow Node's specification for how "exports" should work: 2227 // https://nodejs.org/api/esm.html#resolver-algorithm. Also no one else 2228 // implements it this way (e.g. both Node and Rollup don't do this). 2229 // 2230 // This test case can only be built by Webpack. Implementations that follow the 2231 // specification (including esbuild) will fail to build this test case. This 2232 // test case only exists to document that esbuild doesn't follow Webpack's 2233 // behavior here. 2234 func TestPackageJsonExportsAlternatives(t *testing.T) { 2235 packagejson_suite.expectBundled(t, bundled{ 2236 files: map[string]string{ 2237 "/Users/user/project/src/entry.js": ` 2238 import redApple from 'pkg/apples/red.js' 2239 import greenApple from 'pkg/apples/green.js' 2240 import redBook from 'pkg/books/red' 2241 import greenBook from 'pkg/books/green' 2242 console.log({redApple, greenApple, redBook, greenBook}) 2243 `, 2244 "/Users/user/project/node_modules/pkg/package.json": ` 2245 { 2246 "exports": { 2247 "./apples/": ["./good-apples/", "./bad-apples/"], 2248 "./books/*": ["./good-books/*-book.js", "./bad-books/*-book.js"] 2249 } 2250 } 2251 `, 2252 "/Users/user/project/node_modules/pkg/good-apples/green.js": ` 2253 export default '🍏' 2254 `, 2255 "/Users/user/project/node_modules/pkg/bad-apples/red.js": ` 2256 export default '🍎' 2257 `, 2258 "/Users/user/project/node_modules/pkg/good-books/green-book.js": ` 2259 export default '📗' 2260 `, 2261 "/Users/user/project/node_modules/pkg/bad-books/red-book.js": ` 2262 export default '📕' 2263 `, 2264 }, 2265 entryPaths: []string{"/Users/user/project/src/entry.js"}, 2266 options: config.Options{ 2267 Mode: config.ModeBundle, 2268 AbsOutputFile: "/Users/user/project/out.js", 2269 }, 2270 expectedScanLog: `Users/user/project/src/entry.js: ERROR: Could not resolve "pkg/apples/red.js" 2271 Users/user/project/node_modules/pkg/package.json: NOTE: The module "./good-apples/red.js" was not found on the file system: 2272 NOTE: You can mark the path "pkg/apples/red.js" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle. 2273 Users/user/project/src/entry.js: ERROR: Could not resolve "pkg/books/red" 2274 Users/user/project/node_modules/pkg/package.json: NOTE: The module "./good-books/red-book.js" was not found on the file system: 2275 NOTE: You can mark the path "pkg/books/red" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle. 2276 `, 2277 }) 2278 } 2279 2280 func TestPackageJsonImports(t *testing.T) { 2281 packagejson_suite.expectBundled(t, bundled{ 2282 files: map[string]string{ 2283 "/Users/user/project/src/foo/entry.js": ` 2284 import '#top-level' 2285 import '#nested/path.js' 2286 import '#star/c.js' 2287 import '#slash/d.js' 2288 `, 2289 "/Users/user/project/src/package.json": ` 2290 { 2291 "imports": { 2292 "#top-level": "./a.js", 2293 "#nested/path.js": "./b.js", 2294 "#star/*": "./some-star/*", 2295 "#slash/": "./some-slash/" 2296 } 2297 } 2298 `, 2299 "/Users/user/project/src/a.js": `console.log('a.js')`, 2300 "/Users/user/project/src/b.js": `console.log('b.js')`, 2301 "/Users/user/project/src/some-star/c.js": `console.log('c.js')`, 2302 "/Users/user/project/src/some-slash/d.js": `console.log('d.js')`, 2303 }, 2304 entryPaths: []string{"/Users/user/project/src/foo/entry.js"}, 2305 options: config.Options{ 2306 Mode: config.ModeBundle, 2307 AbsOutputFile: "/Users/user/project/out.js", 2308 }, 2309 }) 2310 } 2311 2312 func TestPackageJsonImportsRemapToOtherPackage(t *testing.T) { 2313 packagejson_suite.expectBundled(t, bundled{ 2314 files: map[string]string{ 2315 "/Users/user/project/src/entry.js": ` 2316 import '#top-level' 2317 import '#nested/path.js' 2318 import '#star/c.js' 2319 import '#slash/d.js' 2320 `, 2321 "/Users/user/project/src/package.json": ` 2322 { 2323 "imports": { 2324 "#top-level": "pkg/a.js", 2325 "#nested/path.js": "pkg/b.js", 2326 "#star/*": "pkg/some-star/*", 2327 "#slash/": "pkg/some-slash/" 2328 } 2329 } 2330 `, 2331 "/Users/user/project/src/node_modules/pkg/a.js": `console.log('a.js')`, 2332 "/Users/user/project/src/node_modules/pkg/b.js": `console.log('b.js')`, 2333 "/Users/user/project/src/node_modules/pkg/some-star/c.js": `console.log('c.js')`, 2334 "/Users/user/project/src/node_modules/pkg/some-slash/d.js": `console.log('d.js')`, 2335 }, 2336 entryPaths: []string{"/Users/user/project/src/entry.js"}, 2337 options: config.Options{ 2338 Mode: config.ModeBundle, 2339 AbsOutputFile: "/Users/user/project/out.js", 2340 }, 2341 }) 2342 } 2343 2344 func TestPackageJsonImportsErrorMissingRemappedPackage(t *testing.T) { 2345 packagejson_suite.expectBundled(t, bundled{ 2346 files: map[string]string{ 2347 "/Users/user/project/src/entry.js": ` 2348 import '#foo' 2349 `, 2350 "/Users/user/project/src/package.json": ` 2351 { 2352 "imports": { 2353 "#foo": "bar" 2354 } 2355 } 2356 `, 2357 }, 2358 entryPaths: []string{"/Users/user/project/src/entry.js"}, 2359 options: config.Options{ 2360 Mode: config.ModeBundle, 2361 AbsOutputFile: "/Users/user/project/out.js", 2362 }, 2363 expectedScanLog: `Users/user/project/src/entry.js: ERROR: Could not resolve "#foo" 2364 Users/user/project/src/package.json: NOTE: The remapped path "bar" could not be resolved: 2365 NOTE: You can mark the path "#foo" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle. 2366 `, 2367 }) 2368 } 2369 2370 func TestPackageJsonImportsInvalidPackageConfiguration(t *testing.T) { 2371 packagejson_suite.expectBundled(t, bundled{ 2372 files: map[string]string{ 2373 "/Users/user/project/src/entry.js": ` 2374 import '#foo' 2375 `, 2376 "/Users/user/project/src/package.json": ` 2377 { 2378 "imports": "#foo" 2379 } 2380 `, 2381 }, 2382 entryPaths: []string{"/Users/user/project/src/entry.js"}, 2383 options: config.Options{ 2384 Mode: config.ModeBundle, 2385 AbsOutputFile: "/Users/user/project/out.js", 2386 }, 2387 expectedScanLog: `Users/user/project/src/entry.js: ERROR: Could not resolve "#foo" 2388 Users/user/project/src/package.json: NOTE: The package configuration has an invalid value here: 2389 NOTE: You can mark the path "#foo" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle. 2390 Users/user/project/src/package.json: WARNING: The value for "imports" must be an object 2391 `, 2392 }) 2393 } 2394 2395 func TestPackageJsonImportsErrorEqualsHash(t *testing.T) { 2396 packagejson_suite.expectBundled(t, bundled{ 2397 files: map[string]string{ 2398 "/Users/user/project/src/entry.js": ` 2399 import '#' 2400 `, 2401 "/Users/user/project/src/package.json": ` 2402 { 2403 "imports": {} 2404 } 2405 `, 2406 }, 2407 entryPaths: []string{"/Users/user/project/src/entry.js"}, 2408 options: config.Options{ 2409 Mode: config.ModeBundle, 2410 AbsOutputFile: "/Users/user/project/out.js", 2411 }, 2412 expectedScanLog: `Users/user/project/src/entry.js: ERROR: Could not resolve "#" 2413 Users/user/project/src/package.json: NOTE: This "imports" map was ignored because the module specifier "#" is invalid: 2414 NOTE: You can mark the path "#" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle. 2415 `, 2416 }) 2417 } 2418 2419 func TestPackageJsonImportsErrorStartsWithHashSlash(t *testing.T) { 2420 packagejson_suite.expectBundled(t, bundled{ 2421 files: map[string]string{ 2422 "/Users/user/project/src/entry.js": ` 2423 import '#/foo' 2424 `, 2425 "/Users/user/project/src/package.json": ` 2426 { 2427 "imports": {} 2428 } 2429 `, 2430 }, 2431 entryPaths: []string{"/Users/user/project/src/entry.js"}, 2432 options: config.Options{ 2433 Mode: config.ModeBundle, 2434 AbsOutputFile: "/Users/user/project/out.js", 2435 }, 2436 expectedScanLog: `Users/user/project/src/entry.js: ERROR: Could not resolve "#/foo" 2437 Users/user/project/src/package.json: NOTE: This "imports" map was ignored because the module specifier "#/foo" is invalid: 2438 NOTE: You can mark the path "#/foo" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle. 2439 `, 2440 }) 2441 } 2442 2443 func TestPackageJsonMainFieldsErrorMessageDefault(t *testing.T) { 2444 packagejson_suite.expectBundled(t, bundled{ 2445 files: map[string]string{ 2446 "/Users/user/project/src/entry.js": ` 2447 import 'foo' 2448 `, 2449 "/Users/user/project/node_modules/foo/package.json": ` 2450 { 2451 "main": "./foo" 2452 } 2453 `, 2454 }, 2455 entryPaths: []string{"/Users/user/project/src/entry.js"}, 2456 options: config.Options{ 2457 Mode: config.ModeBundle, 2458 AbsOutputFile: "/Users/user/project/out.js", 2459 }, 2460 expectedScanLog: `Users/user/project/src/entry.js: ERROR: Could not resolve "foo" 2461 NOTE: You can mark the path "foo" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle. 2462 `, 2463 }) 2464 } 2465 2466 func TestPackageJsonMainFieldsErrorMessageNotIncluded(t *testing.T) { 2467 packagejson_suite.expectBundled(t, bundled{ 2468 files: map[string]string{ 2469 "/Users/user/project/src/entry.js": ` 2470 import 'foo' 2471 `, 2472 "/Users/user/project/node_modules/foo/package.json": ` 2473 { 2474 "main": "./foo" 2475 } 2476 `, 2477 }, 2478 entryPaths: []string{"/Users/user/project/src/entry.js"}, 2479 options: config.Options{ 2480 Mode: config.ModeBundle, 2481 AbsOutputFile: "/Users/user/project/out.js", 2482 MainFields: []string{"some", "fields"}, 2483 }, 2484 expectedScanLog: `Users/user/project/src/entry.js: ERROR: Could not resolve "foo" 2485 Users/user/project/node_modules/foo/package.json: NOTE: The "main" field here was ignored because the list of main fields to use is currently set to ["some", "fields"]. 2486 NOTE: You can mark the path "foo" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle. 2487 `, 2488 }) 2489 } 2490 2491 func TestPackageJsonMainFieldsErrorMessageEmpty(t *testing.T) { 2492 packagejson_suite.expectBundled(t, bundled{ 2493 files: map[string]string{ 2494 "/Users/user/project/src/entry.js": ` 2495 import 'foo' 2496 `, 2497 "/Users/user/project/node_modules/foo/package.json": ` 2498 { 2499 "main": "./foo" 2500 } 2501 `, 2502 }, 2503 entryPaths: []string{"/Users/user/project/src/entry.js"}, 2504 options: config.Options{ 2505 Mode: config.ModeBundle, 2506 AbsOutputFile: "/Users/user/project/out.js", 2507 MainFields: []string{}, 2508 }, 2509 expectedScanLog: `Users/user/project/src/entry.js: ERROR: Could not resolve "foo" 2510 Users/user/project/node_modules/foo/package.json: NOTE: The "main" field here was ignored because the list of main fields to use is currently set to []. 2511 NOTE: You can mark the path "foo" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle. 2512 `, 2513 }) 2514 } 2515 2516 func TestPackageJsonTypeShouldBeTypes(t *testing.T) { 2517 packagejson_suite.expectBundled(t, bundled{ 2518 files: map[string]string{ 2519 "/Users/user/project/src/index.js": ``, 2520 "/Users/user/project/package.json": ` 2521 { 2522 "main": "./src/index.js", 2523 "type": "./src/index.d.ts" 2524 } 2525 `, 2526 }, 2527 entryPaths: []string{"/Users/user/project/src/index.js"}, 2528 options: config.Options{ 2529 Mode: config.ModeBundle, 2530 AbsOutputFile: "/Users/user/project/out.js", 2531 MainFields: []string{}, 2532 }, 2533 expectedScanLog: `Users/user/project/package.json: WARNING: "./src/index.d.ts" is not a valid value for the "type" field 2534 Users/user/project/package.json: NOTE: TypeScript type declarations use the "types" field, not the "type" field: 2535 `, 2536 }) 2537 } 2538 2539 func TestPackageJsonImportSelfUsingRequire(t *testing.T) { 2540 packagejson_suite.expectBundled(t, bundled{ 2541 files: map[string]string{ 2542 "/Users/user/project/src/index.js": ` 2543 module.exports = 'index' 2544 console.log( 2545 require("xyz"), 2546 require("xyz/bar"), 2547 ) 2548 `, 2549 "/Users/user/project/src/foo-import.js": ` 2550 export default 'foo' 2551 `, 2552 "/Users/user/project/src/foo-require.js": ` 2553 module.exports = 'foo' 2554 `, 2555 "/Users/user/project/package.json": ` 2556 { 2557 "name": "xyz", 2558 "exports": { 2559 ".": "./src/index.js", 2560 "./bar": { 2561 "import": "./src/foo-import.js", 2562 "require": "./src/foo-require.js" 2563 } 2564 } 2565 } 2566 `, 2567 }, 2568 entryPaths: []string{"/Users/user/project/src/index.js"}, 2569 options: config.Options{ 2570 Mode: config.ModeBundle, 2571 AbsOutputFile: "/Users/user/project/out.js", 2572 MainFields: []string{}, 2573 }, 2574 }) 2575 } 2576 2577 func TestPackageJsonImportSelfUsingImport(t *testing.T) { 2578 packagejson_suite.expectBundled(t, bundled{ 2579 files: map[string]string{ 2580 "/Users/user/project/src/index.js": ` 2581 import xyz from "xyz" 2582 import foo from "xyz/bar" 2583 export default 'index' 2584 console.log(xyz, foo) 2585 `, 2586 "/Users/user/project/src/foo-import.js": ` 2587 export default 'foo' 2588 `, 2589 "/Users/user/project/src/foo-require.js": ` 2590 module.exports = 'foo' 2591 `, 2592 "/Users/user/project/package.json": ` 2593 { 2594 "name": "xyz", 2595 "exports": { 2596 ".": "./src/index.js", 2597 "./bar": { 2598 "import": "./src/foo-import.js", 2599 "require": "./src/foo-require.js" 2600 } 2601 } 2602 } 2603 `, 2604 }, 2605 entryPaths: []string{"/Users/user/project/src/index.js"}, 2606 options: config.Options{ 2607 Mode: config.ModeBundle, 2608 AbsOutputFile: "/Users/user/project/out.js", 2609 MainFields: []string{}, 2610 }, 2611 }) 2612 } 2613 2614 func TestPackageJsonImportSelfUsingRequireScoped(t *testing.T) { 2615 packagejson_suite.expectBundled(t, bundled{ 2616 files: map[string]string{ 2617 "/Users/user/project/src/index.js": ` 2618 module.exports = 'index' 2619 console.log( 2620 require("@some-scope/xyz"), 2621 require("@some-scope/xyz/bar"), 2622 ) 2623 `, 2624 "/Users/user/project/src/foo-import.js": ` 2625 export default 'foo' 2626 `, 2627 "/Users/user/project/src/foo-require.js": ` 2628 module.exports = 'foo' 2629 `, 2630 "/Users/user/project/package.json": ` 2631 { 2632 "name": "@some-scope/xyz", 2633 "exports": { 2634 ".": "./src/index.js", 2635 "./bar": { 2636 "import": "./src/foo-import.js", 2637 "require": "./src/foo-require.js" 2638 } 2639 } 2640 } 2641 `, 2642 }, 2643 entryPaths: []string{"/Users/user/project/src/index.js"}, 2644 options: config.Options{ 2645 Mode: config.ModeBundle, 2646 AbsOutputFile: "/Users/user/project/out.js", 2647 MainFields: []string{}, 2648 }, 2649 }) 2650 } 2651 2652 func TestPackageJsonImportSelfUsingImportScoped(t *testing.T) { 2653 packagejson_suite.expectBundled(t, bundled{ 2654 files: map[string]string{ 2655 "/Users/user/project/src/index.js": ` 2656 import xyz from "@some-scope/xyz" 2657 import foo from "@some-scope/xyz/bar" 2658 export default 'index' 2659 console.log(xyz, foo) 2660 `, 2661 "/Users/user/project/src/foo-import.js": ` 2662 export default 'foo' 2663 `, 2664 "/Users/user/project/src/foo-require.js": ` 2665 module.exports = 'foo' 2666 `, 2667 "/Users/user/project/package.json": ` 2668 { 2669 "name": "@some-scope/xyz", 2670 "exports": { 2671 ".": "./src/index.js", 2672 "./bar": { 2673 "import": "./src/foo-import.js", 2674 "require": "./src/foo-require.js" 2675 } 2676 } 2677 } 2678 `, 2679 }, 2680 entryPaths: []string{"/Users/user/project/src/index.js"}, 2681 options: config.Options{ 2682 Mode: config.ModeBundle, 2683 AbsOutputFile: "/Users/user/project/out.js", 2684 MainFields: []string{}, 2685 }, 2686 }) 2687 } 2688 2689 func TestPackageJsonImportSelfUsingRequireFailure(t *testing.T) { 2690 packagejson_suite.expectBundled(t, bundled{ 2691 files: map[string]string{ 2692 "/Users/user/project/src/index.js": ` 2693 require("xyz/src/foo.js") 2694 `, 2695 "/Users/user/project/src/foo.js": ` 2696 module.exports = 'foo' 2697 `, 2698 "/Users/user/project/package.json": ` 2699 { 2700 "name": "xyz", 2701 "exports": { 2702 ".": "./src/index.js", 2703 "./bar": "./src/foo.js" 2704 } 2705 } 2706 `, 2707 }, 2708 entryPaths: []string{"/Users/user/project/src/index.js"}, 2709 options: config.Options{ 2710 Mode: config.ModeBundle, 2711 AbsOutputFile: "/Users/user/project/out.js", 2712 MainFields: []string{}, 2713 }, 2714 expectedScanLog: `Users/user/project/src/index.js: ERROR: Could not resolve "xyz/src/foo.js" 2715 Users/user/project/package.json: NOTE: The path "./src/foo.js" is not exported by package "xyz": 2716 Users/user/project/package.json: NOTE: The file "./src/foo.js" is exported at path "./bar": 2717 Users/user/project/src/index.js: NOTE: Import from "xyz/bar" to get the file "Users/user/project/src/foo.js": 2718 NOTE: You can mark the path "xyz/src/foo.js" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle. You can also surround this "require" call with a try/catch block to handle this failure at run-time instead of bundle-time. 2719 `, 2720 }) 2721 } 2722 2723 func TestPackageJsonImportSelfUsingImportFailure(t *testing.T) { 2724 packagejson_suite.expectBundled(t, bundled{ 2725 files: map[string]string{ 2726 "/Users/user/project/src/index.js": ` 2727 import "xyz/src/foo.js" 2728 `, 2729 "/Users/user/project/src/foo.js": ` 2730 export default 'foo' 2731 `, 2732 "/Users/user/project/package.json": ` 2733 { 2734 "name": "xyz", 2735 "exports": { 2736 ".": "./src/index.js", 2737 "./bar": "./src/foo.js" 2738 } 2739 } 2740 `, 2741 }, 2742 entryPaths: []string{"/Users/user/project/src/index.js"}, 2743 options: config.Options{ 2744 Mode: config.ModeBundle, 2745 AbsOutputFile: "/Users/user/project/out.js", 2746 MainFields: []string{}, 2747 }, 2748 expectedScanLog: `Users/user/project/src/index.js: ERROR: Could not resolve "xyz/src/foo.js" 2749 Users/user/project/package.json: NOTE: The path "./src/foo.js" is not exported by package "xyz": 2750 Users/user/project/package.json: NOTE: The file "./src/foo.js" is exported at path "./bar": 2751 Users/user/project/src/index.js: NOTE: Import from "xyz/bar" to get the file "Users/user/project/src/foo.js": 2752 NOTE: You can mark the path "xyz/src/foo.js" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle. 2753 `, 2754 }) 2755 } 2756 2757 func TestCommonJSVariableInESMTypeModule(t *testing.T) { 2758 packagejson_suite.expectBundled(t, bundled{ 2759 files: map[string]string{ 2760 "/entry.js": `module.exports = null`, 2761 "/package.json": `{ "type": "module" }`, 2762 }, 2763 entryPaths: []string{"/entry.js"}, 2764 options: config.Options{ 2765 Mode: config.ModeBundle, 2766 AbsOutputFile: "/out.js", 2767 }, 2768 expectedScanLog: `entry.js: WARNING: The CommonJS "module" variable is treated as a global variable in an ECMAScript module and may not work as expected 2769 package.json: NOTE: This file is considered to be an ECMAScript module because the enclosing "package.json" file sets the type of this file to "module": 2770 NOTE: Node's package format requires that CommonJS files in a "type": "module" package use the ".cjs" file extension. 2771 `, 2772 }) 2773 } 2774 2775 func TestPackageJsonNodePathsIssue2752(t *testing.T) { 2776 packagejson_suite.expectBundled(t, bundled{ 2777 files: map[string]string{ 2778 "/src/entry.js": ` 2779 import "pkg1" 2780 import "pkg2" 2781 import "@scope/pkg3/baz" 2782 import "@scope/pkg4" 2783 `, 2784 "/usr/lib/pkg/pkg1/package.json": `{ "main": "./foo.js" }`, 2785 "/usr/lib/pkg/pkg1/foo.js": `console.log('pkg1')`, 2786 "/lib/pkg/pkg2/package.json": `{ "exports": { ".": "./bar.js" } }`, 2787 "/lib/pkg/pkg2/bar.js": `console.log('pkg2')`, 2788 "/var/lib/pkg/@scope/pkg3/package.json": `{ "browser": { "./baz.js": "./baz-browser.js" } }`, 2789 "/var/lib/pkg/@scope/pkg3/baz-browser.js": `console.log('pkg3')`, 2790 "/tmp/pkg/@scope/pkg4/package.json": `{ "exports": { ".": { "import": "./bat.js" } } }`, 2791 "/tmp/pkg/@scope/pkg4/bat.js": `console.log('pkg4')`, 2792 }, 2793 entryPaths: []string{"/src/entry.js"}, 2794 options: config.Options{ 2795 Mode: config.ModeBundle, 2796 AbsOutputFile: "/out.js", 2797 AbsNodePaths: []string{ 2798 "/usr/lib/pkg", 2799 "/lib/pkg", 2800 "/var/lib/pkg", 2801 "/tmp/pkg", 2802 }, 2803 }, 2804 }) 2805 } 2806 2807 // See: https://github.com/evanw/esbuild/issues/3377 2808 func TestPackageJsonReversePackageExportsIssue3377(t *testing.T) { 2809 packagejson_suite.expectBundled(t, bundled{ 2810 files: map[string]string{ 2811 "/lib/msw-config.ts": ` 2812 import { setupWorker, type SetupWorker } from 'msw/browser' 2813 setupWorker(); 2814 `, 2815 "/node_modules/msw/package.json": `{ 2816 "exports": { 2817 "./browser": { 2818 "node": null, 2819 "require": "./lib/browser/index.js", 2820 "import": "./lib/browser/index.mjs", 2821 "default": "./lib/browser/index.js" 2822 } 2823 } 2824 }`, 2825 "/node_modules/msw/browser/package.json": `{ 2826 "main": "../lib/browser/index.js", 2827 "module": "../lib/browser/index.mjs" 2828 }`, 2829 "/node_modules/msw/lib/browser/index.js": `TEST FAILURE`, 2830 "/node_modules/msw/lib/browser/index.mjs": `TEST FAILURE`, 2831 }, 2832 entryPaths: []string{"/lib/msw-config.ts"}, 2833 options: config.Options{ 2834 Mode: config.ModeBundle, 2835 AbsOutputFile: "/out.js", 2836 Platform: config.PlatformNode, 2837 }, 2838 expectedScanLog: `lib/msw-config.ts: ERROR: Could not resolve "msw/browser" 2839 node_modules/msw/package.json: NOTE: The path "./browser" cannot be imported from package "msw" because it was explicitly disabled by the package author here: 2840 NOTE: You can mark the path "msw/browser" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle. 2841 `, 2842 }) 2843 } 2844 2845 // See: https://github.com/evanw/esbuild/issues/3367 2846 func TestPackageJsonDisabledTypeModuleIssue3367(t *testing.T) { 2847 packagejson_suite.expectBundled(t, bundled{ 2848 files: map[string]string{ 2849 "/entry.js": ` 2850 import foo from 'foo' 2851 foo() 2852 `, 2853 "/package.json": ` 2854 { 2855 "browser": { 2856 "foo": false 2857 } 2858 } 2859 `, 2860 "/node_modules/foo/package.json": ` 2861 { 2862 "type": "module" 2863 } 2864 `, 2865 "/node_modules/foo/index.js": ` 2866 export default function() {} 2867 `, 2868 }, 2869 entryPaths: []string{"/entry.js"}, 2870 options: config.Options{ 2871 Mode: config.ModeBundle, 2872 AbsOutputFile: "/out.js", 2873 }, 2874 }) 2875 } 2876 2877 // See: https://github.com/evanw/esbuild/issues/3485 2878 func TestPackageJsonSubpathImportNodeBuiltinIssue3485(t *testing.T) { 2879 packagejson_suite.expectBundled(t, bundled{ 2880 files: map[string]string{ 2881 "/entry.js": ` 2882 import fs from '#fs' 2883 import http from '#http' 2884 fs.readFileSync() 2885 http.createServer() 2886 `, 2887 "/package.json": ` 2888 { 2889 "imports": { 2890 "#fs": { 2891 "node": "fs", 2892 "default": "./empty.js" 2893 }, 2894 "#http": { 2895 "node": "node:http", 2896 "default": "./empty.js" 2897 } 2898 } 2899 } 2900 `, 2901 "/empty.js": ``, 2902 }, 2903 entryPaths: []string{"/entry.js"}, 2904 options: config.Options{ 2905 Mode: config.ModeBundle, 2906 Platform: config.PlatformNode, 2907 AbsOutputFile: "/out.js", 2908 }, 2909 }) 2910 }