Upgrade to Babel 7
Also, update to webpack 4 and add support for dynamic import() and import.meta in ?module mode. Fixes #108 Fixes #151
This commit is contained in:
@ -3,57 +3,65 @@ const unpkgRewrite = require("../unpkgRewrite");
|
||||
|
||||
const testCases = [
|
||||
{
|
||||
before: "import React from 'react';",
|
||||
after: "import React from 'https://unpkg.com/react@15.6.1?module';"
|
||||
before: 'import React from "react";',
|
||||
after: 'import React from "https://unpkg.com/react@15.6.1?module";'
|
||||
},
|
||||
{
|
||||
before: "import router from '@angular/router';",
|
||||
before: 'import router from "@angular/router";',
|
||||
after:
|
||||
"import router from 'https://unpkg.com/@angular/router@4.3.5?module';"
|
||||
'import router from "https://unpkg.com/@angular/router@4.3.5?module";'
|
||||
},
|
||||
{
|
||||
before: "import map from 'lodash.map';",
|
||||
after: "import map from 'https://unpkg.com/lodash.map@4.6.0?module';"
|
||||
before: 'import map from "lodash.map";',
|
||||
after: 'import map from "https://unpkg.com/lodash.map@4.6.0?module";'
|
||||
},
|
||||
{
|
||||
before: "import fs from 'pn/fs';",
|
||||
after: "import fs from 'https://unpkg.com/pn@1.0.0/fs?module';"
|
||||
before: 'import fs from "pn/fs";',
|
||||
after: 'import fs from "https://unpkg.com/pn@1.0.0/fs?module";'
|
||||
},
|
||||
{
|
||||
before: "import cupcakes from './cupcakes';",
|
||||
after: "import cupcakes from './cupcakes?module';"
|
||||
before: 'import cupcakes from "./cupcakes";',
|
||||
after: 'import cupcakes from "./cupcakes?module";'
|
||||
},
|
||||
{
|
||||
before: "import shoelaces from '/shoelaces';",
|
||||
after: "import shoelaces from '/shoelaces?module';"
|
||||
before: 'import shoelaces from "/shoelaces";',
|
||||
after: 'import shoelaces from "/shoelaces?module";'
|
||||
},
|
||||
{
|
||||
before: "import something from '//something.com/whatevs';",
|
||||
after: "import something from '//something.com/whatevs';"
|
||||
before: 'import something from "//something.com/whatevs";',
|
||||
after: 'import something from "//something.com/whatevs";'
|
||||
},
|
||||
{
|
||||
before: "import something from 'http://something.com/whatevs';",
|
||||
after: "import something from 'http://something.com/whatevs';"
|
||||
before: 'import something from "http://something.com/whatevs";',
|
||||
after: 'import something from "http://something.com/whatevs";'
|
||||
},
|
||||
{
|
||||
before: "let ReactDOM = require('react-dom');",
|
||||
after: "let ReactDOM = require('react-dom');"
|
||||
before: 'let ReactDOM = require("react-dom");',
|
||||
after: 'let ReactDOM = require("react-dom");'
|
||||
},
|
||||
{
|
||||
before: "export React from 'react';",
|
||||
after: "export React from 'https://unpkg.com/react@15.6.1?module';"
|
||||
before: 'export React from "react";',
|
||||
after: 'export React from "https://unpkg.com/react@15.6.1?module";'
|
||||
},
|
||||
{
|
||||
before: "export { Component } from 'react';",
|
||||
after: "export { Component } from 'https://unpkg.com/react@15.6.1?module';"
|
||||
before: 'export { Component } from "react";',
|
||||
after: 'export { Component } from "https://unpkg.com/react@15.6.1?module";'
|
||||
},
|
||||
{
|
||||
before: "export * from 'react';",
|
||||
after: "export * from 'https://unpkg.com/react@15.6.1?module';"
|
||||
before: 'export * from "react";',
|
||||
after: 'export * from "https://unpkg.com/react@15.6.1?module";'
|
||||
},
|
||||
{
|
||||
before: "export var message = 'hello';",
|
||||
after: "export var message = 'hello';"
|
||||
before: 'export var message = "hello";',
|
||||
after: 'export var message = "hello";'
|
||||
},
|
||||
{
|
||||
before: 'import("./something.js");',
|
||||
after: 'import("./something.js?module");'
|
||||
},
|
||||
{
|
||||
before: 'import("react");',
|
||||
after: 'import("https://unpkg.com/react@15.6.1?module");'
|
||||
}
|
||||
];
|
||||
|
||||
@ -66,7 +74,7 @@ const dependencies = {
|
||||
|
||||
describe("Rewriting imports/exports", () => {
|
||||
testCases.forEach(testCase => {
|
||||
it(`successfully rewrites "${testCase.before}"`, () => {
|
||||
it(`successfully rewrites '${testCase.before}'`, () => {
|
||||
const result = babel.transform(testCase.before, {
|
||||
plugins: [unpkgRewrite(dependencies)]
|
||||
});
|
||||
|
||||
@ -5,40 +5,85 @@ const origin = require("../serverConfig").origin;
|
||||
|
||||
const bareIdentifierFormat = /^((?:@[^/]+\/)?[^/]+)(\/.*)?$/;
|
||||
|
||||
function isValidURL(value) {
|
||||
return URL.parseURL(value) != null;
|
||||
}
|
||||
|
||||
function isProbablyURLWithoutProtocol(value) {
|
||||
return value.substr(0, 2) === "//";
|
||||
}
|
||||
|
||||
function isAbsoluteURL(value) {
|
||||
return isValidURL(value) || isProbablyURLWithoutProtocol(value);
|
||||
}
|
||||
|
||||
function isBareIdentifier(value) {
|
||||
return value.charAt(0) !== "." && value.charAt(0) !== "/";
|
||||
}
|
||||
|
||||
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];
|
||||
const file = match[2] || "";
|
||||
|
||||
warning(
|
||||
dependencies[packageName],
|
||||
'Missing version info for package "%s" in dependencies; falling back to "latest"',
|
||||
packageName
|
||||
);
|
||||
|
||||
const version = dependencies[packageName] || "latest";
|
||||
|
||||
node.value = `${origin}/${packageName}@${version}${file}?module`;
|
||||
} else {
|
||||
// local path
|
||||
node.value = `${node.value}?module`;
|
||||
}
|
||||
}
|
||||
|
||||
function unpkgRewrite(dependencies = {}) {
|
||||
return {
|
||||
inherits: require("babel-plugin-syntax-export-extensions"),
|
||||
manipulateOptions(opts, parserOpts) {
|
||||
parserOpts.plugins.push(
|
||||
"dynamicImport",
|
||||
"exportDefaultFrom",
|
||||
"exportNamespaceFrom",
|
||||
"importMeta"
|
||||
);
|
||||
},
|
||||
|
||||
visitor: {
|
||||
"ImportDeclaration|ExportNamedDeclaration|ExportAllDeclaration"(path) {
|
||||
if (!path.node.source) return; // probably a variable declaration
|
||||
|
||||
if (
|
||||
URL.parseURL(path.node.source.value) != null ||
|
||||
path.node.source.value.substr(0, 2) === "//"
|
||||
)
|
||||
return; // valid URL or URL w/o protocol, leave it alone
|
||||
|
||||
if ([".", "/"].indexOf(path.node.source.value.charAt(0)) >= 0) {
|
||||
// local path
|
||||
path.node.source.value = `${path.node.source.value}?module`;
|
||||
} else {
|
||||
// "bare" identifier
|
||||
const match = bareIdentifierFormat.exec(path.node.source.value);
|
||||
const packageName = match[1];
|
||||
const file = match[2] || "";
|
||||
|
||||
warning(
|
||||
dependencies[packageName],
|
||||
'Missing version info for package "%s" in dependencies; falling back to "latest"',
|
||||
packageName
|
||||
);
|
||||
|
||||
const version = dependencies[packageName] || "latest";
|
||||
const url = `${origin}/${packageName}@${version}${file}?module`;
|
||||
|
||||
path.node.source.value = url;
|
||||
CallExpression(path) {
|
||||
if (path.node.callee.type !== "Import") {
|
||||
// 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;
|
||||
}
|
||||
|
||||
rewriteValue(path.node.source, dependencies);
|
||||
},
|
||||
ImportDeclaration(path) {
|
||||
return rewriteValue(path.node.source, dependencies);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user