[react-packager] Implement the browser field package.json spec
This commit is contained in:
parent
bbddd0262d
commit
e3ce3d0d84
|
@ -674,6 +674,296 @@ describe('DependencyGraph', function() {
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
pit('should support simple browser field in packages', function() {
|
||||||
|
var root = '/root';
|
||||||
|
fs.__setMockFilesystem({
|
||||||
|
'root': {
|
||||||
|
'index.js': [
|
||||||
|
'/**',
|
||||||
|
' * @providesModule index',
|
||||||
|
' */',
|
||||||
|
'require("aPackage")',
|
||||||
|
].join('\n'),
|
||||||
|
'aPackage': {
|
||||||
|
'package.json': JSON.stringify({
|
||||||
|
name: 'aPackage',
|
||||||
|
main: 'main.js',
|
||||||
|
browser: 'client.js',
|
||||||
|
}),
|
||||||
|
'main.js': 'some other code',
|
||||||
|
'client.js': 'some code',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var dgraph = new DependencyGraph({
|
||||||
|
roots: [root],
|
||||||
|
fileWatcher: fileWatcher
|
||||||
|
});
|
||||||
|
return dgraph.load().then(function() {
|
||||||
|
expect(dgraph.getOrderedDependencies('/root/index.js'))
|
||||||
|
.toEqual([
|
||||||
|
{ id: 'index', altId: '/root/index.js',
|
||||||
|
path: '/root/index.js',
|
||||||
|
dependencies: ['aPackage']
|
||||||
|
},
|
||||||
|
{ id: 'aPackage/client',
|
||||||
|
path: '/root/aPackage/client.js',
|
||||||
|
dependencies: []
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
pit('should supportbrowser field in packages w/o .js ext', function() {
|
||||||
|
var root = '/root';
|
||||||
|
fs.__setMockFilesystem({
|
||||||
|
'root': {
|
||||||
|
'index.js': [
|
||||||
|
'/**',
|
||||||
|
' * @providesModule index',
|
||||||
|
' */',
|
||||||
|
'require("aPackage")',
|
||||||
|
].join('\n'),
|
||||||
|
'aPackage': {
|
||||||
|
'package.json': JSON.stringify({
|
||||||
|
name: 'aPackage',
|
||||||
|
main: 'main.js',
|
||||||
|
browser: 'client',
|
||||||
|
}),
|
||||||
|
'main.js': 'some other code',
|
||||||
|
'client.js': 'some code',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var dgraph = new DependencyGraph({
|
||||||
|
roots: [root],
|
||||||
|
fileWatcher: fileWatcher
|
||||||
|
});
|
||||||
|
return dgraph.load().then(function() {
|
||||||
|
expect(dgraph.getOrderedDependencies('/root/index.js'))
|
||||||
|
.toEqual([
|
||||||
|
{ id: 'index', altId: '/root/index.js',
|
||||||
|
path: '/root/index.js',
|
||||||
|
dependencies: ['aPackage']
|
||||||
|
},
|
||||||
|
{ id: 'aPackage/client',
|
||||||
|
path: '/root/aPackage/client.js',
|
||||||
|
dependencies: []
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
pit('should support mapping main in browser field json', function() {
|
||||||
|
var root = '/root';
|
||||||
|
fs.__setMockFilesystem({
|
||||||
|
'root': {
|
||||||
|
'index.js': [
|
||||||
|
'/**',
|
||||||
|
' * @providesModule index',
|
||||||
|
' */',
|
||||||
|
'require("aPackage")',
|
||||||
|
].join('\n'),
|
||||||
|
'aPackage': {
|
||||||
|
'package.json': JSON.stringify({
|
||||||
|
name: 'aPackage',
|
||||||
|
main: './main.js',
|
||||||
|
browser: {
|
||||||
|
'./main.js': './client.js',
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
'main.js': 'some other code',
|
||||||
|
'client.js': 'some code',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var dgraph = new DependencyGraph({
|
||||||
|
roots: [root],
|
||||||
|
fileWatcher: fileWatcher
|
||||||
|
});
|
||||||
|
return dgraph.load().then(function() {
|
||||||
|
expect(dgraph.getOrderedDependencies('/root/index.js'))
|
||||||
|
.toEqual([
|
||||||
|
{ id: 'index', altId: '/root/index.js',
|
||||||
|
path: '/root/index.js',
|
||||||
|
dependencies: ['aPackage']
|
||||||
|
},
|
||||||
|
{ id: 'aPackage/client',
|
||||||
|
path: '/root/aPackage/client.js',
|
||||||
|
dependencies: []
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
pit('should work do correct browser mapping w/o js ext', function() {
|
||||||
|
var root = '/root';
|
||||||
|
fs.__setMockFilesystem({
|
||||||
|
'root': {
|
||||||
|
'index.js': [
|
||||||
|
'/**',
|
||||||
|
' * @providesModule index',
|
||||||
|
' */',
|
||||||
|
'require("aPackage")',
|
||||||
|
].join('\n'),
|
||||||
|
'aPackage': {
|
||||||
|
'package.json': JSON.stringify({
|
||||||
|
name: 'aPackage',
|
||||||
|
main: './main.js',
|
||||||
|
browser: {
|
||||||
|
'./main': './client.js',
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
'main.js': 'some other code',
|
||||||
|
'client.js': 'some code',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var dgraph = new DependencyGraph({
|
||||||
|
roots: [root],
|
||||||
|
fileWatcher: fileWatcher
|
||||||
|
});
|
||||||
|
return dgraph.load().then(function() {
|
||||||
|
expect(dgraph.getOrderedDependencies('/root/index.js'))
|
||||||
|
.toEqual([
|
||||||
|
{ id: 'index', altId: '/root/index.js',
|
||||||
|
path: '/root/index.js',
|
||||||
|
dependencies: ['aPackage']
|
||||||
|
},
|
||||||
|
{ id: 'aPackage/client',
|
||||||
|
path: '/root/aPackage/client.js',
|
||||||
|
dependencies: []
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
pit('should support browser mapping of files', function() {
|
||||||
|
var root = '/root';
|
||||||
|
fs.__setMockFilesystem({
|
||||||
|
'root': {
|
||||||
|
'index.js': [
|
||||||
|
'/**',
|
||||||
|
' * @providesModule index',
|
||||||
|
' */',
|
||||||
|
'require("aPackage")',
|
||||||
|
].join('\n'),
|
||||||
|
'aPackage': {
|
||||||
|
'package.json': JSON.stringify({
|
||||||
|
name: 'aPackage',
|
||||||
|
main: './main.js',
|
||||||
|
browser: {
|
||||||
|
'./main': './client.js',
|
||||||
|
'./node.js': './not-node.js',
|
||||||
|
'./not-browser': './browser.js',
|
||||||
|
'./dir/server.js': './dir/client',
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
'main.js': 'some other code',
|
||||||
|
'client.js': 'require("./node")\nrequire("./dir/server.js")',
|
||||||
|
'not-node.js': 'require("./not-browser")',
|
||||||
|
'not-browser.js': 'require("./dir/server")',
|
||||||
|
'browser.js': 'some browser code',
|
||||||
|
'dir': {
|
||||||
|
'server.js': 'some node code',
|
||||||
|
'client.js': 'some browser code',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var dgraph = new DependencyGraph({
|
||||||
|
roots: [root],
|
||||||
|
fileWatcher: fileWatcher
|
||||||
|
});
|
||||||
|
return dgraph.load().then(function() {
|
||||||
|
expect(dgraph.getOrderedDependencies('/root/index.js'))
|
||||||
|
.toEqual([
|
||||||
|
{ id: 'index', altId: '/root/index.js',
|
||||||
|
path: '/root/index.js',
|
||||||
|
dependencies: ['aPackage']
|
||||||
|
},
|
||||||
|
{ id: 'aPackage/client',
|
||||||
|
path: '/root/aPackage/client.js',
|
||||||
|
dependencies: ['./node', './dir/server.js']
|
||||||
|
},
|
||||||
|
{ id: 'aPackage/not-node',
|
||||||
|
path: '/root/aPackage/not-node.js',
|
||||||
|
dependencies: ['./not-browser']
|
||||||
|
},
|
||||||
|
{ id: 'aPackage/browser',
|
||||||
|
path: '/root/aPackage/browser.js',
|
||||||
|
dependencies: []
|
||||||
|
},
|
||||||
|
{ id: 'aPackage/dir/client',
|
||||||
|
path: '/root/aPackage/dir/client.js',
|
||||||
|
dependencies: []
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
pit('should support browser mapping for packages', function() {
|
||||||
|
var root = '/root';
|
||||||
|
fs.__setMockFilesystem({
|
||||||
|
'root': {
|
||||||
|
'index.js': [
|
||||||
|
'/**',
|
||||||
|
' * @providesModule index',
|
||||||
|
' */',
|
||||||
|
'require("aPackage")',
|
||||||
|
].join('\n'),
|
||||||
|
'aPackage': {
|
||||||
|
'package.json': JSON.stringify({
|
||||||
|
name: 'aPackage',
|
||||||
|
browser: {
|
||||||
|
'node-package': 'browser-package',
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
'index.js': 'require("node-package")',
|
||||||
|
'node-package': {
|
||||||
|
'package.json': JSON.stringify({
|
||||||
|
'name': 'node-package',
|
||||||
|
}),
|
||||||
|
'index.js': 'some node code',
|
||||||
|
},
|
||||||
|
'browser-package': {
|
||||||
|
'package.json': JSON.stringify({
|
||||||
|
'name': 'browser-package',
|
||||||
|
}),
|
||||||
|
'index.js': 'some browser code',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var dgraph = new DependencyGraph({
|
||||||
|
roots: [root],
|
||||||
|
fileWatcher: fileWatcher
|
||||||
|
});
|
||||||
|
return dgraph.load().then(function() {
|
||||||
|
expect(dgraph.getOrderedDependencies('/root/index.js'))
|
||||||
|
.toEqual([
|
||||||
|
{ id: 'index', altId: '/root/index.js',
|
||||||
|
path: '/root/index.js',
|
||||||
|
dependencies: ['aPackage']
|
||||||
|
},
|
||||||
|
{ id: 'aPackage/index',
|
||||||
|
path: '/root/aPackage/index.js',
|
||||||
|
dependencies: ['node-package']
|
||||||
|
},
|
||||||
|
{ id: 'browser-package/index',
|
||||||
|
path: '/root/aPackage/browser-package/index.js',
|
||||||
|
dependencies: []
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('file watch updating', function() {
|
describe('file watch updating', function() {
|
||||||
|
|
|
@ -168,15 +168,22 @@ DependecyGraph.prototype.resolveDependency = function(
|
||||||
// Package relative modules starts with '.' or '..'.
|
// Package relative modules starts with '.' or '..'.
|
||||||
if (depModuleId[0] !== '.') {
|
if (depModuleId[0] !== '.') {
|
||||||
|
|
||||||
// 1. `depModuleId` is simply a top-level `providesModule`.
|
// Check if we need to map the dependency to something else via the
|
||||||
// 2. `depModuleId` is a package module but given the full path from the
|
// `browser` field in package.json
|
||||||
// package, i.e. package_name/module_name
|
var fromPackageJson = this._lookupPackage(fromModule.path);
|
||||||
|
if (fromPackageJson && fromPackageJson.browser &&
|
||||||
|
fromPackageJson.browser[depModuleId]) {
|
||||||
|
depModuleId = fromPackageJson.browser[depModuleId];
|
||||||
|
}
|
||||||
|
|
||||||
|
// `depModuleId` is simply a top-level `providesModule`.
|
||||||
|
// `depModuleId` is a package module but given the full path from the
|
||||||
|
// package, i.e. package_name/module_name
|
||||||
if (this._moduleById[sansExtJs(depModuleId)]) {
|
if (this._moduleById[sansExtJs(depModuleId)]) {
|
||||||
return this._moduleById[sansExtJs(depModuleId)];
|
return this._moduleById[sansExtJs(depModuleId)];
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. `depModuleId` is a package and it's depending on the "main"
|
// `depModuleId` is a package and it's depending on the "main" resolution.
|
||||||
// resolution.
|
|
||||||
packageJson = this._packagesById[depModuleId];
|
packageJson = this._packagesById[depModuleId];
|
||||||
|
|
||||||
// We are being forgiving here and raising an error because we could be
|
// We are being forgiving here and raising an error because we could be
|
||||||
|
@ -190,7 +197,25 @@ DependecyGraph.prototype.resolveDependency = function(
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var main = packageJson.main || 'index';
|
var main;
|
||||||
|
|
||||||
|
// We prioritize the `browser` field if it's a module path.
|
||||||
|
if (typeof packageJson.browser === 'string') {
|
||||||
|
main = packageJson.browser;
|
||||||
|
} else {
|
||||||
|
main = packageJson.main || 'index';
|
||||||
|
}
|
||||||
|
|
||||||
|
// If there is a mapping for main in the `browser` field.
|
||||||
|
if (packageJson.browser && typeof packageJson.browser === 'object') {
|
||||||
|
var tmpMain = packageJson.browser[main] ||
|
||||||
|
packageJson.browser[withExtJs(main)] ||
|
||||||
|
packageJson.browser[sansExtJs(main)];
|
||||||
|
if (tmpMain) {
|
||||||
|
main = tmpMain;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
modulePath = withExtJs(path.join(packageJson._root, main));
|
modulePath = withExtJs(path.join(packageJson._root, main));
|
||||||
dep = this._graph[modulePath];
|
dep = this._graph[modulePath];
|
||||||
|
|
||||||
|
@ -207,8 +232,7 @@ DependecyGraph.prototype.resolveDependency = function(
|
||||||
return dep;
|
return dep;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// 4. `depModuleId` is a module defined in a package relative to
|
// `depModuleId` is a module defined in a package relative to `fromModule`.
|
||||||
// `fromModule`.
|
|
||||||
packageJson = this._lookupPackage(fromModule.path);
|
packageJson = this._lookupPackage(fromModule.path);
|
||||||
|
|
||||||
if (packageJson == null) {
|
if (packageJson == null) {
|
||||||
|
@ -224,12 +248,23 @@ DependecyGraph.prototype.resolveDependency = function(
|
||||||
var dir = path.dirname(fromModule.path);
|
var dir = path.dirname(fromModule.path);
|
||||||
modulePath = path.join(dir, depModuleId);
|
modulePath = path.join(dir, depModuleId);
|
||||||
|
|
||||||
|
if (packageJson.browser && typeof packageJson.browser === 'object') {
|
||||||
|
var relPath = './' + path.relative(packageJson._root, modulePath);
|
||||||
|
var tmpModulePath = packageJson.browser[withExtJs(relPath)] ||
|
||||||
|
packageJson.browser[sansExtJs(relPath)];
|
||||||
|
if (tmpModulePath) {
|
||||||
|
modulePath = path.join(packageJson._root, tmpModulePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// JS modules can be required without extensios.
|
||||||
if (this._assetExts.indexOf(extname(modulePath)) === -1) {
|
if (this._assetExts.indexOf(extname(modulePath)) === -1) {
|
||||||
modulePath = withExtJs(modulePath);
|
modulePath = withExtJs(modulePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
dep = this._graph[modulePath];
|
dep = this._graph[modulePath];
|
||||||
|
|
||||||
|
// Maybe the dependency is a directory and there is an index.js inside it.
|
||||||
if (dep == null) {
|
if (dep == null) {
|
||||||
modulePath = path.join(dir, depModuleId, 'index.js');
|
modulePath = path.join(dir, depModuleId, 'index.js');
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue