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:
parent
fde375782c
commit
4fd697aec1
|
@ -2,8 +2,8 @@ FROM node:8
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
COPY package.json yarn.lock ./
|
COPY package.json package-lock.json ./
|
||||||
RUN yarn --pure-lockfile
|
RUN npm ci
|
||||||
# COPY . .
|
# COPY . .
|
||||||
|
|
||||||
ENV PORT 5000
|
ENV PORT 5000
|
||||||
|
|
|
@ -1,8 +1,4 @@
|
||||||
{
|
{
|
||||||
"presets": ["env", "stage-2", "react"],
|
"presets": [["@babel/env", { "loose": true }], "@babel/react"],
|
||||||
"env": {
|
"plugins": [["@babel/plugin-proposal-class-properties", { "loose": true }]]
|
||||||
"production": {
|
|
||||||
"plugins": ["transform-react-remove-prop-types"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// Use babel to compile JSX on the fly.
|
// Use babel to compile JSX on the fly.
|
||||||
require("babel-register")({
|
require("@babel/register")({
|
||||||
only: /modules\/client/
|
only: [/modules\/client/]
|
||||||
});
|
});
|
||||||
|
|
||||||
// Ignore require("*.css") calls.
|
// Ignore require("*.css") calls.
|
||||||
|
|
|
@ -3,57 +3,65 @@ const unpkgRewrite = require("../unpkgRewrite");
|
||||||
|
|
||||||
const testCases = [
|
const testCases = [
|
||||||
{
|
{
|
||||||
before: "import React from 'react';",
|
before: 'import React from "react";',
|
||||||
after: "import React from 'https://unpkg.com/react@15.6.1?module';"
|
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:
|
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';",
|
before: 'import map from "lodash.map";',
|
||||||
after: "import map from 'https://unpkg.com/lodash.map@4.6.0?module';"
|
after: 'import map from "https://unpkg.com/lodash.map@4.6.0?module";'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
before: "import fs from 'pn/fs';",
|
before: 'import fs from "pn/fs";',
|
||||||
after: "import fs from 'https://unpkg.com/pn@1.0.0/fs?module';"
|
after: 'import fs from "https://unpkg.com/pn@1.0.0/fs?module";'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
before: "import cupcakes from './cupcakes';",
|
before: 'import cupcakes from "./cupcakes";',
|
||||||
after: "import cupcakes from './cupcakes?module';"
|
after: 'import cupcakes from "./cupcakes?module";'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
before: "import shoelaces from '/shoelaces';",
|
before: 'import shoelaces from "/shoelaces";',
|
||||||
after: "import shoelaces from '/shoelaces?module';"
|
after: 'import shoelaces from "/shoelaces?module";'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
before: "import something from '//something.com/whatevs';",
|
before: 'import something from "//something.com/whatevs";',
|
||||||
after: "import something from '//something.com/whatevs';"
|
after: 'import something from "//something.com/whatevs";'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
before: "import something from 'http://something.com/whatevs';",
|
before: 'import something from "http://something.com/whatevs";',
|
||||||
after: "import something from 'http://something.com/whatevs';"
|
after: 'import something from "http://something.com/whatevs";'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
before: "let ReactDOM = require('react-dom');",
|
before: 'let ReactDOM = require("react-dom");',
|
||||||
after: "let ReactDOM = require('react-dom');"
|
after: 'let ReactDOM = require("react-dom");'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
before: "export React from 'react';",
|
before: 'export React from "react";',
|
||||||
after: "export React from 'https://unpkg.com/react@15.6.1?module';"
|
after: 'export React from "https://unpkg.com/react@15.6.1?module";'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
before: "export { Component } from 'react';",
|
before: 'export { Component } from "react";',
|
||||||
after: "export { Component } from 'https://unpkg.com/react@15.6.1?module';"
|
after: 'export { Component } from "https://unpkg.com/react@15.6.1?module";'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
before: "export * from 'react';",
|
before: 'export * from "react";',
|
||||||
after: "export * from 'https://unpkg.com/react@15.6.1?module';"
|
after: 'export * from "https://unpkg.com/react@15.6.1?module";'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
before: "export var message = 'hello';",
|
before: 'export var message = "hello";',
|
||||||
after: "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", () => {
|
describe("Rewriting imports/exports", () => {
|
||||||
testCases.forEach(testCase => {
|
testCases.forEach(testCase => {
|
||||||
it(`successfully rewrites "${testCase.before}"`, () => {
|
it(`successfully rewrites '${testCase.before}'`, () => {
|
||||||
const result = babel.transform(testCase.before, {
|
const result = babel.transform(testCase.before, {
|
||||||
plugins: [unpkgRewrite(dependencies)]
|
plugins: [unpkgRewrite(dependencies)]
|
||||||
});
|
});
|
||||||
|
|
|
@ -5,40 +5,85 @@ const origin = require("../serverConfig").origin;
|
||||||
|
|
||||||
const bareIdentifierFormat = /^((?:@[^/]+\/)?[^/]+)(\/.*)?$/;
|
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 = {}) {
|
function unpkgRewrite(dependencies = {}) {
|
||||||
return {
|
return {
|
||||||
inherits: require("babel-plugin-syntax-export-extensions"),
|
manipulateOptions(opts, parserOpts) {
|
||||||
|
parserOpts.plugins.push(
|
||||||
|
"dynamicImport",
|
||||||
|
"exportDefaultFrom",
|
||||||
|
"exportNamespaceFrom",
|
||||||
|
"importMeta"
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
visitor: {
|
visitor: {
|
||||||
"ImportDeclaration|ExportNamedDeclaration|ExportAllDeclaration"(path) {
|
CallExpression(path) {
|
||||||
if (!path.node.source) return; // probably a variable declaration
|
if (path.node.callee.type !== "Import") {
|
||||||
|
// Some other function call, not import();
|
||||||
if (
|
return;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
31
package.json
31
package.json
|
@ -7,13 +7,15 @@
|
||||||
"test": "jest"
|
"test": "jest"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"babel-core": "^6.26.3",
|
"@babel/core": "^7.2.0",
|
||||||
"babel-plugin-syntax-export-extensions": "^6.13.0",
|
"@babel/plugin-proposal-class-properties": "^7.2.1",
|
||||||
"babel-plugin-transform-react-remove-prop-types": "^0.4.14",
|
"@babel/plugin-syntax-dynamic-import": "^7.2.0",
|
||||||
"babel-preset-env": "^1.7.0",
|
"@babel/plugin-syntax-export-default-from": "^7.2.0",
|
||||||
"babel-preset-react": "^6.24.1",
|
"@babel/plugin-syntax-export-namespace-from": "^7.2.0",
|
||||||
"babel-preset-stage-2": "^6.24.1",
|
"@babel/plugin-syntax-import-meta": "^7.2.0",
|
||||||
"babel-register": "^6.26.0",
|
"@babel/preset-env": "^7.2.0",
|
||||||
|
"@babel/preset-react": "^7.0.0",
|
||||||
|
"@babel/register": "^7.0.0",
|
||||||
"body-parser": "^1.18.2",
|
"body-parser": "^1.18.2",
|
||||||
"cheerio": "^1.0.0-rc.2",
|
"cheerio": "^1.0.0-rc.2",
|
||||||
"cors": "^2.8.1",
|
"cors": "^2.8.1",
|
||||||
|
@ -47,25 +49,26 @@
|
||||||
"whatwg-url": "^6.4.0"
|
"whatwg-url": "^6.4.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"babel-core": "^7.0.0-bridge.0",
|
||||||
"babel-eslint": "^8.0.3",
|
"babel-eslint": "^8.0.3",
|
||||||
"babel-jest": "^23.4.2",
|
"babel-jest": "^23.4.2",
|
||||||
"babel-loader": "^7.1.2",
|
"babel-loader": "^8.0.4",
|
||||||
"css-loader": "0.26.1",
|
"css-loader": "0.26.1",
|
||||||
"errorhandler": "^1.5.0",
|
"errorhandler": "^1.5.0",
|
||||||
"eslint": "^4.13.1",
|
"eslint": "^4.13.1",
|
||||||
"eslint-plugin-import": "^2.8.0",
|
"eslint-plugin-import": "^2.8.0",
|
||||||
"eslint-plugin-react": "^7.5.1",
|
"eslint-plugin-react": "^7.5.1",
|
||||||
"extract-text-webpack-plugin": "^3.0.2",
|
"file-loader": "^2.0.0",
|
||||||
"file-loader": "0.10.0",
|
"html-loader": "^0.5.5",
|
||||||
"html-loader": "^0.5.1",
|
|
||||||
"jest": "^22.4.4",
|
"jest": "^22.4.4",
|
||||||
"markdown-loader": "^2.0.1",
|
"markdown-loader": "^2.0.1",
|
||||||
|
"mini-css-extract-plugin": "^0.4.5",
|
||||||
"nodemon": "^1.18.3",
|
"nodemon": "^1.18.3",
|
||||||
"style-loader": "0.13.1",
|
"style-loader": "0.13.1",
|
||||||
"supertest": "^3.0.0",
|
"supertest": "^3.0.0",
|
||||||
"url-loader": "0.5.7",
|
"url-loader": "^1.1.2",
|
||||||
"webpack": "^3.10.0",
|
"webpack": "^4.27.1",
|
||||||
"webpack-dev-server": "^2.11.1",
|
"webpack-dev-server": "^3.1.10",
|
||||||
"whatwg-fetch": "2.0.2"
|
"whatwg-fetch": "2.0.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const webpack = require("webpack");
|
const webpack = require("webpack");
|
||||||
const ExtractTextPlugin = require("extract-text-webpack-plugin");
|
const MiniCSSExtractPlugin = require("mini-css-extract-plugin");
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
mode: process.env.NODE_ENV || "development",
|
||||||
|
|
||||||
entry: {
|
entry: {
|
||||||
main: path.resolve(__dirname, "./modules/client/main.js"),
|
main: path.resolve(__dirname, "./modules/client/main.js"),
|
||||||
autoIndex: path.resolve(__dirname, "./modules/client/autoIndex.js")
|
autoIndex: path.resolve(__dirname, "./modules/client/autoIndex.js")
|
||||||
|
@ -25,10 +27,7 @@ module.exports = {
|
||||||
{ test: /\.js$/, exclude: /node_modules/, use: "babel-loader" },
|
{ test: /\.js$/, exclude: /node_modules/, use: "babel-loader" },
|
||||||
{
|
{
|
||||||
test: /\.css$/,
|
test: /\.css$/,
|
||||||
use: ExtractTextPlugin.extract({
|
use: [MiniCSSExtractPlugin.loader, "css-loader"]
|
||||||
fallback: "style-loader",
|
|
||||||
use: "css-loader"
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
{ test: /\.md$/, use: ["html-loader", "markdown-loader"] },
|
{ test: /\.md$/, use: ["html-loader", "markdown-loader"] },
|
||||||
{ test: /\.png$/, use: "file-loader" }
|
{ test: /\.png$/, use: "file-loader" }
|
||||||
|
@ -41,7 +40,7 @@ module.exports = {
|
||||||
process.env.NODE_ENV || "development"
|
process.env.NODE_ENV || "development"
|
||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
new ExtractTextPlugin("[name]-[hash:8].css")
|
new MiniCSSExtractPlugin()
|
||||||
],
|
],
|
||||||
|
|
||||||
devtool:
|
devtool:
|
||||||
|
|
Loading…
Reference in New Issue