From a0d1479edd252654cafb4a557ddd9c67852654d1 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 9 Jan 2018 21:41:19 -0800 Subject: [PATCH] Inline babel-plugin-unpkg-rewrite --- package.json | 5 +- server/middleware/serveFile.js | 6 +- .../__tests__/unpkgRewriteBabelPlugin-test.js | 76 +++++++++++++++++++ .../utils/unpkgRewriteBabelPlugin.js | 44 +++++++++++ yarn.lock | 32 +++++--- 5 files changed, 151 insertions(+), 12 deletions(-) create mode 100644 server/middleware/utils/__tests__/unpkgRewriteBabelPlugin-test.js create mode 100644 server/middleware/utils/unpkgRewriteBabelPlugin.js diff --git a/package.json b/package.json index 944a614..e6bdcab 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "test": "jest" }, "dependencies": { - "babel-plugin-unpkg-rewrite": "^3.6.0", + "babel-plugin-syntax-export-extensions": "^6.13.0", "babel-preset-env": "^1.6.1", "babel-preset-react": "^6.24.1", "body-parser": "^1.18.2", @@ -40,7 +40,8 @@ "tar-fs": "^1.15.2", "throng": "^4.0.0", "validate-npm-package-name": "^3.0.0", - "warning": "^3.0.0" + "warning": "^3.0.0", + "whatwg-url": "^6.4.0" }, "devDependencies": { "babel-core": "^6.26.0", diff --git a/server/middleware/serveFile.js b/server/middleware/serveFile.js index c325146..c3c87e8 100644 --- a/server/middleware/serveFile.js +++ b/server/middleware/serveFile.js @@ -2,10 +2,10 @@ const fs = require("fs") const path = require("path") const etag = require("etag") const babel = require("babel-core") -const unpkgRewrite = require("babel-plugin-unpkg-rewrite") const getMetadata = require("./utils/getMetadata") const getFileContentType = require("./utils/getFileContentType") const getIndexHTML = require("./utils/getIndexHTML") +const unpkgRewrite = require("./utils/unpkgRewriteBabelPlugin") /** * Automatically generate HTML pages that show package contents. @@ -37,6 +37,7 @@ function serveFile(req, res) { getMetadata(req.packageDir, req.filename, req.stats, MaximumDepth, (error, metadata) => { if (error) { console.error(error) + res .status(500) .type("text") @@ -64,12 +65,14 @@ function serveFile(req, res) { rewriteBareModuleIdentifiers(file, req.packageConfig, (error, code) => { if (error) { console.error(error) + const debugInfo = error.constructor.name + ": " + error.message.replace(/^.*?\/unpkg-.+?\//, `/${req.packageSpec}/`) + "\n\n" + error.codeFrame + res .status(500) .type("text") @@ -129,6 +132,7 @@ function serveFile(req, res) { }, error => { console.error(error) + res .status(500) .type("text") diff --git a/server/middleware/utils/__tests__/unpkgRewriteBabelPlugin-test.js b/server/middleware/utils/__tests__/unpkgRewriteBabelPlugin-test.js new file mode 100644 index 0000000..7f21220 --- /dev/null +++ b/server/middleware/utils/__tests__/unpkgRewriteBabelPlugin-test.js @@ -0,0 +1,76 @@ +const babel = require("babel-core") +const unpkgRewrite = require("../unpkgRewriteBabelPlugin") + +const testCases = [ + { + before: "import React from 'react';", + after: "import React from 'https://unpkg.com/react@15.6.1?module';" + }, + { + before: "import router from '@angular/router';", + after: "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 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 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 '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: "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 * from 'react';", + after: "export * from 'https://unpkg.com/react@15.6.1?module';" + }, + { + before: "export var message = 'hello';", + after: "export var message = 'hello';" + } +] + +const dependencies = { + react: "15.6.1", + "@angular/router": "4.3.5", + "lodash.map": "4.6.0", + pn: "1.0.0" +} + +describe("Rewriting imports/exports", () => { + testCases.forEach(testCase => { + it(`successfully rewrites "${testCase.before}"`, () => { + const result = babel.transform(testCase.before, { + plugins: [unpkgRewrite(dependencies)] + }) + + expect(result.code).toEqual(testCase.after) + }) + }) +}) diff --git a/server/middleware/utils/unpkgRewriteBabelPlugin.js b/server/middleware/utils/unpkgRewriteBabelPlugin.js new file mode 100644 index 0000000..5059c61 --- /dev/null +++ b/server/middleware/utils/unpkgRewriteBabelPlugin.js @@ -0,0 +1,44 @@ +const URL = require("whatwg-url") +const warning = require("warning") + +const BareIdentifierFormat = /^((?:@[^\/]+\/)?[^\/]+)(\/.*)?$/ + +function unpkgRewriteBabelPlugin(dependencies = {}) { + return { + inherits: require("babel-plugin-syntax-export-extensions"), + + 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" + + path.node.source.value = `https://unpkg.com/${packageName}@${version}${file}?module` + } + } + } + } +} + +module.exports = unpkgRewriteBabelPlugin diff --git a/yarn.lock b/yarn.lock index 3b908bb..601c2aa 100644 --- a/yarn.lock +++ b/yarn.lock @@ -857,14 +857,6 @@ babel-plugin-transform-strict-mode@^6.24.1: babel-runtime "^6.22.0" babel-types "^6.24.1" -babel-plugin-unpkg-rewrite@^3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/babel-plugin-unpkg-rewrite/-/babel-plugin-unpkg-rewrite-3.6.0.tgz#3fe5fc6895b7a375bf9405faa079856a1b81de49" - dependencies: - babel-plugin-syntax-export-extensions "^6.13.0" - warning "^3.0.0" - whatwg-url "^4.3.0" - babel-preset-env@^1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.6.1.tgz#a18b564cc9b9afdf4aae57ae3c1b0d99188e6f48" @@ -4040,6 +4032,10 @@ lodash.once@^4.0.0: version "4.1.1" resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" +lodash.sortby@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" + lodash.toarray@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/lodash.toarray/-/lodash.toarray-4.4.0.tgz#24c4bfcd6b2fba38bfd0594db1179d8e9b656561" @@ -5179,6 +5175,10 @@ punycode@^1.2.4, punycode@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" +punycode@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.0.tgz#5f863edc89b96db09074bad7947bf09056ca4e7d" + q@^1.1.2: version "1.5.1" resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" @@ -6220,6 +6220,12 @@ tough-cookie@^2.3.2, tough-cookie@~2.3.0, tough-cookie@~2.3.3: dependencies: punycode "^1.4.1" +tr46@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" + dependencies: + punycode "^2.1.0" + tr46@~0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" @@ -6464,7 +6470,7 @@ webidl-conversions@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" -webidl-conversions@^4.0.0: +webidl-conversions@^4.0.0, webidl-conversions@^4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" @@ -6576,6 +6582,14 @@ whatwg-url@^4.3.0: tr46 "~0.0.3" webidl-conversions "^3.0.0" +whatwg-url@^6.4.0: + version "6.4.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-6.4.0.tgz#08fdf2b9e872783a7a1f6216260a1d66cc722e08" + dependencies: + lodash.sortby "^4.7.0" + tr46 "^1.0.0" + webidl-conversions "^4.0.1" + whet.extend@~0.9.9: version "0.9.9" resolved "https://registry.yarnpkg.com/whet.extend/-/whet.extend-0.9.9.tgz#f877d5bf648c97e5aa542fadc16d6a259b9c11a1"