Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ jobs:
matrix:
node-version:
- 14.x
- 16.x
- 17.x
- 18.x
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
Expand Down
13 changes: 0 additions & 13 deletions greenkeeper.json

This file was deleted.

51 changes: 0 additions & 51 deletions lib/bundle/babel.js

This file was deleted.

29 changes: 0 additions & 29 deletions lib/bundle/basic.js

This file was deleted.

172 changes: 50 additions & 122 deletions lib/bundle/config.js
Original file line number Diff line number Diff line change
@@ -1,33 +1,28 @@
/* eslint-disable object-curly-newline */
"use strict";

let generateTranspiler = require("./babel");
let { loadExtension, abort, repr } = require("faucet-pipeline-core/lib/util");
let { determinePlugins } = require("./plugins");
let { abort, repr } = require("faucet-pipeline-core/lib/util");
let commonjs = require("@rollup/plugin-commonjs");
let { nodeResolve } = require("@rollup/plugin-node-resolve");

let MODULE_FORMATS = { // maps faucet identifiers to Rollup identifiers
esm: true,
es: "esm", // alias
es6: "esm", // alias
umd: true,
amd: true,
commonjs: "cjs",
cjs: false, // deprecated in favor of `commonjs`
iife: true
};
let NAMELESS_MODULES = new Set(["es", "amd", "cjs"]); // NB: Rollup identifiers
let MODULE_FORMATS = new Map([ // maps faucet identifiers to Rollup identifiers
["esm", "esm"],
["umd", "umd"],
["amd", "amd"],
["commonjs", "cjs"],
["iife", "iife"]
]);
let NAMELESS_MODULES = new Set(["esm", "amd", "commonjs"]);

module.exports = generateConfig;

// generates Rollup configuration
// * `extensions` is a list of additional file extensions for loading modules
// (e.g. `[".jsx"]`)
// * `externals` determines which modules/packages to exclude from the bundle
// (e.g. `{ jquery: "jQuery" }` - the key refers to the respective
// module/package name, the value refers to a corresponding global variable)
// * `format` determines the bundle format: ES, UMD, AMD, CommonJS or IIFE
// (case-insensitive, defaults to IIFE)
// * `format` determines the bundle format: ESM, UMD, AMD, CommonJS or IIFE
// (case-insensitive, defaults to ESM)
// * `exports` determines the bundle's API, as per the entry point's exported
// value (if any)
// * `esnext`, if truthy, activates ESNext transpilation
Expand All @@ -47,138 +42,71 @@ module.exports = generateConfig;
// * `sourcemaps`, if truthy, activates inline source-map generation
// * `compact`, if truthy, compresses the bundle's code - see `determineCompacting`
// for compression levels, determined by the respective value
function generateConfig({ extensions = [], // eslint-disable-next-line indent
externals, format, exports, // eslint-disable-next-line indent
function generateConfig({ externals, format, exports, // eslint-disable-next-line indent
esnext, jsx, typescript, // eslint-disable-next-line indent
sourcemaps, sourcemap, compact }, { browsers }) {
if(sourcemap !== undefined) { // for backwards compatibility (explicit error)
abort(`ERROR: ${repr("sourcemap", false)} has been deprecated in ` +
`favor of ${repr("sourcemaps", false)}`);
}

let cfg = { sourcemap: sourcemaps };
let plugins = [];

if(esnext || jsx) {
let transpiler = Object.assign({}, esnext, jsx);
if(esnext) {
transpiler.esnext = true;
}
if(jsx) {
// just to be safe, discard JSX-specifics on parent object
delete transpiler.pragma;
delete transpiler.fragment;

transpiler.jsx = selectiveAssign({}, {
pragma: jsx.pragma,
pragmaFrag: jsx.fragment
});
}

let { browserslist } = transpiler;
browsers = browserslist === false ? null : browsers[browserslist || "defaults"];
if(browsers && browsers.length) {
console.error("transpiling JavaScript for", browsers.join(", "));
}

let { plugin, extensions: ext } = generateTranspiler(transpiler, { browsers });
extensions = ext.concat(extensions);
plugins.push(plugin);
}
if(typescript) {
let ts = loadExtension("@rollup/plugin-typescript",
"failed to activate TypeScript", "faucet-pipeline-typescript");
extensions.push(".ts");
// TODO: provide defaults and abstractions for low-level options?
plugins.push(typescript === true ? ts() : ts(typescript));
}

let resolve = {
// NB: `jsnext:main` retained for backwards compatibility
mainFields: ["module", "jsnext:main", "main"]
sourcemaps, compact }, { browsers }) {
let plugins = [
nodeResolve({ extensions: determineExtensions(jsx, typescript) }),
commonjs({ include: "node_modules/**" }),
...determinePlugins({
esnext,
typescript,
jsx,
sourcemaps,
browsers,
compact
})
];

let config = {
sourcemap: sourcemaps,
compact: !!compact,
plugins,
format: determineModuleFormat(format)
};
if(extensions.length) {
resolve.extensions = [".js"].concat(extensions);
}

plugins = plugins.concat([
nodeResolve(resolve),
commonjs({ include: "node_modules/**" })
]);
if(compact) {
cfg.compact = true;
plugins = plugins.concat(determineCompacting(compact));
}
cfg.plugins = plugins;

cfg.format = determineModuleFormat(format);
if(exports) {
if(NAMELESS_MODULES.has(format)) {
console.error(`WARNING: ${repr(format, false)} bundles ignore ` +
`${repr("exports", false)} configuration`);
}
cfg.name = exports;
config.name = exports;
}

if(externals) { // excluded from bundle
cfg.external = Object.keys(externals);
cfg.globals = externals;
config.external = Object.keys(externals);
config.globals = externals;
}

// distinguish between (roughly) read and write settings
let read = ["external", "plugins"];
return Object.keys(cfg).reduce((memo, key) => {
return Object.keys(config).reduce((memo, key) => {
let type = read.includes(key) ? "readConfig" : "writeConfig";
memo[type][key] = cfg[key];
memo[type][key] = config[key];
return memo;
}, {
readConfig: {},
writeConfig: { indent: false }
});
}

function determineModuleFormat(format = "iife") {
function determineModuleFormat(format = "esm") {
format = format.toLowerCase();
let _format = MODULE_FORMATS[format];
switch(_format) {
case undefined:
return abort(`unrecognized module format: ${repr(format)}`);
case false:
console.error(`WARNING: ${repr(format)} is deprecated`);
return format;
case true:
return format;
default:
return _format;
}
}

function determineCompacting(type = true) {
switch(type) {
case true: // default
case "compact":
return require("rollup-plugin-cleanup")();
case "minify":
var options = { compress: false, mangle: false }; // eslint-disable-line no-var
break;
case "mangle":
options = { compress: false, mangle: true };
break;
default:
abort(`unknown compacting option ${type}`);
if(!MODULE_FORMATS.has(format)) {
return abort(`unrecognized module format: ${repr(format)}`);
}

let { terser } = loadExtension("rollup-plugin-terser",
"failed to activate minification", "faucet-pipeline-jsmin");
return terser(options);
return MODULE_FORMATS.get(format);
}

// merges `source` properties into `target`, skipping `undefined` values
function selectiveAssign(target, source) {
Object.entries(source).forEach(([key, value]) => {
if(value !== undefined) {
target[key] = value;
}
});
return target;
function determineExtensions(jsx, typescript) {
let extensions = [".js"];
if(jsx) {
extensions.push(".jsx");
}
if(typescript) {
extensions.push(".ts");
}
return extensions;
}
43 changes: 0 additions & 43 deletions lib/bundle/diskless.js

This file was deleted.

Loading