2018-12-17 17:38:05 +00:00
|
|
|
const URL = require('whatwg-url');
|
|
|
|
const warning = require('warning');
|
2018-01-10 05:41:19 +00:00
|
|
|
|
2018-12-17 17:38:05 +00:00
|
|
|
const origin = require('../serverConfig').origin;
|
2018-05-17 17:10:33 +00:00
|
|
|
|
2018-06-01 16:50:39 +00:00
|
|
|
const bareIdentifierFormat = /^((?:@[^/]+\/)?[^/]+)(\/.*)?$/;
|
2018-01-10 05:41:19 +00:00
|
|
|
|
2018-12-06 03:54:42 +00:00
|
|
|
function isValidURL(value) {
|
|
|
|
return URL.parseURL(value) != null;
|
|
|
|
}
|
|
|
|
|
|
|
|
function isProbablyURLWithoutProtocol(value) {
|
2018-12-17 17:38:05 +00:00
|
|
|
return value.substr(0, 2) === '//';
|
2018-12-06 03:54:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function isAbsoluteURL(value) {
|
|
|
|
return isValidURL(value) || isProbablyURLWithoutProtocol(value);
|
|
|
|
}
|
|
|
|
|
|
|
|
function isBareIdentifier(value) {
|
2018-12-17 17:38:05 +00:00
|
|
|
return value.charAt(0) !== '.' && value.charAt(0) !== '/';
|
2018-12-06 03:54:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function rewriteValue(/* StringLiteral */ node, dependencies) {
|
|
|
|
if (isAbsoluteURL(node.value)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isBareIdentifier(node.value)) {
|
|
|
|
// "bare" identifier
|
|
|
|
const match = bareIdentifierFormat.exec(node.value);
|
|
|
|
const packageName = match[1];
|
2018-12-17 17:38:05 +00:00
|
|
|
const file = match[2] || '';
|
2018-12-06 03:54:42 +00:00
|
|
|
|
|
|
|
warning(
|
|
|
|
dependencies[packageName],
|
|
|
|
'Missing version info for package "%s" in dependencies; falling back to "latest"',
|
|
|
|
packageName
|
|
|
|
);
|
|
|
|
|
2018-12-17 17:38:05 +00:00
|
|
|
const version = dependencies[packageName] || 'latest';
|
2018-12-06 03:54:42 +00:00
|
|
|
|
|
|
|
node.value = `${origin}/${packageName}@${version}${file}?module`;
|
|
|
|
} else {
|
|
|
|
// local path
|
|
|
|
node.value = `${node.value}?module`;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-17 17:10:33 +00:00
|
|
|
function unpkgRewrite(dependencies = {}) {
|
2018-01-10 05:41:19 +00:00
|
|
|
return {
|
2018-12-06 03:54:42 +00:00
|
|
|
manipulateOptions(opts, parserOpts) {
|
|
|
|
parserOpts.plugins.push(
|
2018-12-17 17:38:05 +00:00
|
|
|
'dynamicImport',
|
|
|
|
'exportDefaultFrom',
|
|
|
|
'exportNamespaceFrom',
|
|
|
|
'importMeta'
|
2018-12-06 03:54:42 +00:00
|
|
|
);
|
|
|
|
},
|
2018-01-10 05:41:19 +00:00
|
|
|
|
|
|
|
visitor: {
|
2018-12-06 03:54:42 +00:00
|
|
|
CallExpression(path) {
|
2018-12-17 17:38:05 +00:00
|
|
|
if (path.node.callee.type !== 'Import') {
|
2018-12-06 03:54:42 +00:00
|
|
|
// Some other function call, not import();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
rewriteValue(path.node.arguments[0], dependencies);
|
|
|
|
},
|
|
|
|
ExportAllDeclaration(path) {
|
|
|
|
return rewriteValue(path.node.source, dependencies);
|
|
|
|
},
|
|
|
|
ExportNamedDeclaration(path) {
|
|
|
|
if (!path.node.source) {
|
|
|
|
// This export has no "source", so it's probably
|
|
|
|
// a local variable or function, e.g.
|
|
|
|
// export { varName }
|
|
|
|
// export const constName = ...
|
|
|
|
// export function funcName() {}
|
|
|
|
return;
|
2018-01-10 05:41:19 +00:00
|
|
|
}
|
2018-12-06 03:54:42 +00:00
|
|
|
|
|
|
|
rewriteValue(path.node.source, dependencies);
|
|
|
|
},
|
|
|
|
ImportDeclaration(path) {
|
|
|
|
return rewriteValue(path.node.source, dependencies);
|
2018-01-10 05:41:19 +00:00
|
|
|
}
|
|
|
|
}
|
2018-02-18 02:00:56 +00:00
|
|
|
};
|
2018-01-10 05:41:19 +00:00
|
|
|
}
|
|
|
|
|
2018-05-17 17:10:33 +00:00
|
|
|
module.exports = unpkgRewrite;
|