Skip to content

Commit

Permalink
chore(build): Add esm, cjs, umd & dist build targets (#14)
Browse files Browse the repository at this point in the history
Added Gulp in order to create build targets for ECMAScript modules (ESM), CommonJS (cjs), Universal Modules (UMD), and dist bundles. This should hopefully be the final step before actually doing an inaugural release.

* ESM - used by modern dependency systems like Webpack or Rollup that can do tree-shaking optimizations
* CJS - used primarily by Node for resolving dependencies
* Dist bundle - used by legacy dependency systems like requireJS
* UMD - Can't think of a good use case where you'd use UMD over the previous 3, but adding it for now for completeness. May get removed in later releases

Was having issues with `lodash` including everything just for `isPlainObject` so I rewrote the code to no longer need it. In the future if we do need `lodash` we should use [`lodash-es`](https://www.npmjs.com/package/lodash-es) (lodash exported as ES modules).

Also changing the package name to be just `eventbrite` instead of `brite-rest`.

Fixes #11
  • Loading branch information
benmvp authored and BenAtEventbrite committed Mar 29, 2018
1 parent ed8df35 commit 6250f55
Show file tree
Hide file tree
Showing 7 changed files with 1,787 additions and 66 deletions.
1 change: 1 addition & 0 deletions .npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ logs

# Test files
**/*.spec.*
**/__tests__/*
6 changes: 4 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,7 @@ node_js:
# Cache dependencies in $HOME/.yarn-cache across builds
cache: yarn

# Run the the validate script with code coverage
script: yarn run validate
# Run the the validate script
# Temporarily also run the build script to make sure it works
# (will move this to the release step once that's implemented)
script: yarn run validate && yarn run build
199 changes: 199 additions & 0 deletions gulpfile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
const gulp = require("gulp");
const babel = require("gulp-babel");
const uglify = require("gulp-uglify");
const rename = require("gulp-rename");
const sourcemaps = require("gulp-sourcemaps");
const replace = require("gulp-replace");
const debug = require("gulp-debug");
const util = require("gulp-util");

const { rollup } = require("rollup");
const rollupBabel = require("rollup-plugin-babel");
const rollupNodeResolve = require("rollup-plugin-node-resolve");
const rollupCommonjs = require("rollup-plugin-commonjs");
const rollupJson = require("rollup-plugin-json");
const rollupReplace = require("rollup-plugin-replace");
const rollupUglify = require("rollup-plugin-uglify");

const FORMAT_ESM = "esm";
const FORMAT_CJS = "cjs";
const FORMAT_UMD = "umd";

const MODULE_NAME = "Eventbrite";

const SOURCE_ENTRY = "src/index.ts";

const FILES_TO_BUILD = [
// include all the JavaScript files in src/ directory
"src/**/*.@(ts|js)",

// but exclude the test files
"!src/**/__tests__/**"
];

// When transpiling to ES format, we still use the `env` preset
// and we want everything transpiled EXCEPT modules
const ESM_ENV_PRESET = ["@babel/env", { modules: false }];

// When transpiling to UMD, we need the UMD transform plugin.
// Need to explicitly list the globals unfortunately
const UMD_TRANSFORM_PLUGIN = [
"@babel/plugin-transform-modules-umd",
{
globals: {
index: MODULE_NAME,
"isomorphic-fetch": "fetch"
},
exactGlobals: true
}
];

const _getBabelConfig = format => ({
babelrc: false,

presets: [
format === FORMAT_ESM ? ESM_ENV_PRESET : "@babel/env",
"@babel/typescript"
],
plugins: [
"@babel/proposal-class-properties",
"@babel/proposal-object-rest-spread",
"@babel/plugin-external-helpers",
...(format === FORMAT_UMD ? [UMD_TRANSFORM_PLUGIN] : [])
]
});

const _getBabelStream = format =>
gulp
// get a stream of the files to transpile
.src(FILES_TO_BUILD)
// initialize the sourcemaps (used by UMD only)
.pipe(format === FORMAT_UMD ? sourcemaps.init() : util.noop())
// do the appropriate babel transpile (this is a copy from package.json)
.pipe(babel(_getBabelConfig(format)));

const _genUmd = ({ minify = false } = {}) =>
_getBabelStream(FORMAT_UMD)
// If you're using UMD, you probably don't have `process.env.NODE_ENV` so, we'll replace it.
// If you're using the unminified UMD, you're probably in DEV
// If you're using the unminified UMD, you're probably in production
.pipe(
replace(
"process.env.NODE_ENV",
JSON.stringify(minify ? "production" : "development")
)
)
// minify the files and rename to .min.js extension (when minifying)
.pipe(minify ? uglify() : util.noop())
.pipe(minify ? rename({ extname: ".min.js" }) : util.noop())
.pipe(sourcemaps.write("./"))
.pipe(
debug({
title: minify ? "Building + Minifying UMD:" : "Building UMD:"
})
)
.pipe(gulp.dest("lib/umd"));

const _genDist = ({ minify = false } = {}) =>
rollup({
input: SOURCE_ENTRY,

plugins: [
// Need to replace `process.env.NODE_ENV` in the bundle because most likely the place where this
// would be used doesn't support it. When minified we assume production, dev otherwise
rollupReplace({
"process.env.NODE_ENV": JSON.stringify(
minify ? "production" : "development"
)
}),

// convert JSON files to ES6 modules, so they can be included in Rollup bundle
rollupJson(),

// Locate modules using the Node resolution algorithm, for using third party modules in node_modules
rollupNodeResolve({
// use "module" field for ES6 module if possible
module: true,

// use (legacy) "jsnext:main" if possible
jsnext: true,

// use "main" field or index.(ts|js)
main: true,

// use "browser" field if possible
browser: true,

// include typescript files as default extensions
extensions: [".ts", ".js"]
}),

// Convert CommonJS modules to ES6 modules, so they can be included in a Rollup bundle
rollupCommonjs({
// Node modules are the ones we're trying to get it to understand
include: "node_modules/**"
}),

// Seamless integration between Rollup and Babel
rollupBabel(
Object.assign(
{
// don't worry about transpiling node_modules when bundling
exclude: "node_modules/**",

// don't place helpers at the top of the files, but point to reference contained external helpers
externalHelpers: true
},
_getBabelConfig(FORMAT_ESM)
)
),

// Minify the code if that option is specified
// `false` will get filtered out below
minify && rollupUglify()
].filter(Boolean)
}).then(bundle => {
bundle.write({
format: FORMAT_UMD,
file: `dist/eventbrite${minify ? ".min" : ""}.js`,

// The name to use for dist bundle
name: MODULE_NAME,

sourcemap: true
});
});

// Used by modern dependency systems like Webpack or Rollup that can do tree-shaking
gulp.task("build:lib:esm", () =>
_getBabelStream(FORMAT_ESM)
.pipe(debug({ title: "Building ESM:" }))
.pipe(gulp.dest("lib/esm"))
);

// Used primarily by Node for resolving dependencies
gulp.task("build:lib:cjs", () =>
_getBabelStream(FORMAT_CJS)
.pipe(debug({ title: "Building CJS" }))
.pipe(gulp.dest("lib/cjs"))
);

// Used by legacy dependency systems like requireJS
gulp.task("build:dist", () => _genDist());
gulp.task("build:dist:min", () => _genDist({ minify: true }));

// Unclear what would use this over the previous 3, but keeping for now
// May get removed in later releases
gulp.task("build:lib:umd", () => _genUmd());
gulp.task("build:lib:umd:min", () => _genUmd({ minify: true }));

gulp.task("build:lib", [
"build:lib:esm",
"build:lib:cjs",
"build:lib:umd",
"build:lib:umd:min"
]);

gulp.task("build", ["build:lib", "build:dist", "build:dist:min"]);

gulp.task("default", ["build"]);
38 changes: 27 additions & 11 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
{
"name": "brite-rest",
"name": "eventbrite",
"version": "0.0.0-semantically-released",
"description": "The official JavaScript SDK for the Eventbrite v3 API",
"author": "Eventbrite <[email protected]>",
"main": "lib/cjs/index.js",
"module": "lib/esm/index.js",
"jsnext:main": "lib/esm/index.js",
"browser": "dist/brite-rest.js",
"types": "lib/cjs/index.d.ts",
"browser": "dist/eventbrite.js",
"types": "lib/index.d.ts",
"keywords": [
"rest",
"api",
Expand All @@ -30,13 +30,14 @@
"format": "prettier-eslint --write",
"lint": "eslint --cache --max-warnings 0 --ext .ts,.js src",
"precommit": "lint-staged",
"test": "jest --config=jest.json",
"test:watch": "yarn test --watch",
"build": "npm-run-all --parallel build:declarations build:transpile",
"build:declarations": "tsc --p ./tsconfig.build.json",
"build:transpile": "babel src --ignore **/*.spec.ts --out-dir lib/cjs --extensions \".ts,.tsx\"",
"gen:declarations": "tsc --p ./tsconfig.build.json",
"build": "npm-run-all build:targets gen:declarations",
"build:targets": "gulp build",
"prebuild:targets": "rm -rf dist && rm -rf lib",
"tsc": "tsc",
"test": "jest --config=jest.json",
"test:ci": "yarn test --ci",
"test:watch": "yarn test --watch",
"validate": "npm-run-all --parallel check:static test:ci"
},
"lint-staged": {
Expand All @@ -46,34 +47,49 @@
]
},
"dependencies": {
"isomorphic-fetch": "^2.2.1",
"lodash": "^4.17.5"
"isomorphic-fetch": "^2.2.1"
},
"resolutions": {
"babel-core": "^7.0.0-bridge.0"
},
"devDependencies": {
"@babel/cli": "^7.0.0-beta.40",
"@babel/core": "^7.0.0-beta.40",
"@babel/plugin-external-helpers": "^7.0.0-beta.40",
"@babel/plugin-proposal-class-properties": "^7.0.0-beta.40",
"@babel/plugin-proposal-object-rest-spread": "^7.0.0-beta.40",
"@babel/plugin-transform-modules-umd": "^7.0.0-beta.40",
"@babel/preset-env": "^7.0.0-beta.40",
"@babel/preset-typescript": "^7.0.0-beta.40",
"@types/isomorphic-fetch": "^0.0.34",
"@types/jest": "^22.1.3",
"@types/lodash": "^4.14.104",
"@types/node": "^9.4.6",
"babel-eslint": "^7.0.0",
"eslint": "^3.0.0",
"eslint-config-eventbrite": "^4.1.0",
"eslint-plugin-import": "^2.0.0",
"eslint-plugin-typescript": "^0.9.0",
"gulp": "^3.9.1",
"gulp-babel": "^7.0.1",
"gulp-debug": "^3.2.0",
"gulp-rename": "^1.2.2",
"gulp-replace": "^0.6.1",
"gulp-sourcemaps": "^2.6.4",
"gulp-uglify": "^3.0.0",
"husky": "^0.14.3",
"jest": "^22.4.0",
"lint-staged": "^6.1.0",
"node": "^8.9.2",
"npm-run-all": "^4.1.2",
"prettier-eslint-cli": "^4.7.1",
"rollup": "^0.56.3",
"rollup-plugin-babel": "^4.0.0-beta.2",
"rollup-plugin-commonjs": "^8.3.0",
"rollup-plugin-json": "^2.3.0",
"rollup-plugin-node-resolve": "^3.0.3",
"rollup-plugin-replace": "^2.0.0",
"rollup-plugin-typescript": "^0.8.1",
"rollup-plugin-uglify": "^3.0.0",
"typescript": "^2.7.2",
"typescript-babel-jest": "^1.0.5",
"typescript-eslint-parser": "^14.0.0"
Expand Down
7 changes: 4 additions & 3 deletions src/request.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import {isPlainObject} from 'lodash';
import {JSONResponseData, ParsedResponseError} from './types';
import 'isomorphic-fetch';

Expand Down Expand Up @@ -53,8 +52,10 @@ export const fetchJSON = (
};

const hasArgumentsError = (responseData: JSONResponseData): boolean =>
isPlainObject(responseData['error_detail']) &&
isPlainObject(responseData['error_detail']['ARGUMENTS_ERROR']);
!!(
responseData['error_detail'] &&
responseData['error_detail']['ARGUMENTS_ERROR']
);

/**
* Parse v3 errors into an array of objects representing the errors returned by
Expand Down
4 changes: 1 addition & 3 deletions tsconfig.build.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,5 @@
"emitDeclarationOnly": true,
"noEmit": false
},
"exclude": [
"**/*.spec.ts"
]
"exclude": ["**/__tests__"]
}
Loading

0 comments on commit 6250f55

Please sign in to comment.