Skip to content

Commit

Permalink
Merge pull request #12 from regal/feat/7-bundle-option
Browse files Browse the repository at this point in the history
Implement bundle option
  • Loading branch information
jcowman2 authored Dec 22, 2018
2 parents 180fe25 + ea4c13a commit 87e9fe5
Show file tree
Hide file tree
Showing 12 changed files with 145 additions and 30 deletions.
5 changes: 5 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
"rollup-plugin-node-resolve": "^3.4.0",
"rollup-plugin-terser": "^3.0.0",
"rollup-plugin-typescript2": "^0.18.0",
"rollup-plugin-virtual": "^1.0.1",
"sanitize-filename": "^1.6.1"
},
"devDependencies": {
Expand Down
11 changes: 11 additions & 0 deletions src/bundle-standard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { GameApi } from "regal";

export default (game: GameApi): GameApi => {
return {
getMetadataCommand: game.getMetadataCommand.bind(game),
postPlayerCommand: game.postPlayerCommand.bind(game),
postStartCommand: game.postStartCommand.bind(game),
postUndoCommand: game.postUndoCommand.bind(game),
postOptionCommand: game.postOptionCommand.bind(game)
};
};
52 changes: 42 additions & 10 deletions src/bundle.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { RegalError } from "regal";
import * as rollup from "rollup";
import * as _commonjs from "rollup-plugin-commonjs";
import * as insert from "rollup-plugin-insert";
import * as _json from "rollup-plugin-json";
import * as _resolve from "rollup-plugin-node-resolve";
import { terser } from "rollup-plugin-terser";
import * as _typescript from "rollup-plugin-typescript2";
import * as _virtual from "rollup-plugin-virtual";
import standardBundle from "./bundle-standard";
import { getConfig } from "./get-config";
import { LoadedConfiguration } from "./interfaces-internal";
import { BundlerOptions, RecursivePartial } from "./interfaces-public";
Expand All @@ -14,35 +17,64 @@ const json = _json;
const resolve = _resolve;
const typescript = _typescript;
const commonjs = _commonjs;
const virtual = _virtual;

const esFooter = (metadata: string) => `
import { Game } from "regal";
/** Initialize game **/
const footerCode = (metadata: string) => `
/* Initialize game */
Game.init(${metadata});
export { Game as default };
/* Generate bundle */
const bundledGame = makeBundle(Game);
`;

export const esFooter = (metadata: string) => `
import { Game } from "regal";
import makeBundle from "_bundle";
${footerCode(metadata)}
export { bundledGame as default };
`;

const cjsFooter = (metadata: string) => `
export const cjsFooter = (metadata: string) => `
const Game = require("regal").Game;
/** Initialize game **/
Game.init(${metadata});
module.exports = Game;
const makeBundle = require("_bundle");
${footerCode(metadata)}
module.exports = bundledGame;
`;

export const bundleFooter = (config: LoadedConfiguration) => {
export const makeBundleFooter = (config: LoadedConfiguration) => {
const footer = config.bundler.input.ts ? esFooter : cjsFooter;
return footer(JSON.stringify(config.game, undefined, 2));
};

export const makeBundler = (config: LoadedConfiguration) => {
let bundleFunc: string;

const bundleType = config.bundler.output.bundle;
if (bundleType.toLowerCase() === "standard") {
bundleFunc = standardBundle.toString();
} else {
throw new RegalError(`Illegal bundle type: ${bundleType}`);
}

return {
bundleFooter: makeBundleFooter(config),
bundlePlugin: virtual({
_bundle: `export default ${bundleFunc};`
})
};
};

export const bundleHeader = () => "/** BUNDLED GAME */";

export const getPlugins = (config: LoadedConfiguration): rollup.Plugin[] => {
const plugins: rollup.Plugin[] = [];

const { bundleFooter, bundlePlugin } = makeBundler(config);

plugins.push(
insert.append(bundleFooter(config), {
insert.append(bundleFooter, {
include: config.bundler.input.file
}),
bundlePlugin,
resolve(),
json({ exclude: "node_modules/**" })
);
Expand Down
3 changes: 1 addition & 2 deletions src/get-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import * as _sanitize from "sanitize-filename";
import { LoadedConfiguration } from "./interfaces-internal";
import {
BundlerOptions,
BundleType,
ModuleFormat,
RecursivePartial
} from "./interfaces-public";
Expand Down Expand Up @@ -106,7 +105,7 @@ export const fillInOpts = (
c.output.file = path.join(configLocation, c.output.file);
}
if (c.output.bundle === undefined) {
c.output.bundle = BundleType.STANDARD;
c.output.bundle = "standard";
}
if (c.output.format === undefined) {
c.output.format = ModuleFormat.CJS;
Expand Down
1 change: 0 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,5 @@ export {
BundleConfigInput,
BundleConfigOutput,
RecursivePartial,
BundleType,
ModuleFormat
} from "./interfaces-public";
6 changes: 1 addition & 5 deletions src/interfaces-public.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,11 @@ export interface BundleConfigInput {

export interface BundleConfigOutput {
file: string;
bundle: BundleType;
bundle: string;
format: ModuleFormat;
minify: boolean;
}

export enum BundleType {
STANDARD = "standard"
}

export enum ModuleFormat {
CJS = "cjs",
ESM = "esm",
Expand Down
3 changes: 1 addition & 2 deletions test/cases/basic/basic.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { lines } from "../../test-utils";
import {
getConfig,
bundle,
BundleType,
ModuleFormat
// @ts-ignore: import will be resolved
} from "../../../dist/regal-bundler.cjs.js";
Expand All @@ -27,7 +26,7 @@ describe("Case: Basic", () => {
ts: true
},
output: {
bundle: BundleType.STANDARD,
bundle: "standard",
file: path.join(__dirname, "basic.regal.js"),
format: ModuleFormat.CJS,
minify: false
Expand Down
2 changes: 1 addition & 1 deletion test/cases/minify/minify.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as path from "path";
import * as fs from "fs";
import { GameResponse, GameApi } from "regal";
import { GameApi } from "regal";
import { lines } from "../../test-utils";
import { bundleHeader } from "../../../src/bundle";

Expand Down
3 changes: 2 additions & 1 deletion test/cases/minify/regal.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
"file": "../basic/src/index.ts"
},
"output": {
"minify": true
"minify": true,
"bundle": "standard"
}
}
}
78 changes: 75 additions & 3 deletions test/unit/bundle.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
import { bundle, BundleType, ModuleFormat } from "../../src";
import { bundle, ModuleFormat } from "../../src";
import * as rollup from "rollup";
import { getConfig } from "../../src/get-config";
import { bundleHeader, getPlugins } from "../../src/bundle";
import {
bundleHeader,
getPlugins,
makeBundler,
esFooter
} from "../../src/bundle";
import { LoadedConfiguration } from "../../src/interfaces-internal";
import standardBundle from "../../src/bundle-standard";
import { onStartCommand, onPlayerCommand, Game } from "regal";

jest.mock("rollup");
jest.mock("../../src/get-config");
Expand All @@ -19,7 +26,7 @@ const sampleConfig = () => ({
},
output: {
file: "sample/out",
bundle: BundleType.STANDARD,
bundle: "standard",
format: ModuleFormat.CJS,
minify: false
}
Expand Down Expand Up @@ -110,4 +117,69 @@ describe("Bundle", () => {
expect(plugins.find(p => p.name === "rpt2")).toBeUndefined();
});
});

describe("makeBundler", () => {
it("Returns a standard bundle footer and plugin", () => {
const config = sampleConfig();
config.bundler.output.bundle = "standard";

const { bundleFooter, bundlePlugin } = makeBundler(config);

expect(bundleFooter).toBe(
esFooter(JSON.stringify(config.game, undefined, 2))
);
expect(bundlePlugin.name).toBe("virtual");
});

it("Throws an error if a config other than standard is used", () => {
const config = sampleConfig();
config.bundler.output.bundle = "foo";

expect(() => makeBundler(config)).toThrow(
"RegalError: Illegal bundle type: foo"
);
});
});

describe("Standard Bundle", () => {
beforeAll(() => {
onStartCommand(game => game.output.write("hi"));
onPlayerCommand(cmd => game => game.output.write(cmd));
Game.init({
name: "My Game",
author: "Joe Cowman"
});
});

it("Behaves the same as Regal GameApi", () => {
const bundle = standardBundle(Game);

expect(Game.getMetadataCommand()).toEqual(
bundle.getMetadataCommand()
);

const seed = { seed: "foo" };
const response = bundle.postStartCommand(seed);
expect(Game.postStartCommand(seed)).toEqual(response);

const instance = response.instance;
expect(Game.postPlayerCommand(instance, "1")).toEqual(
bundle.postPlayerCommand(instance, "1")
);
expect(Game.postUndoCommand(instance)).toEqual(
bundle.postUndoCommand(instance)
);

const opt = { debug: true };
expect(Game.postOptionCommand(instance, opt)).toEqual(
bundle.postOptionCommand(instance, opt)
);
});

it("Does not have Game.init or Game.reset", () => {
const bundle = standardBundle(Game) as any;
expect(bundle.init).toBeUndefined;
expect(bundle.reset).toBeUndefined;
});
});
});
10 changes: 5 additions & 5 deletions test/unit/get-config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import * as path from "path";

import * as Config from "../../src/get-config";
import { LoadedConfiguration } from "../../src/interfaces-internal";
import { BundleType, ModuleFormat, RecursivePartial } from "../../src";
import { ModuleFormat, RecursivePartial } from "../../src";

// Mock importing package.json
const pkgRetValue = jest.fn();
Expand Down Expand Up @@ -48,7 +48,7 @@ describe("Get Config", () => {
},
output: {
file: "sample/out",
bundle: BundleType.STANDARD,
bundle: "standard",
format: ModuleFormat.CJS,
minify: true
}
Expand Down Expand Up @@ -126,7 +126,7 @@ describe("Get Config", () => {
},
output: {
file: path.join(process.cwd(), "my-cool-game.regal.js"),
bundle: BundleType.STANDARD,
bundle: "standard",
format: ModuleFormat.CJS,
minify: false
}
Expand All @@ -153,7 +153,7 @@ describe("Get Config", () => {
},
output: {
file: "out.js",
bundle: BundleType.STANDARD,
bundle: "standard",
format: ModuleFormat.ESM,
minify: true
}
Expand Down Expand Up @@ -237,7 +237,7 @@ describe("Get Config", () => {
format: ModuleFormat.ESM,
minify: false,
file: path.join(__dirname, "my-cool-game.regal.js"),
bundle: BundleType.STANDARD
bundle: "standard"
});
});

Expand Down

0 comments on commit 87e9fe5

Please sign in to comment.