Nicer logging on build script (#4590)

master
Lucas Duailibe 2018-05-29 14:59:57 -03:00 committed by GitHub
parent 71e12ef321
commit 8a67378f97
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 230 additions and 188 deletions

View File

@ -1,198 +1,54 @@
"use strict"; "use strict";
const path = require("path"); const chalk = require("chalk");
const { rollup } = require("rollup"); const stringWidth = require("string-width");
const webpack = require("webpack"); const bundler = require("./bundler");
const resolve = require("rollup-plugin-node-resolve"); const bundleConfigs = require("./config");
const commonjs = require("rollup-plugin-commonjs");
const nodeGlobals = require("rollup-plugin-node-globals");
const json = require("rollup-plugin-json");
const replace = require("rollup-plugin-replace");
const uglify = require("rollup-plugin-uglify");
const babel = require("rollup-plugin-babel");
const nativeShims = require("./rollup-plugins/native-shims");
const executable = require("./rollup-plugins/executable");
const Bundles = require("./bundles");
const util = require("./util"); const util = require("./util");
const EXTERNALS = [ // Errors in promises should be fatal.
"assert", const loggedErrors = new Set();
"buffer", process.on("unhandledRejection", err => {
"constants", if (loggedErrors.has(err)) {
"crypto", // No need to print it twice.
"events", process.exit(1);
"fs",
"module",
"os",
"path",
"stream",
"url",
"util",
"readline",
// See comment in jest.config.js
"graceful-fs"
];
function getBabelConfig(bundle) {
const config = {
babelrc: false,
plugins: []
};
if (bundle.type === "core") {
config.plugins.push(
require.resolve("./babel-plugins/transform-custom-require")
);
} }
const targets = { node: 4 }; throw err;
if (bundle.target === "universal") { });
// From https://jamie.build/last-2-versions
targets.browsers = [">0.25%", "not ie 11", "not op_mini all"]; const OK = chalk.reset.inverse.bold.green(" DONE ");
const FAIL = chalk.reset.inverse.bold.red(" FAIL ");
function fitTerminal(input) {
const columns = process.stdout.columns || 80;
const WIDTH = columns - stringWidth(OK) + 1;
if (input.length < WIDTH) {
input += Array(WIDTH - input.length).join(chalk.dim("."));
} }
config.presets = [ return input;
[require.resolve("@babel/preset-env"), { targets, modules: false }]
];
return config;
} }
function getRollupConfig(bundle) { async function createBundle(bundleConfig) {
const relative = fp => `./${path.basename(fp).replace(/\.js$/, "")}`; const { output } = bundleConfig;
const paths = (bundle.external || []).reduce( process.stdout.write(fitTerminal(output));
(paths, filepath) =>
Object.assign(paths, { [filepath]: relative(filepath) }),
{ "graceful-fs": "fs" }
);
const config = { try {
entry: bundle.input, await bundler(bundleConfig, output);
paths, } catch (error) {
process.stdout.write(`${FAIL}\n\n`);
onwarn(warning) { handleError(error);
if (
// We use `eval("require")` to enable dynamic requires in the
// custom parser API
warning.code === "EVAL" ||
(warning.code === "CIRCULAR_DEPENDENCY" &&
warning.importer.startsWith("node_modules"))
) {
return;
}
// web bundle can't have external requires
if (
warning.code === "UNRESOLVED_IMPORT" &&
bundle.target === "universal"
) {
throw new Error(
`Unresolved dependency in universal bundle: ${warning.source}`
);
}
console.warn(warning);
}
};
const replaceStrings = {
"proces.env.NODE_ENV": JSON.stringify("production")
};
if (bundle.target === "universal") {
// We can't reference `process` in UMD bundles and this is
// an undocumented "feature"
replaceStrings["process.env.PRETTIER_DEBUG"] = "global.PRETTIER_DEBUG";
}
Object.assign(replaceStrings, bundle.replace);
const babelConfig = getBabelConfig(bundle);
config.plugins = [
replace(replaceStrings),
executable(),
json(),
bundle.target === "universal" &&
nativeShims(path.resolve(__dirname, "shims")),
resolve({
extensions: [".js", ".json"],
preferBuiltins: bundle.target === "node"
}),
commonjs(bundle.commonjs || {}),
bundle.target === "universal" && nodeGlobals(),
babelConfig && babel(babelConfig),
bundle.type === "plugin" && uglify()
].filter(Boolean);
if (bundle.target === "node") {
config.external = EXTERNALS.concat(bundle.external);
} }
return config; process.stdout.write(`${OK}\n`);
} }
function getRollupOutputOptions(bundle) { function handleError(error) {
const options = { loggedErrors.add(error);
dest: `dist/${Bundles.getFileOutput(bundle)}`, console.error(error);
useStrict: typeof bundle.strict === "undefined" ? true : bundle.strict throw error;
};
if (bundle.target === "node") {
options.format = "cjs";
} else if (bundle.target === "universal") {
options.format = "umd";
options.moduleName =
bundle.type === "plugin" ? `prettierPlugins.${bundle.name}` : bundle.name;
}
return options;
} }
function getWebpackConfig(bundle) { async function preparePackage() {
if (bundle.target === "node") {
throw new Error("Unsupported webpack bundle for node");
}
const root = path.resolve(__dirname, "..", "..");
return {
entry: path.resolve(root, bundle.input),
output: {
path: path.resolve(root, "dist"),
filename: Bundles.getFileOutput(bundle),
library:
bundle.type === "plugin"
? ["prettierPlugins", bundle.name]
: bundle.name,
libraryTarget: "umd"
}
};
}
function asyncWebpack(config) {
return new Promise((resolve, reject) => {
webpack(config, err => {
if (err) {
reject(err);
} else {
resolve();
}
});
});
}
async function createBundle(bundle) {
const output = Bundles.getFileOutput(bundle);
console.log(`BUILDING ${output}`);
if (bundle.bundler === "webpack") {
await asyncWebpack(getWebpackConfig(bundle));
} else {
try {
const result = await rollup(getRollupConfig(bundle));
await result.write(getRollupOutputOptions(bundle));
} catch (error) {
console.log(error);
throw error;
}
}
}
async function createPackageJson() {
const pkg = await util.readJson("package.json"); const pkg = await util.readJson("package.json");
pkg.bin = "./bin-prettier.js"; pkg.bin = "./bin-prettier.js";
pkg.engines.node = ">=4"; pkg.engines.node = ">=4";
@ -203,18 +59,19 @@ async function createPackageJson() {
"node -e \"assert.equal(require('.').version, require('..').version)\"" "node -e \"assert.equal(require('.').version, require('..').version)\""
}; };
await util.writeJson("dist/package.json", pkg); await util.writeJson("dist/package.json", pkg);
await util.copyFile("./README.md", "./dist/README.md");
} }
async function run() { async function run() {
await util.asyncRimRaf("dist"); await util.asyncRimRaf("dist");
for (const bundle of Bundles.bundles) { console.log(chalk.inverse(" Building packages "));
await createBundle(bundle, "node"); for (const bundleConfig of bundleConfigs) {
await createBundle(bundleConfig);
} }
await createPackageJson(); await preparePackage();
await util.copyFile("./README.md", "./dist/README.md");
} }
run(); run();

183
scripts/build/bundler.js Normal file
View File

@ -0,0 +1,183 @@
"use strict";
const path = require("path");
const { rollup } = require("rollup");
const webpack = require("webpack");
const resolve = require("rollup-plugin-node-resolve");
const commonjs = require("rollup-plugin-commonjs");
const nodeGlobals = require("rollup-plugin-node-globals");
const json = require("rollup-plugin-json");
const replace = require("rollup-plugin-replace");
const uglify = require("rollup-plugin-uglify");
const babel = require("rollup-plugin-babel");
const nativeShims = require("./rollup-plugins/native-shims");
const executable = require("./rollup-plugins/executable");
const EXTERNALS = [
"assert",
"buffer",
"constants",
"crypto",
"events",
"fs",
"module",
"os",
"path",
"stream",
"url",
"util",
"readline",
// See comment in jest.config.js
"graceful-fs"
];
function getBabelConfig(bundle) {
const config = {
babelrc: false,
plugins: [],
compact: bundle.type === "plugin" ? false : "auto"
};
if (bundle.type === "core") {
config.plugins.push(
require.resolve("./babel-plugins/transform-custom-require")
);
}
const targets = { node: 4 };
if (bundle.target === "universal") {
// From https://jamie.build/last-2-versions
targets.browsers = [">0.25%", "not ie 11", "not op_mini all"];
}
config.presets = [
[require.resolve("@babel/preset-env"), { targets, modules: false }]
];
return config;
}
function getRollupConfig(bundle) {
const relative = fp => `./${path.basename(fp).replace(/\.js$/, "")}`;
const paths = (bundle.external || []).reduce(
(paths, filepath) =>
Object.assign(paths, { [filepath]: relative(filepath) }),
{ "graceful-fs": "fs" }
);
const config = {
entry: bundle.input,
paths,
onwarn(warning) {
if (
// We use `eval("require")` to enable dynamic requires in the
// custom parser API
warning.code === "EVAL" ||
(warning.code === "CIRCULAR_DEPENDENCY" &&
warning.importer.startsWith("node_modules"))
) {
return;
}
// web bundle can't have external requires
if (
warning.code === "UNRESOLVED_IMPORT" &&
bundle.target === "universal"
) {
throw new Error(
`Unresolved dependency in universal bundle: ${warning.source}`
);
}
console.warn(warning);
}
};
const replaceStrings = {
"proces.env.NODE_ENV": JSON.stringify("production")
};
if (bundle.target === "universal") {
// We can't reference `process` in UMD bundles and this is
// an undocumented "feature"
replaceStrings["process.env.PRETTIER_DEBUG"] = "global.PRETTIER_DEBUG";
}
Object.assign(replaceStrings, bundle.replace);
const babelConfig = getBabelConfig(bundle);
config.plugins = [
replace(replaceStrings),
executable(),
json(),
bundle.target === "universal" &&
nativeShims(path.resolve(__dirname, "shims")),
resolve({
extensions: [".js", ".json"],
preferBuiltins: bundle.target === "node"
}),
commonjs(bundle.commonjs || {}),
bundle.target === "universal" && nodeGlobals(),
babelConfig && babel(babelConfig),
bundle.type === "plugin" && uglify()
].filter(Boolean);
if (bundle.target === "node") {
config.external = EXTERNALS.concat(bundle.external);
}
return config;
}
function getRollupOutputOptions(bundle) {
const options = {
dest: `dist/${bundle.output}`,
useStrict: typeof bundle.strict === "undefined" ? true : bundle.strict
};
if (bundle.target === "node") {
options.format = "cjs";
} else if (bundle.target === "universal") {
options.format = "umd";
options.moduleName =
bundle.type === "plugin" ? `prettierPlugins.${bundle.name}` : bundle.name;
}
return options;
}
function getWebpackConfig(bundle) {
if (bundle.target === "node") {
throw new Error("Unsupported webpack bundle for node");
}
const root = path.resolve(__dirname, "..", "..");
return {
entry: path.resolve(root, bundle.input),
output: {
path: path.resolve(root, "dist"),
filename: bundle.output,
library:
bundle.type === "plugin"
? ["prettierPlugins", bundle.name]
: bundle.name,
libraryTarget: "umd"
}
};
}
function runWebpack(config) {
return new Promise((resolve, reject) => {
webpack(config, err => {
if (err) {
reject(err);
} else {
resolve();
}
});
});
}
module.exports = async function createBundle(bundle) {
if (bundle.bundler === "webpack") {
await runWebpack(getWebpackConfig(bundle));
} else {
const result = await rollup(getRollupConfig(bundle));
await result.write(getRollupOutputOptions(bundle));
}
};

View File

@ -75,7 +75,7 @@ const parsers = [
}); });
/** @type {Bundle[]} */ /** @type {Bundle[]} */
const bundles = [ const coreBundles = [
{ {
input: "index.js", input: "index.js",
type: "core", type: "core",
@ -109,10 +109,12 @@ const bundles = [
"module.parent": "(module.parent || module)" "module.parent": "(module.parent || module)"
} }
} }
].concat(parsers); ];
function getFileOutput(bundle) { function getFileOutput(bundle) {
return bundle.output || path.basename(bundle.input); return bundle.output || path.basename(bundle.input);
} }
module.exports = { bundles, getFileOutput }; module.exports = coreBundles
.concat(parsers)
.map(b => Object.assign(b, { output: getFileOutput(b) }));