Refactor build script (#11475)
This commit is contained in:
1 parent
2664fcb2ba
commit
8a01dee53e
4 files changed
+101
-82
No files matched your search
+34
-41
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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 };
|
||||
Reference in new issue
Block a user