From 151de2bdfb39bc4786b7a07e1e116a5690df6b94 Mon Sep 17 00:00:00 2001 From: Timothy Gu Date: Sat, 14 Jan 2017 20:50:10 -0800 Subject: [PATCH] Use ES2015 export syntax (#212) * Implement Rollup's external module check * Use ES2015 export syntax More friendly to ES2015 environments. --- .babelrc | 12 +++++------ build/babel-plugin.js | 48 ++++++++++++++++++++++++++++++++++++++++++ build/rollup-plugin.js | 16 ++++++++++++++ package.json | 3 ++- rollup.config.js | 14 ++++++++++-- src/index.js | 12 +++++------ test/test.js | 18 ++++++++++------ 7 files changed, 101 insertions(+), 22 deletions(-) create mode 100644 build/babel-plugin.js create mode 100644 build/rollup-plugin.js diff --git a/.babelrc b/.babelrc index 3cd9d25..f2845f2 100644 --- a/.babelrc +++ b/.babelrc @@ -6,6 +6,10 @@ "test": { "presets": [ [ "es2015", { "loose": true } ] + ], + "plugins": [ + "transform-runtime", + "./build/babel-plugin" ] }, "coverage": { @@ -13,12 +17,8 @@ [ "es2015", { "loose": true } ] ], "plugins": [ - [ "istanbul", { - "exclude": [ - "src/blob.js", - "test" - ] - } ] + [ "istanbul", { "exclude": [ "src/blob.js", "build", "test" ] } ], + "./build/babel-plugin" ] }, "rollup": { diff --git a/build/babel-plugin.js b/build/babel-plugin.js new file mode 100644 index 0000000..08efac9 --- /dev/null +++ b/build/babel-plugin.js @@ -0,0 +1,48 @@ +// This Babel plugin makes it possible to do CommonJS-style function exports + +const walked = Symbol('walked'); + +module.exports = ({ types: t }) => ({ + visitor: { + Program: { + exit(program) { + if (program[walked]) { + return; + } + + for (let path of program.get('body')) { + if (path.isExpressionStatement()) { + const expr = path.get('expression'); + if (expr.isAssignmentExpression() && + expr.get('left').matchesPattern('exports.*')) { + const prop = expr.get('left').get('property'); + if (prop.isIdentifier({ name: 'default' })) { + program.unshiftContainer('body', [ + t.expressionStatement( + t.assignmentExpression('=', + t.identifier('exports'), + t.assignmentExpression('=', + t.memberExpression( + t.identifier('module'), t.identifier('exports') + ), + expr.node.right + ) + ) + ), + t.expressionStatement( + t.assignmentExpression('=', + expr.node.left, t.identifier('exports') + ) + ) + ]); + path.remove(); + } + } + } + } + + program[walked] = true; + } + } + } +}); diff --git a/build/rollup-plugin.js b/build/rollup-plugin.js new file mode 100644 index 0000000..411d677 --- /dev/null +++ b/build/rollup-plugin.js @@ -0,0 +1,16 @@ +export default function tweakDefault() { + return { + transformBundle: function (source) { + var lines = source.split('\n'); + for (var i = 0; i < lines.length; i++) { + var line = lines[i]; + var matches = /^exports\['default'] = (.*);$/.exec(line); + if (matches) { + lines[i] = 'module.exports = exports = ' + matches[1] + ';'; + break; + } + } + return lines.join('\n'); + } + }; +} diff --git a/package.json b/package.json index d69dd48..84a8909 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "lib/index.es.js" ], "scripts": { - "build": "rollup -c", + "build": "cross-env BABEL_ENV=rollup rollup -c", "prepublish": "npm run build", "test": "cross-env BABEL_ENV=test mocha --compilers js:babel-register test/test.js", "report": "cross-env BABEL_ENV=coverage nyc --reporter lcov --reporter text mocha -R spec test/test.js", @@ -43,6 +43,7 @@ "codecov": "^1.0.1", "cross-env": "2.0.1", "form-data": ">=1.0.0", + "is-builtin-module": "^1.0.0", "mocha": "^3.1.2", "nyc": "^10.0.0", "parted": "^0.1.1", diff --git a/rollup.config.js b/rollup.config.js index 4a57423..3e3ed20 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -1,5 +1,7 @@ +import isBuiltin from 'is-builtin-module'; import babel from 'rollup-plugin-babel'; import resolve from 'rollup-plugin-node-resolve'; +import tweakDefault from './build/rollup-plugin'; process.env.BABEL_ENV = 'rollup'; @@ -8,10 +10,18 @@ export default { plugins: [ babel({ runtimeHelpers: true - }) + }), + tweakDefault() ], targets: [ { dest: 'lib/index.js', format: 'cjs' }, { dest: 'lib/index.es.js', format: 'es' } - ] + ], + external: function (id) { + if (isBuiltin(id)) { + return true; + } + id = id.split('/').slice(0, id[0] === '@' ? 2 : 1).join('/'); + return !!require('./package.json').dependencies[id]; + } }; diff --git a/src/index.js b/src/index.js index e9f2d55..ef668b8 100644 --- a/src/index.js +++ b/src/index.js @@ -24,7 +24,7 @@ import FetchError from './fetch-error'; * @param Object opts Fetch options * @return Promise */ -function fetch(url, opts) { +export default function fetch(url, opts) { // allow custom promise if (!fetch.Promise) { @@ -189,8 +189,6 @@ function fetch(url, opts) { }; -module.exports = fetch; - /** * Redirect code matching * @@ -210,6 +208,8 @@ fetch.Promise = global.Promise; * objects; existing objects are not affected. */ fetch.FOLLOW_SPEC = false; -fetch.Response = Response; -fetch.Headers = Headers; -fetch.Request = Request; +export { + Headers, + Request, + Response +}; diff --git a/test/test.js b/test/test.js index ae4972b..df0c6ff 100644 --- a/test/test.js +++ b/test/test.js @@ -23,10 +23,14 @@ const expect = chai.expect; import TestServer from './server'; // test subjects -import fetch from '../src/index.js'; -import Headers from '../src/headers.js'; -import Response from '../src/response.js'; -import Request from '../src/request.js'; +import fetch, { + Headers, + Request, + Response +} from '../src/'; +import HeadersOrig from '../src/headers.js'; +import RequestOrig from '../src/request.js'; +import ResponseOrig from '../src/response.js'; import Body from '../src/body.js'; import Blob from '../src/blob.js'; import FetchError from '../src/fetch-error.js'; @@ -93,9 +97,9 @@ describe(`node-fetch with FOLLOW_SPEC = ${defaultFollowSpec}`, () => { }); it('should expose Headers, Response and Request constructors', function() { - expect(fetch.Headers).to.equal(Headers); - expect(fetch.Response).to.equal(Response); - expect(fetch.Request).to.equal(Request); + expect(Headers).to.equal(HeadersOrig); + expect(Response).to.equal(ResponseOrig); + expect(Request).to.equal(RequestOrig); }); (supportToString ? it : it.skip)('should support proper toString output for Headers, Response and Request objects', function() {