Skip to content

Commit

Permalink
extracted ESNext transpilation into separate plugin
Browse files Browse the repository at this point in the history
this resolves the dependencies-management issue (cf. previous commit;
69a2bc2)

opting into features like this is pretty much why we designed extensible
configuration the way we did

creating a separate repository for this plugin didn't seem warranted and
would have complicated testing
  • Loading branch information
FND committed Jul 5, 2020
1 parent 69a2bc2 commit c2f9f8b
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 39 deletions.
12 changes: 0 additions & 12 deletions lib/config/mapping.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
"use strict";

let generateTranspiler = require("./babel");
let { Plugin } = require("./plugin");
let { warn, raise, ValidationError } = require("../util");

Expand Down Expand Up @@ -38,13 +37,6 @@ let NAMELESS_FORMATS = new Set(["es", "amd", "cjs"]); // NB: Rollup identifiers
// `extensions` (optional; depends on `resolve`) is a list of additional file
// extensions for implicit module resolution (e.g. `[".wasm"]`)
//
// `esnext` (boolean or object) activates ESNext transpilation if truthy
// * `esnext.browsers` (optional) is an array of Browserslist queries (e.g.
// `["> 1%", "last 2 versions"]`) to determine which features are transpiled
// * `esnext.exclude` is a list of modules for which to skip transpilation
// (e.g. `exclude: ["jquery"]`, perhaps due to a distribution already
// optimized for ES5)
//
// `commonJS` (boolean or glob) activates support for importing CommonJS modules
// limited to `node_modules` directory unless a custom glob pattern is specified
//
Expand All @@ -59,7 +51,6 @@ exports.generateConfig = function generateConfig(entryPoint, {
sourcemaps,
resolve,
extensions = [],
esnext,
commonjs,
treeshaking,
parser
Expand Down Expand Up @@ -91,9 +82,6 @@ exports.generateConfig = function generateConfig(entryPoint, {
include: commonjs === true ? defaultGlob : commonjs
}));
}
if(esnext) {
plugins.push(generateTranspiler(esnext));
}

format = MODULE_FORMATS[format.toLowerCase()] ||
raise(`unrecognized module format: \`${format}\``, ValidationError,
Expand Down
13 changes: 10 additions & 3 deletions lib/config/plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,28 @@
let { loadExtension } = require("../util");

exports.Plugin = class Plugin {
constructor(id, ref, config = null) {
constructor(id, ref, config = null, supplier = null) {
this.id = id;
this.ref = ref;
this.config = config;
if(supplier) {
this.supplier = supplier;
}
}

init() {
let { ref, config } = this;
// lazy loading
if(ref.substr) {
ref = loadExtension(ref, `plugin \`${this.id}\``);
ref = this._load(ref);
} else if(ref.module && ref.import) {
ref = loadExtension(ref.module, `plugin \`${this.id}\``)[ref.import];
ref = this._load(ref.module)[ref.import];
}

return config === null ? ref : ref(config);
}

_load(pkg) {
return loadExtension(pkg, `plugin \`${this.id}\``, this.supplier);
}
};
8 changes: 3 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "beatdown",
"version": "1.0.1",
"version": "1.0.2",
"description": "simplified JavaScript module bundling",
"author": "FND",
"license": "Apache-2.0",
Expand All @@ -22,14 +22,12 @@
"node": ">=10"
},
"dependencies": {
"rollup": "^2.18.1"
"rollup": "^2.19.0"
},
"devDependencies": {
"@babel/core": "^7.10.3",
"@babel/preset-env": "^7.10.3",
"@rollup/plugin-babel": "^5.0.4",
"@rollup/plugin-commonjs": "^13.0.0",
"@rollup/plugin-node-resolve": "^8.1.0",
"beatdown-esnext": "file:./pkg/esnext",
"eslint-config-fnd": "^1.8.0",
"mocha": "^8.0.1",
"npm-run-all": "^4.1.5",
Expand Down
31 changes: 22 additions & 9 deletions lib/config/babel.js → pkg/esnext/index.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
"use strict";

let { Plugin } = require("./plugin");
let { report } = require("../util");
let { Plugin } = require("beatdown/lib/config/plugin");
let { report } = require("beatdown/lib/util");

let PRESET_ENV = "@babel/preset-env";

//* `browsers` (optional) is an array of Browserslist queries (e.g.
// `["> 1%", "last 2 versions"]`) to determine which features are transpiled
//* `exclude` (optional) is a list of modules for which to skip transpilation
// (e.g. `exclude: ["jquery"]`, perhaps due to the respective library's
// distribution already being optimized for ES5)
module.exports = function generateTranspiler({ browsers, exclude }) {
if(browsers && browsers.length) {
report("transpiling JavaScript for", browsers.join(", "));
}
return new Plugin("babel", {
// FIXME: @babel/core and @babel/preset-env are additional dependencies
module: "@rollup/plugin-babel",
import: "default"
}, {

let config = {
babelHelpers: "bundled",
presets: [
["@babel/preset-env", {
[PRESET_ENV, {
modules: false,
...(browsers && {
targets: { browsers }
Expand All @@ -30,5 +34,14 @@ module.exports = function generateTranspiler({ browsers, exclude }) {
return /^\.{0,2}\//.test(pkg) ? pkg : `node_modules/${pkg}/**`;
})
})
});
};

let plugin = new Plugin("babel", {
module: "@rollup/plugin-babel",
import: "default"
}, config, "beatdown-babel");
// ensure controlled error handling for implicit dependency
plugin._load(PRESET_ENV);

return plugin;
};
22 changes: 22 additions & 0 deletions pkg/esnext/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"name": "beatdown-esnext",
"version": "1.0.0",
"description": "simplified JavaScript module bundling",
"author": "FND",
"license": "Apache-2.0",
"homepage": "https://www.faucet-pipeline.org",
"repository": {
"type": "git",
"url": "https://github.com/faucet-pipeline/beatdown.git"
},
"bugs": {
"url": "https://github.com/faucet-pipeline/beatdown/issues"
},
"main": "index.js",
"dependencies": {
"@babel/core": "^7.10.4",
"@babel/preset-env": "^7.10.4",
"@rollup/plugin-babel": "^5.0.4",
"beatdown": "1.0.2"
}
}
20 changes: 10 additions & 10 deletions test/test_transpiling.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* global suite, test */
"use strict";

let generateTranspiler = require("../pkg/esnext");
let { Bundle } = require("../lib/bundle");
let { Config } = require("../lib/config");
let { FIXTURES_DIR, fixturePath } = require("./util");
Expand All @@ -17,7 +18,7 @@ let warn = (...msg) => console.error(...msg);let lipsum = lang => \`[$\{lang}] l
`.trim());
/* eslint-enable max-len */

bundle = makeBundle("./index.esnext.js", { esnext: true });
bundle = makeBundle("./index.esnext.js", {});
code = await bundle.compile();
assertSame(code, `
var warn = function warn() {
Expand All @@ -34,9 +35,7 @@ var warn = function warn() {

test("Browserslist support", async () => {
let bundle = makeBundle("./index.esnext.js", {
esnext: {
browsers: ["current Node"]
}
browsers: ["current Node"]
});
let code = await bundle.compile();
/* eslint-disable max-len */
Expand All @@ -50,9 +49,7 @@ test("selectively skipping transpilation", async () => {
let cwd = process.cwd();
process.chdir(FIXTURES_DIR); // FIXME: smell
let bundle = makeBundle("./index.esnext.js", {
esnext: {
exclude: ["mylib"]
}
exclude: ["mylib"]
});
let code = await bundle.compile();
process.chdir(cwd);
Expand All @@ -69,11 +66,14 @@ var warn = function warn() {
/* eslint-enable max-len */
});

function makeBundle(entryPoint, options) {
function makeBundle(entryPoint, esnext) {
let config = new Config(fixturePath(entryPoint), {
compact: true,
resolve: true,
...options
resolve: true
});
if(esnext) {
let plugin = generateTranspiler(esnext);
config.addPlugin(plugin);
}
return new Bundle(config);
}

0 comments on commit c2f9f8b

Please sign in to comment.