Files
esbuild/internal/bundler/bundler_packagejson_test.go
2020-10-03 10:26:36 -07:00

894 lines
23 KiB
Go

package bundler
import (
"testing"
"github.com/evanw/esbuild/internal/config"
)
var packagejson_suite = suite{
name: "packagejson",
}
func TestPackageJsonMain(t *testing.T) {
packagejson_suite.expectBundled(t, bundled{
files: map[string]string{
"/Users/user/project/src/entry.js": `
import fn from 'demo-pkg'
console.log(fn())
`,
"/Users/user/project/node_modules/demo-pkg/package.json": `
{
"main": "./custom-main.js"
}
`,
"/Users/user/project/node_modules/demo-pkg/custom-main.js": `
module.exports = function() {
return 123
}
`,
},
entryPaths: []string{"/Users/user/project/src/entry.js"},
options: config.Options{
Mode: config.ModeBundle,
AbsOutputFile: "/Users/user/project/out.js",
},
})
}
func TestPackageJsonBadMain(t *testing.T) {
packagejson_suite.expectBundled(t, bundled{
files: map[string]string{
"/Users/user/project/src/entry.js": `
import fn from 'demo-pkg'
console.log(fn())
`,
"/Users/user/project/node_modules/demo-pkg/package.json": `
{
"main": "./does-not-exist.js"
}
`,
"/Users/user/project/node_modules/demo-pkg/index.js": `
module.exports = function() {
return 123
}
`,
},
entryPaths: []string{"/Users/user/project/src/entry.js"},
options: config.Options{
Mode: config.ModeBundle,
AbsOutputFile: "/Users/user/project/out.js",
},
})
}
func TestPackageJsonSyntaxErrorComment(t *testing.T) {
packagejson_suite.expectBundled(t, bundled{
files: map[string]string{
"/Users/user/project/src/entry.js": `
import fn from 'demo-pkg'
console.log(fn())
`,
"/Users/user/project/node_modules/demo-pkg/package.json": `
{
// Single-line comment
"a": 1
}
`,
"/Users/user/project/node_modules/demo-pkg/index.js": `
module.exports = function() {
return 123
}
`,
},
entryPaths: []string{"/Users/user/project/src/entry.js"},
options: config.Options{
Mode: config.ModeBundle,
AbsOutputFile: "/Users/user/project/out.js",
},
expectedScanLog: "/Users/user/project/node_modules/demo-pkg/package.json: error: JSON does not support comments\n",
})
}
func TestPackageJsonSyntaxErrorTrailingComma(t *testing.T) {
packagejson_suite.expectBundled(t, bundled{
files: map[string]string{
"/Users/user/project/src/entry.js": `
import fn from 'demo-pkg'
console.log(fn())
`,
"/Users/user/project/node_modules/demo-pkg/package.json": `
{
"a": 1,
"b": 2,
}
`,
"/Users/user/project/node_modules/demo-pkg/index.js": `
module.exports = function() {
return 123
}
`,
},
entryPaths: []string{"/Users/user/project/src/entry.js"},
options: config.Options{
Mode: config.ModeBundle,
AbsOutputFile: "/Users/user/project/out.js",
},
expectedScanLog: "/Users/user/project/node_modules/demo-pkg/package.json: error: JSON does not support trailing commas\n",
})
}
func TestPackageJsonModule(t *testing.T) {
packagejson_suite.expectBundled(t, bundled{
files: map[string]string{
"/Users/user/project/src/entry.js": `
import fn from 'demo-pkg'
console.log(fn())
`,
"/Users/user/project/node_modules/demo-pkg/package.json": `
{
"main": "./main.js",
"module": "./main.esm.js"
}
`,
"/Users/user/project/node_modules/demo-pkg/main.js": `
module.exports = function() {
return 123
}
`,
"/Users/user/project/node_modules/demo-pkg/main.esm.js": `
export default function() {
return 123
}
`,
},
entryPaths: []string{"/Users/user/project/src/entry.js"},
options: config.Options{
Mode: config.ModeBundle,
AbsOutputFile: "/Users/user/project/out.js",
},
})
}
func TestPackageJsonBrowserString(t *testing.T) {
packagejson_suite.expectBundled(t, bundled{
files: map[string]string{
"/Users/user/project/src/entry.js": `
import fn from 'demo-pkg'
console.log(fn())
`,
"/Users/user/project/node_modules/demo-pkg/package.json": `
{
"browser": "./browser"
}
`,
"/Users/user/project/node_modules/demo-pkg/browser.js": `
module.exports = function() {
return 123
}
`,
},
entryPaths: []string{"/Users/user/project/src/entry.js"},
options: config.Options{
Mode: config.ModeBundle,
AbsOutputFile: "/Users/user/project/out.js",
},
})
}
func TestPackageJsonBrowserMapRelativeToRelative(t *testing.T) {
packagejson_suite.expectBundled(t, bundled{
files: map[string]string{
"/Users/user/project/src/entry.js": `
import fn from 'demo-pkg'
console.log(fn())
`,
"/Users/user/project/node_modules/demo-pkg/package.json": `
{
"main": "./main",
"browser": {
"./main.js": "./main-browser",
"./lib/util.js": "./lib/util-browser"
}
}
`,
"/Users/user/project/node_modules/demo-pkg/main.js": `
const util = require('./lib/util')
module.exports = function() {
return ['main', util]
}
`,
"/Users/user/project/node_modules/demo-pkg/main-browser.js": `
const util = require('./lib/util')
module.exports = function() {
return ['main-browser', util]
}
`,
"/Users/user/project/node_modules/demo-pkg/lib/util.js": `
module.exports = 'util'
`,
"/Users/user/project/node_modules/demo-pkg/lib/util-browser.js": `
module.exports = 'util-browser'
`,
},
entryPaths: []string{"/Users/user/project/src/entry.js"},
options: config.Options{
Mode: config.ModeBundle,
AbsOutputFile: "/Users/user/project/out.js",
},
})
}
func TestPackageJsonBrowserMapRelativeToModule(t *testing.T) {
packagejson_suite.expectBundled(t, bundled{
files: map[string]string{
"/Users/user/project/src/entry.js": `
import fn from 'demo-pkg'
console.log(fn())
`,
"/Users/user/project/node_modules/demo-pkg/package.json": `
{
"main": "./main",
"browser": {
"./util.js": "util-browser"
}
}
`,
"/Users/user/project/node_modules/demo-pkg/main.js": `
const util = require('./util')
module.exports = function() {
return ['main', util]
}
`,
"/Users/user/project/node_modules/demo-pkg/util.js": `
module.exports = 'util'
`,
"/Users/user/project/node_modules/util-browser/index.js": `
module.exports = 'util-browser'
`,
},
entryPaths: []string{"/Users/user/project/src/entry.js"},
options: config.Options{
Mode: config.ModeBundle,
AbsOutputFile: "/Users/user/project/out.js",
},
})
}
func TestPackageJsonBrowserMapRelativeDisabled(t *testing.T) {
packagejson_suite.expectBundled(t, bundled{
files: map[string]string{
"/Users/user/project/src/entry.js": `
import fn from 'demo-pkg'
console.log(fn())
`,
"/Users/user/project/node_modules/demo-pkg/package.json": `
{
"main": "./main",
"browser": {
"./util-node.js": false
}
}
`,
"/Users/user/project/node_modules/demo-pkg/main.js": `
const util = require('./util-node')
module.exports = function(obj) {
return util.inspect(obj)
}
`,
"/Users/user/project/node_modules/demo-pkg/util-node.js": `
module.exports = require('util')
`,
},
entryPaths: []string{"/Users/user/project/src/entry.js"},
options: config.Options{
Mode: config.ModeBundle,
AbsOutputFile: "/Users/user/project/out.js",
},
})
}
func TestPackageJsonBrowserMapModuleToRelative(t *testing.T) {
packagejson_suite.expectBundled(t, bundled{
files: map[string]string{
"/Users/user/project/src/entry.js": `
import fn from 'demo-pkg'
console.log(fn())
`,
"/Users/user/project/node_modules/demo-pkg/package.json": `
{
"browser": {
"node-pkg": "./node-pkg-browser"
}
}
`,
"/Users/user/project/node_modules/demo-pkg/node-pkg-browser.js": `
module.exports = function() {
return 123
}
`,
"/Users/user/project/node_modules/demo-pkg/index.js": `
const fn = require('node-pkg')
module.exports = function() {
return fn()
}
`,
"/Users/user/project/node_modules/node-pkg/index.js": `
module.exports = function() {
return 234
}
`,
},
entryPaths: []string{"/Users/user/project/src/entry.js"},
options: config.Options{
Mode: config.ModeBundle,
AbsOutputFile: "/Users/user/project/out.js",
},
})
}
func TestPackageJsonBrowserMapModuleToModule(t *testing.T) {
packagejson_suite.expectBundled(t, bundled{
files: map[string]string{
"/Users/user/project/src/entry.js": `
import fn from 'demo-pkg'
console.log(fn())
`,
"/Users/user/project/node_modules/demo-pkg/package.json": `
{
"browser": {
"node-pkg": "node-pkg-browser"
}
}
`,
"/Users/user/project/node_modules/node-pkg-browser/index.js": `
module.exports = function() {
return 123
}
`,
"/Users/user/project/node_modules/demo-pkg/index.js": `
const fn = require('node-pkg')
module.exports = function() {
return fn()
}
`,
"/Users/user/project/node_modules/node-pkg/index.js": `
module.exports = function() {
return 234
}
`,
},
entryPaths: []string{"/Users/user/project/src/entry.js"},
options: config.Options{
Mode: config.ModeBundle,
AbsOutputFile: "/Users/user/project/out.js",
},
})
}
func TestPackageJsonBrowserMapModuleDisabled(t *testing.T) {
packagejson_suite.expectBundled(t, bundled{
files: map[string]string{
"/Users/user/project/src/entry.js": `
import fn from 'demo-pkg'
console.log(fn())
`,
"/Users/user/project/node_modules/demo-pkg/package.json": `
{
"browser": {
"node-pkg": false
}
}
`,
"/Users/user/project/node_modules/demo-pkg/index.js": `
const fn = require('node-pkg')
module.exports = function() {
return fn()
}
`,
"/Users/user/project/node_modules/node-pkg/index.js": `
module.exports = function() {
return 234
}
`,
},
entryPaths: []string{"/Users/user/project/src/entry.js"},
options: config.Options{
Mode: config.ModeBundle,
AbsOutputFile: "/Users/user/project/out.js",
},
})
}
func TestPackageJsonBrowserMapNativeModuleDisabled(t *testing.T) {
packagejson_suite.expectBundled(t, bundled{
files: map[string]string{
"/Users/user/project/src/entry.js": `
import fn from 'demo-pkg'
console.log(fn())
`,
"/Users/user/project/node_modules/demo-pkg/package.json": `
{
"browser": {
"fs": false
}
}
`,
"/Users/user/project/node_modules/demo-pkg/index.js": `
const fs = require('fs')
module.exports = function() {
return fs.readFile()
}
`,
},
entryPaths: []string{"/Users/user/project/src/entry.js"},
options: config.Options{
Mode: config.ModeBundle,
AbsOutputFile: "/Users/user/project/out.js",
},
})
}
func TestPackageJsonBrowserMapAvoidMissing(t *testing.T) {
packagejson_suite.expectBundled(t, bundled{
files: map[string]string{
"/Users/user/project/src/entry.js": `
import 'component-classes'
`,
"/Users/user/project/node_modules/component-classes/package.json": `
{
"browser": {
"indexof": "component-indexof"
}
}
`,
"/Users/user/project/node_modules/component-classes/index.js": `
try {
var index = require('indexof');
} catch (err) {
var index = require('component-indexof');
}
`,
"/Users/user/project/node_modules/component-indexof/index.js": `
module.exports = function() {
return 234
}
`,
},
entryPaths: []string{"/Users/user/project/src/entry.js"},
options: config.Options{
Mode: config.ModeBundle,
AbsOutputFile: "/Users/user/project/out.js",
},
})
}
func TestPackageJsonBrowserOverModuleBrowser(t *testing.T) {
packagejson_suite.expectBundled(t, bundled{
files: map[string]string{
"/Users/user/project/src/entry.js": `
import fn from 'demo-pkg'
console.log(fn())
`,
"/Users/user/project/node_modules/demo-pkg/package.json": `
{
"main": "./main.js",
"module": "./main.esm.js",
"browser": "./main.browser.js"
}
`,
"/Users/user/project/node_modules/demo-pkg/main.js": `
module.exports = function() {
return 123
}
`,
"/Users/user/project/node_modules/demo-pkg/main.esm.js": `
export default function() {
return 123
}
`,
"/Users/user/project/node_modules/demo-pkg/main.browser.js": `
module.exports = function() {
return 123
}
`,
},
entryPaths: []string{"/Users/user/project/src/entry.js"},
options: config.Options{
Mode: config.ModeBundle,
Platform: config.PlatformBrowser,
AbsOutputFile: "/Users/user/project/out.js",
},
})
}
func TestPackageJsonBrowserOverMainNode(t *testing.T) {
packagejson_suite.expectBundled(t, bundled{
files: map[string]string{
"/Users/user/project/src/entry.js": `
import fn from 'demo-pkg'
console.log(fn())
`,
"/Users/user/project/node_modules/demo-pkg/package.json": `
{
"main": "./main.js",
"module": "./main.esm.js",
"browser": "./main.browser.js"
}
`,
"/Users/user/project/node_modules/demo-pkg/main.js": `
module.exports = function() {
return 123
}
`,
"/Users/user/project/node_modules/demo-pkg/main.esm.js": `
export default function() {
return 123
}
`,
"/Users/user/project/node_modules/demo-pkg/main.browser.js": `
module.exports = function() {
return 123
}
`,
},
entryPaths: []string{"/Users/user/project/src/entry.js"},
options: config.Options{
Mode: config.ModeBundle,
Platform: config.PlatformNode,
AbsOutputFile: "/Users/user/project/out.js",
},
})
}
func TestPackageJsonBrowserWithModuleBrowser(t *testing.T) {
packagejson_suite.expectBundled(t, bundled{
files: map[string]string{
"/Users/user/project/src/entry.js": `
import fn from 'demo-pkg'
console.log(fn())
`,
"/Users/user/project/node_modules/demo-pkg/package.json": `
{
"main": "./main.js",
"module": "./main.esm.js",
"browser": {
"./main.js": "./main.browser.js",
"./main.esm.js": "./main.browser.esm.js"
}
}
`,
"/Users/user/project/node_modules/demo-pkg/main.js": `
module.exports = function() {
return 123
}
`,
"/Users/user/project/node_modules/demo-pkg/main.esm.js": `
export default function() {
return 123
}
`,
"/Users/user/project/node_modules/demo-pkg/main.browser.js": `
module.exports = function() {
return 123
}
`,
"/Users/user/project/node_modules/demo-pkg/main.browser.esm.js": `
export default function() {
return 123
}
`,
},
entryPaths: []string{"/Users/user/project/src/entry.js"},
options: config.Options{
Mode: config.ModeBundle,
Platform: config.PlatformBrowser,
AbsOutputFile: "/Users/user/project/out.js",
},
})
}
func TestPackageJsonBrowserWithMainNode(t *testing.T) {
packagejson_suite.expectBundled(t, bundled{
files: map[string]string{
"/Users/user/project/src/entry.js": `
import fn from 'demo-pkg'
console.log(fn())
`,
"/Users/user/project/node_modules/demo-pkg/package.json": `
{
"main": "./main.js",
"module": "./main.esm.js",
"browser": {
"./main.js": "./main.browser.js",
"./main.esm.js": "./main.browser.esm.js"
}
}
`,
"/Users/user/project/node_modules/demo-pkg/main.js": `
module.exports = function() {
return 123
}
`,
"/Users/user/project/node_modules/demo-pkg/main.esm.js": `
export default function() {
return 123
}
`,
"/Users/user/project/node_modules/demo-pkg/main.browser.js": `
module.exports = function() {
return 123
}
`,
"/Users/user/project/node_modules/demo-pkg/main.browser.esm.js": `
export default function() {
return 123
}
`,
},
entryPaths: []string{"/Users/user/project/src/entry.js"},
options: config.Options{
Mode: config.ModeBundle,
Platform: config.PlatformNode,
AbsOutputFile: "/Users/user/project/out.js",
},
})
}
func TestPackageJsonDualPackageHazardImportOnly(t *testing.T) {
packagejson_suite.expectBundled(t, bundled{
files: map[string]string{
"/Users/user/project/src/entry.js": `
import value from 'demo-pkg'
console.log(value)
`,
"/Users/user/project/node_modules/demo-pkg/package.json": `
{
"main": "./main.js",
"module": "./module.js"
}
`,
"/Users/user/project/node_modules/demo-pkg/main.js": `
module.exports = 'main'
`,
"/Users/user/project/node_modules/demo-pkg/module.js": `
export default 'module'
`,
},
entryPaths: []string{"/Users/user/project/src/entry.js"},
options: config.Options{
Mode: config.ModeBundle,
AbsOutputFile: "/Users/user/project/out.js",
},
})
}
func TestPackageJsonDualPackageHazardRequireOnly(t *testing.T) {
packagejson_suite.expectBundled(t, bundled{
files: map[string]string{
"/Users/user/project/src/entry.js": `
console.log(require('demo-pkg'))
`,
"/Users/user/project/node_modules/demo-pkg/package.json": `
{
"main": "./main.js",
"module": "./module.js"
}
`,
"/Users/user/project/node_modules/demo-pkg/main.js": `
module.exports = 'main'
`,
"/Users/user/project/node_modules/demo-pkg/module.js": `
export default 'module'
`,
},
entryPaths: []string{"/Users/user/project/src/entry.js"},
options: config.Options{
Mode: config.ModeBundle,
AbsOutputFile: "/Users/user/project/out.js",
},
})
}
func TestPackageJsonDualPackageHazardImportAndRequireSameFile(t *testing.T) {
packagejson_suite.expectBundled(t, bundled{
files: map[string]string{
"/Users/user/project/src/entry.js": `
import value from 'demo-pkg'
console.log(value, require('demo-pkg'))
`,
"/Users/user/project/node_modules/demo-pkg/package.json": `
{
"main": "./main.js",
"module": "./module.js"
}
`,
"/Users/user/project/node_modules/demo-pkg/main.js": `
module.exports = 'main'
`,
"/Users/user/project/node_modules/demo-pkg/module.js": `
export default 'module'
`,
},
entryPaths: []string{"/Users/user/project/src/entry.js"},
options: config.Options{
Mode: config.ModeBundle,
AbsOutputFile: "/Users/user/project/out.js",
},
})
}
func TestPackageJsonDualPackageHazardImportAndRequireSeparateFiles(t *testing.T) {
packagejson_suite.expectBundled(t, bundled{
files: map[string]string{
"/Users/user/project/src/entry.js": `
import './test-main'
import './test-module'
`,
"/Users/user/project/src/test-main.js": `
console.log(require('demo-pkg'))
`,
"/Users/user/project/src/test-module.js": `
import value from 'demo-pkg'
console.log(value)
`,
"/Users/user/project/node_modules/demo-pkg/package.json": `
{
"main": "./main.js",
"module": "./module.js"
}
`,
"/Users/user/project/node_modules/demo-pkg/main.js": `
module.exports = 'main'
`,
"/Users/user/project/node_modules/demo-pkg/module.js": `
export default 'module'
`,
},
entryPaths: []string{"/Users/user/project/src/entry.js"},
options: config.Options{
Mode: config.ModeBundle,
AbsOutputFile: "/Users/user/project/out.js",
},
})
}
func TestPackageJsonDualPackageHazardImportAndRequireForceModuleBeforeMain(t *testing.T) {
packagejson_suite.expectBundled(t, bundled{
files: map[string]string{
"/Users/user/project/src/entry.js": `
import './test-main'
import './test-module'
`,
"/Users/user/project/src/test-main.js": `
console.log(require('demo-pkg'))
`,
"/Users/user/project/src/test-module.js": `
import value from 'demo-pkg'
console.log(value)
`,
"/Users/user/project/node_modules/demo-pkg/package.json": `
{
"main": "./main.js",
"module": "./module.js"
}
`,
"/Users/user/project/node_modules/demo-pkg/main.js": `
module.exports = 'main'
`,
"/Users/user/project/node_modules/demo-pkg/module.js": `
export default 'module'
`,
},
entryPaths: []string{"/Users/user/project/src/entry.js"},
options: config.Options{
Mode: config.ModeBundle,
MainFields: []string{"module", "main"},
AbsOutputFile: "/Users/user/project/out.js",
},
})
}
func TestPackageJsonDualPackageHazardImportAndRequireBrowser(t *testing.T) {
packagejson_suite.expectBundled(t, bundled{
files: map[string]string{
"/Users/user/project/src/entry.js": `
import './test-main'
import './test-module'
`,
"/Users/user/project/src/test-main.js": `
console.log(require('demo-pkg'))
`,
"/Users/user/project/src/test-module.js": `
import value from 'demo-pkg'
console.log(value)
`,
"/Users/user/project/node_modules/demo-pkg/package.json": `
{
"main": "./main.js",
"module": "./module.js",
"browser": {
"./main.js": "./main.browser.js",
"./module.js": "./module.browser.js"
}
}
`,
"/Users/user/project/node_modules/demo-pkg/main.js": `
module.exports = 'main'
`,
"/Users/user/project/node_modules/demo-pkg/module.js": `
export default 'module'
`,
"/Users/user/project/node_modules/demo-pkg/main.browser.js": `
module.exports = 'browser main'
`,
"/Users/user/project/node_modules/demo-pkg/module.browser.js": `
export default 'browser module'
`,
},
entryPaths: []string{"/Users/user/project/src/entry.js"},
options: config.Options{
Mode: config.ModeBundle,
AbsOutputFile: "/Users/user/project/out.js",
},
})
}
func TestPackageJsonMainFieldsA(t *testing.T) {
packagejson_suite.expectBundled(t, bundled{
files: map[string]string{
"/Users/user/project/src/entry.js": `
import value from 'demo-pkg'
console.log(value)
`,
"/Users/user/project/node_modules/demo-pkg/package.json": `
{
"a": "./a.js",
"b": "./b.js"
}
`,
"/Users/user/project/node_modules/demo-pkg/a.js": `
module.exports = 'a'
`,
"/Users/user/project/node_modules/demo-pkg/b.js": `
export default 'b'
`,
},
entryPaths: []string{"/Users/user/project/src/entry.js"},
options: config.Options{
Mode: config.ModeBundle,
MainFields: []string{"a", "b"},
AbsOutputFile: "/Users/user/project/out.js",
},
})
}
func TestPackageJsonMainFieldsB(t *testing.T) {
packagejson_suite.expectBundled(t, bundled{
files: map[string]string{
"/Users/user/project/src/entry.js": `
import value from 'demo-pkg'
console.log(value)
`,
"/Users/user/project/node_modules/demo-pkg/package.json": `
{
"a": "./a.js",
"b": "./b.js"
}
`,
"/Users/user/project/node_modules/demo-pkg/a.js": `
module.exports = 'a'
`,
"/Users/user/project/node_modules/demo-pkg/b.js": `
export default 'b'
`,
},
entryPaths: []string{"/Users/user/project/src/entry.js"},
options: config.Options{
Mode: config.ModeBundle,
MainFields: []string{"b", "a"},
AbsOutputFile: "/Users/user/project/out.js",
},
})
}