Refactor build script (#11475)

This commit is contained in:
fisker Cheung authored and GitHub committed 2021-09-10 10:20:43 +08:00
1 parent 2664fcb2ba
commit 8a01dee53e
4 files changed
+101 -82

No files matched your search

+34 -41
View File
@@ -4,12 +4,19 @@ import path from "node:path";
import fs from "node:fs/promises";
import readline from "node:readline";
import chalk from "chalk";
import execa from "execa";
import minimist from "minimist";
import prettyBytes from "pretty-bytes";
import rimraf from "rimraf";
import bundler from "./bundler.mjs";
import bundleConfigs from "./config.mjs";
import * as utils from "./utils.mjs";
import {
PROJECT_ROOT,
CACHE_DIR,
DIST_DIR,
readJson,
writeJson,
copyFile,
} from "./utils.mjs";
import Cache from "./cache.mjs";
// Errors in promises should be fatal.
@@ -67,7 +74,7 @@ async function createBundle(bundleConfig, cache, options) {
return;
}
const file = path.join("dist", output);
const file = path.join(DIST_DIR, output);
// Files including U+FFEE can't load in Chrome Extension
// `prettier-chrome-extension` https://github.com/prettier/prettier-chrome-extension
@@ -93,7 +100,11 @@ async function createBundle(bundleConfig, cache, options) {
bundleConfig.bundler !== "webpack" &&
target === "universal"
) {
const esmFile = path.join("dist/esm", output.replace(".js", ".mjs"));
const esmFile = path.join(
DIST_DIR,
"esm",
output.replace(".js", ".mjs")
);
sizeTexts.push(`esm ${await getSizeText(esmFile)}`);
}
process.stdout.write(fitTerminal(output, `${sizeTexts.join(", ")} `));
@@ -112,41 +123,23 @@ function handleError(error) {
throw error;
}
async function cacheFiles(cache) {
// Copy built files to .cache
try {
await execa("rm", ["-rf", path.join(".cache", "files")]);
await execa("mkdir", ["-p", path.join(".cache", "files")]);
await execa("mkdir", ["-p", path.join(".cache", "files", "esm")]);
const manifest = cache.updated;
for (const file of Object.keys(manifest.files)) {
await execa("cp", [
file,
path.join(".cache", file.replace("dist", "files")),
]);
}
} catch {
// Don't fail the build
}
}
async function preparePackage() {
const pkg = await utils.readJson("package.json");
pkg.bin = "./bin-prettier.js";
pkg.engines.node = ">=10.13.0";
delete pkg.dependencies;
delete pkg.devDependencies;
delete pkg.browserslist;
pkg.scripts = {
const packageJson = await readJson(path.join(PROJECT_ROOT, "package.json"));
packageJson.bin = "./bin-prettier.js";
packageJson.engines.node = ">=10.13.0";
delete packageJson.dependencies;
delete packageJson.devDependencies;
delete packageJson.browserslist;
packageJson.scripts = {
prepublishOnly:
"node -e \"assert.equal(require('.').version, require('..').version)\"",
};
pkg.files = ["*.js", "esm/*.mjs"];
await utils.writeJson("dist/package.json", pkg);
packageJson.files = ["*.js", "esm/*.mjs"];
await writeJson(path.join(DIST_DIR, "package.json"), packageJson);
await utils.copyFile("./README.md", "./dist/README.md");
await utils.copyFile("./LICENSE", "./dist/LICENSE");
for (const file of ["README.md", "LICENSE"]) {
await copyFile(path.join(PROJECT_ROOT, file), path.join(DIST_DIR, file));
}
}
async function run(params) {
@@ -156,19 +149,20 @@ async function run(params) {
if (params.file) {
configs = configs.filter(({ output }) => output === params.file);
} else {
await execa("rm", ["-rf", "dist"]);
rimraf.sync(DIST_DIR);
}
await execa("mkdir", ["-p", "dist"]);
await execa("mkdir", ["-p", "dist/esm"]);
if (params["purge-cache"]) {
await execa("rm", ["-rf", ".cache"]);
rimraf.sync(CACHE_DIR);
}
let bundleCache;
if (shouldUseCache) {
bundleCache = new Cache(".cache/", CACHE_VERSION);
bundleCache = new Cache({
cacheDir: CACHE_DIR,
distDir: DIST_DIR,
version: CACHE_VERSION,
});
await bundleCache.load();
}
@@ -179,7 +173,6 @@ async function run(params) {
}
if (shouldUseCache) {
await cacheFiles(bundleCache);
await bundleCache.save();
}
+9 -5
View File
@@ -17,9 +17,9 @@ import rollupPluginExecutable from "./rollup-plugins/executable.mjs";
import rollupPluginEvaluate from "./rollup-plugins/evaluate.mjs";
import rollupPluginReplaceModule from "./rollup-plugins/replace-module.mjs";
import bundles from "./config.mjs";
import { PROJECT_ROOT, DIST_DIR } from "./utils.mjs";
const { __dirname, require, json } = createEsmUtils(import.meta);
const PROJECT_ROOT = path.join(__dirname, "../..");
const packageJson = json.loadSync("../../package.json");
const entries = [
@@ -114,7 +114,7 @@ function getBabelConfig(bundle) {
function getRollupConfig(bundle) {
const config = {
input: bundle.input,
input: path.join(PROJECT_ROOT, bundle.input),
onwarn(warning) {
if (
// ignore `MIXED_EXPORTS` warn
@@ -255,7 +255,7 @@ function getRollupOutputOptions(bundle, buildOptions) {
const options = {
// Avoid warning form #8797
exports: "auto",
file: `dist/${bundle.output}`,
file: path.join(DIST_DIR, bundle.output),
name: bundle.name,
plugins: [
bundle.minify !== false &&
@@ -280,7 +280,10 @@ function getRollupOutputOptions(bundle, buildOptions) {
!buildOptions.playground && {
...options,
format: "esm",
file: `dist/esm/${bundle.output.replace(".js", ".mjs")}`,
file: path.join(
DIST_DIR,
`esm/${bundle.output.replace(".js", ".mjs")}`
),
},
].filter(Boolean);
}
@@ -290,6 +293,7 @@ function getRollupOutputOptions(bundle, buildOptions) {
if (buildOptions.playground && bundle.bundler !== "webpack") {
return { skipped: true };
}
return [options];
}
@@ -314,7 +318,7 @@ function getWebpackConfig(bundle) {
],
},
output: {
path: path.resolve(PROJECT_ROOT, "dist"),
path: DIST_DIR,
filename: bundle.output,
library: {
type: "umd",
+39 -33
View File
@@ -2,17 +2,14 @@ import { strict as assert } from "node:assert";
import crypto from "node:crypto";
import fs from "node:fs/promises";
import path from "node:path";
import execa from "execa";
import { rollup } from "rollup";
import createEsmUtils from "esm-utils";
const { __dirname } = createEsmUtils(import.meta);
const ROOT = path.join(__dirname, "..", "..");
import { PROJECT_ROOT, readJson, writeJson, copyFile } from "./utils.mjs";
class Cache {
constructor(cacheDir, version) {
this.cacheDir = path.resolve(cacheDir || required("cacheDir"));
this.manifest = path.join(this.cacheDir, "manifest.json");
constructor({ cacheDir, distDir, version }) {
this.cacheDir = cacheDir || required("cacheDir");
this.distDir = distDir || required("distDir");
this.manifest = path.join(cacheDir, "manifest.json");
this.version = version || required("version");
this.checksums = {};
this.files = {};
@@ -26,13 +23,15 @@ class Cache {
// Loads the manifest.json file with the information from the last build
async load() {
// This should never throw, if it does, let it fail the build
const lockfile = await fs.readFile("yarn.lock", "utf-8");
const lockfile = await fs.readFile(
path.join(PROJECT_ROOT, "yarn.lock"),
"utf8"
);
const lockfileHash = hashString(lockfile);
this.updated.checksums["yarn.lock"] = lockfileHash;
try {
const manifest = await fs.readFile(this.manifest, "utf-8");
const { version, checksums, files } = JSON.parse(manifest);
const { version, checksums, files } = await readJson(this.manifest);
// Ignore the cache if the version changed
assert.strictEqual(this.version, version);
@@ -40,17 +39,17 @@ class Cache {
assert.ok(typeof checksums === "object");
// If yarn.lock changed, rebuild everything
assert.strictEqual(lockfileHash, checksums["yarn.lock"]);
this.checksums = checksums;
assert.ok(typeof files === "object");
this.files = files;
for (const files of Object.values(this.files)) {
assert.ok(Array.isArray(files));
for (const modules of Object.values(files)) {
assert.ok(Array.isArray(modules));
}
this.checksums = checksums;
this.files = files;
} catch {
this.checksums = {};
this.files = {};
// noop
}
}
@@ -69,7 +68,10 @@ class Cache {
const modules = output
.filter((mod) => !/\0/.test(mod.facadeModuleId))
.map((mod) => [path.relative(ROOT, mod.facadeModuleId), mod.code]);
.map((mod) => [
path.relative(PROJECT_ROOT, mod.facadeModuleId),
mod.code,
]);
for (const [id, code] of modules) {
newFiles.push(id);
@@ -95,28 +97,32 @@ class Cache {
}
async save() {
try {
await fs.writeFile(this.manifest, JSON.stringify(this.updated, null, 2));
} catch {
// Don't fail the build
const { manifest, updated } = this;
await writeJson(manifest, updated);
const files = Object.keys(updated.files);
for (const file of files) {
await copyFile(
path.join(this.distDir, file),
path.join(this.cacheDir, "files", file)
);
}
}
async isCached(inputOptions, outputOption) {
const useCache = await this.checkBundle(
outputOption.file,
inputOptions,
outputOption
);
const file = path.relative(this.distDir, outputOption.file);
const useCache = await this.checkBundle(file, inputOptions, outputOption);
if (useCache) {
try {
await execa("cp", [
path.join(this.cacheDir, outputOption.file.replace("dist", "files")),
outputOption.file,
]);
await copyFile(
path.join(this.cacheDir, "files", file),
path.join(this.distDir, file)
);
return true;
} catch (err) {
console.log(err);
} catch {
// Proceed to build
}
}
+19 -3
View File
@@ -1,4 +1,6 @@
import fs from "node:fs/promises";
import url from "node:url";
import path from "node:path";
async function readJson(file) {
const data = await fs.readFile(file);
@@ -7,12 +9,26 @@ async function readJson(file) {
function writeJson(file, content) {
content = JSON.stringify(content, null, 2);
return fs.writeFile(file, content);
return writeFile(file, content);
}
async function copyFile(from, to) {
const data = await fs.readFile(from);
return fs.writeFile(to, data);
return writeFile(to, data);
}
export { readJson, writeJson, copyFile };
async function writeFile(file, content) {
const directory = path.dirname(file);
try {
await fs.mkdir(directory, { recursive: true });
} catch {
// noop
}
return fs.writeFile(file, content);
}
const PROJECT_ROOT = url.fileURLToPath(new URL("../../", import.meta.url));
const CACHE_DIR = path.join(PROJECT_ROOT, ".cache");
const DIST_DIR = path.join(PROJECT_ROOT, "dist");
export { PROJECT_ROOT, DIST_DIR, CACHE_DIR, readJson, writeJson, copyFile };