1 parent
6ccc462409
commit
cc6856ae20
26 files changed
+832
-1158
No files matched your search
@@ -23,17 +23,6 @@ jobs:
|
||||
- name: Install Dependencies
|
||||
run: yarn install --frozen-lockfile
|
||||
|
||||
- name: Cache Build Results
|
||||
id: build-cache
|
||||
uses: actions/cache@v2.1.7
|
||||
with:
|
||||
path: .cache
|
||||
key: v2-build-cache-${{ hashFiles('yarn.lock') }}-${{ hashFiles('scripts/build/**/*') }}-${{ github.ref }}-
|
||||
restore-keys: |
|
||||
v2-build-cache-${{ hashFiles('yarn.lock') }}-${{ hashFiles('scripts/build/**/*') }}-${{ github.ref }}-
|
||||
v2-build-cache-${{ hashFiles('yarn.lock') }}-${{ hashFiles('scripts/build/**/*') }}-refs/heads/${{ github.base_ref }}-
|
||||
v2-build-cache-${{ hashFiles('yarn.lock') }}-${{ hashFiles('scripts/build/**/*') }}-refs/heads/main-
|
||||
|
||||
- name: Build Package
|
||||
run: yarn build
|
||||
|
||||
@@ -45,7 +34,6 @@ jobs:
|
||||
|
||||
# This step calls `git reset`
|
||||
# It should be the last step
|
||||
# The cache step might saving the result of main branch, need investigate
|
||||
- name: Check Sizes
|
||||
if: ${{ github.event_name == 'pull_request' && startsWith(github.head_ref, 'dependabot/npm_and_yarn/') }}
|
||||
uses: preactjs/compressed-size-action@2.3.0
|
||||
|
||||
@@ -93,6 +93,7 @@
|
||||
"eqeqeq",
|
||||
"Ericsburgh",
|
||||
"Esben",
|
||||
"esbuild",
|
||||
"eslintignore",
|
||||
"eslump",
|
||||
"espree",
|
||||
@@ -188,6 +189,7 @@
|
||||
"mdast",
|
||||
"Memberish",
|
||||
"meriyah",
|
||||
"metafile",
|
||||
"Michał",
|
||||
"Microsyntax",
|
||||
"Mikael",
|
||||
@@ -227,6 +229,8 @@
|
||||
"onwarn",
|
||||
"Oopsy",
|
||||
"outdent",
|
||||
"outfile",
|
||||
"outro",
|
||||
"overparenthesization",
|
||||
"Panasenko",
|
||||
"pandoc",
|
||||
|
||||
+9
-14
@@ -91,24 +91,24 @@
|
||||
"@babel/core": "7.16.7",
|
||||
"@babel/preset-env": "7.16.7",
|
||||
"@babel/types": "7.16.7",
|
||||
"@esbuild-plugins/node-globals-polyfill": "0.1.1",
|
||||
"@esbuild-plugins/node-modules-polyfill": "0.1.4",
|
||||
"@glimmer/reference": "0.83.1",
|
||||
"@rollup/plugin-alias": "3.1.9",
|
||||
"@rollup/plugin-babel": "5.3.0",
|
||||
"@rollup/plugin-commonjs": "21.0.1",
|
||||
"@rollup/plugin-json": "4.1.0",
|
||||
"@rollup/plugin-node-resolve": "13.1.3",
|
||||
"@rollup/plugin-replace": "3.0.1",
|
||||
"@types/estree": "0.0.50",
|
||||
"@types/jest": "27.4.0",
|
||||
"babel-jest": "27.4.6",
|
||||
"@typescript-eslint/eslint-plugin": "5.9.0",
|
||||
"babel-loader": "8.2.3",
|
||||
"benchmark": "2.1.4",
|
||||
"browserslist": "4.19.1",
|
||||
"builtin-modules": "3.2.0",
|
||||
"core-js": "3.20.2",
|
||||
"cross-env": "7.0.3",
|
||||
"cspell": "5.15.1",
|
||||
"enquirer": "2.3.6",
|
||||
"esbuild": "0.14.10",
|
||||
"esbuild-plugin-browserslist": "0.4.1",
|
||||
"esbuild-plugin-text-replace": "1.1.3",
|
||||
"eslint": "8.6.0",
|
||||
"eslint-config-prettier": "8.3.0",
|
||||
"eslint-formatter-friendly": "7.0.0",
|
||||
@@ -132,14 +132,9 @@
|
||||
"prettier": "2.5.1",
|
||||
"pretty-bytes": "5.6.0",
|
||||
"rimraf": "3.0.2",
|
||||
"rollup": "2.63.0",
|
||||
"rollup-plugin-polyfill-node": "0.8.0",
|
||||
"rollup-plugin-terser": "7.0.2",
|
||||
"rollup-plugin-license": "2.2.0",
|
||||
"snapshot-diff": "0.9.0",
|
||||
"string-replace-loader": "3.1.0",
|
||||
"tempy": "1.0.1",
|
||||
"terser-webpack-plugin": "5.3.0",
|
||||
"webpack": "5.49.0"
|
||||
"tempy": "1.0.1"
|
||||
},
|
||||
"scripts": {
|
||||
"prepublishOnly": "echo \"Error: must publish from dist/\" && exit 1",
|
||||
@@ -163,7 +158,7 @@
|
||||
"fix": "run-s fix:eslint fix:prettier",
|
||||
"fix:eslint": "yarn lint:eslint --fix",
|
||||
"fix:prettier": "yarn lint:prettier --write",
|
||||
"build": "node --max-old-space-size=4096 ./scripts/build/build.mjs",
|
||||
"build": "node ./scripts/build/build.mjs",
|
||||
"build:website": "node ./scripts/build-website.mjs"
|
||||
},
|
||||
"browserslist": [
|
||||
|
||||
@@ -12,14 +12,6 @@ yarn build
|
||||
|
||||
## Flags
|
||||
|
||||
### `--no-cache` flag
|
||||
|
||||
Run script with `--no-cache` flag will clean up the cache directory (`.cache` in project root) before bundling files.
|
||||
|
||||
```sh
|
||||
yarn build --no-cache
|
||||
```
|
||||
|
||||
### `--playground`
|
||||
|
||||
Run script with `--playground` flag will only build files needed for the website.
|
||||
|
||||
+19
-31
@@ -9,7 +9,6 @@ import prettyBytes from "pretty-bytes";
|
||||
import rimraf from "rimraf";
|
||||
import {
|
||||
PROJECT_ROOT,
|
||||
BUILD_CACHE_DIR,
|
||||
DIST_DIR,
|
||||
readJson,
|
||||
writeJson,
|
||||
@@ -17,7 +16,7 @@ import {
|
||||
} from "../utils/index.mjs";
|
||||
import bundler from "./bundler.mjs";
|
||||
import bundleConfigs from "./config.mjs";
|
||||
import Cache from "./cache.mjs";
|
||||
import saveLicenses from "./save-licenses.mjs";
|
||||
|
||||
// Errors in promises should be fatal.
|
||||
const loggedErrors = new Set();
|
||||
@@ -29,9 +28,7 @@ process.on("unhandledRejection", (err) => {
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
const CACHE_VERSION = "v38"; // This need update when updating build scripts
|
||||
const statusConfig = [
|
||||
{ color: "bgYellow", text: "CACHED" },
|
||||
{ color: "bgGreen", text: "DONE" },
|
||||
{ color: "bgRed", text: "FAIL" },
|
||||
{ color: "bgGray", text: "SKIPPED" },
|
||||
@@ -58,22 +55,17 @@ function fitTerminal(input, suffix = "") {
|
||||
return input;
|
||||
}
|
||||
|
||||
async function createBundle(bundleConfig, cache, options) {
|
||||
async function createBundle(bundleConfig, options) {
|
||||
const { output, target, format, type } = bundleConfig;
|
||||
process.stdout.write(fitTerminal(output));
|
||||
try {
|
||||
const { cached, skipped } = await bundler(bundleConfig, cache, options);
|
||||
const { skipped } = await bundler(bundleConfig, options);
|
||||
|
||||
if (skipped) {
|
||||
console.log(status.SKIPPED);
|
||||
return;
|
||||
}
|
||||
|
||||
if (cached) {
|
||||
console.log(status.CACHED);
|
||||
return;
|
||||
}
|
||||
|
||||
const file = path.join(DIST_DIR, output);
|
||||
|
||||
// Files including U+FFEE can't load in Chrome Extension
|
||||
@@ -143,9 +135,10 @@ async function preparePackage() {
|
||||
}
|
||||
|
||||
async function run(params) {
|
||||
const shouldUseCache = params.cache && !params.file && params.minify === null;
|
||||
const shouldPreparePackage =
|
||||
!params.playground && !params.file && params.minify === null;
|
||||
const shouldSaveBundledPackagesLicenses = shouldPreparePackage;
|
||||
|
||||
let configs = bundleConfigs;
|
||||
if (params.file) {
|
||||
configs = configs.filter(({ output }) => output === params.file);
|
||||
@@ -153,39 +146,34 @@ async function run(params) {
|
||||
rimraf.sync(DIST_DIR);
|
||||
}
|
||||
|
||||
if (!params.cache) {
|
||||
rimraf.sync(BUILD_CACHE_DIR);
|
||||
}
|
||||
|
||||
let bundleCache;
|
||||
if (shouldUseCache) {
|
||||
bundleCache = new Cache({
|
||||
cacheDir: BUILD_CACHE_DIR,
|
||||
distDir: DIST_DIR,
|
||||
version: CACHE_VERSION,
|
||||
});
|
||||
await bundleCache.load();
|
||||
const licenses = [];
|
||||
if (shouldSaveBundledPackagesLicenses) {
|
||||
params.onLicenseFound = (dependencies) => licenses.push(...dependencies);
|
||||
}
|
||||
|
||||
console.log(chalk.inverse(" Building packages "));
|
||||
|
||||
for (const bundleConfig of configs) {
|
||||
await createBundle(bundleConfig, bundleCache, params);
|
||||
}
|
||||
|
||||
if (shouldUseCache) {
|
||||
await bundleCache.save();
|
||||
await createBundle(bundleConfig, params);
|
||||
}
|
||||
|
||||
if (shouldPreparePackage) {
|
||||
await preparePackage();
|
||||
}
|
||||
|
||||
if (shouldSaveBundledPackagesLicenses) {
|
||||
await saveLicenses(licenses);
|
||||
} else {
|
||||
console.warn(
|
||||
chalk.red("Bundled packages licenses not included in `dist/LICENSE`.")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
run(
|
||||
minimist(process.argv.slice(2), {
|
||||
boolean: ["cache", "playground", "print-size", "minify"],
|
||||
boolean: ["playground", "print-size", "minify"],
|
||||
string: ["file"],
|
||||
default: { cache: true, playground: false, printSize: false, minify: null },
|
||||
default: { playground: false, printSize: false, minify: null },
|
||||
})
|
||||
);
|
||||
+118
-293
@@ -1,58 +1,28 @@
|
||||
import fs from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import fs from "node:fs";
|
||||
import { rollup } from "rollup";
|
||||
import webpack from "webpack";
|
||||
import { nodeResolve as rollupPluginNodeResolve } from "@rollup/plugin-node-resolve";
|
||||
import rollupPluginAlias from "@rollup/plugin-alias";
|
||||
import rollupPluginCommonjs from "@rollup/plugin-commonjs";
|
||||
import rollupPluginPolyfillNode from "rollup-plugin-polyfill-node";
|
||||
import rollupPluginJson from "@rollup/plugin-json";
|
||||
import rollupPluginReplace from "@rollup/plugin-replace";
|
||||
import { terser as rollupPluginTerser } from "rollup-plugin-terser";
|
||||
import { babel as rollupPluginBabel } from "@rollup/plugin-babel";
|
||||
import WebpackPluginTerser from "terser-webpack-plugin";
|
||||
import createEsmUtils from "esm-utils";
|
||||
import builtinModules from "builtin-modules";
|
||||
import browserslist from "browserslist";
|
||||
import * as babel from "@babel/core";
|
||||
import esbuild from "esbuild";
|
||||
import { NodeModulesPolyfillPlugin as esbuildPluginNodeModulePolyfills } from "@esbuild-plugins/node-modules-polyfill";
|
||||
import { NodeGlobalsPolyfillPlugin as esbuildPluginNodeGlobalsPolyfills } from "@esbuild-plugins/node-globals-polyfill";
|
||||
import esbuildPluginTextReplace from "esbuild-plugin-text-replace";
|
||||
import { resolveToEsbuildTarget } from "esbuild-plugin-browserslist";
|
||||
import { PROJECT_ROOT, DIST_DIR } from "../utils/index.mjs";
|
||||
import rollupPluginExecutable from "./rollup-plugins/executable.mjs";
|
||||
import rollupPluginEvaluate from "./rollup-plugins/evaluate.mjs";
|
||||
import rollupPluginReplaceModule from "./rollup-plugins/replace-module.mjs";
|
||||
import esbuildPluginEvaluate from "./esbuild-plugins/evaluate.mjs";
|
||||
import esbuildPluginReplaceModule from "./esbuild-plugins/replace-module.mjs";
|
||||
import esbuildPluginLicense from "./esbuild-plugins/license.mjs";
|
||||
import esbuildPluginUmd from "./esbuild-plugins/umd.mjs";
|
||||
import bundles from "./config.mjs";
|
||||
|
||||
const { __dirname, json } = createEsmUtils(import.meta);
|
||||
const packageJson = json.loadSync("../../package.json");
|
||||
|
||||
const entries = [
|
||||
// Force using the CJS file, instead of ESM; i.e. get the file
|
||||
// from `"main"` instead of `"module"` (rollup default) of package.json
|
||||
{
|
||||
find: "@angular/compiler/src",
|
||||
replacement: path.resolve(
|
||||
`${PROJECT_ROOT}/node_modules/@angular/compiler/esm2015/src`
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
function webpackNativeShims(config, modules) {
|
||||
if (!config.resolve) {
|
||||
config.resolve = {};
|
||||
}
|
||||
const { resolve } = config;
|
||||
resolve.alias = resolve.alias || {};
|
||||
resolve.fallback = resolve.fallback || {};
|
||||
for (const module of modules) {
|
||||
if (module in resolve.alias || module in resolve.fallback) {
|
||||
throw new Error(`fallback/alias for "${module}" already exists.`);
|
||||
}
|
||||
const file = path.join(__dirname, `shims/${module}.mjs`);
|
||||
if (fs.existsSync(file)) {
|
||||
resolve.alias[module] = file;
|
||||
} else {
|
||||
resolve.fallback[module] = false;
|
||||
}
|
||||
}
|
||||
return config;
|
||||
}
|
||||
const umdTarget = resolveToEsbuildTarget(
|
||||
browserslist(packageJson.browserslist),
|
||||
{ printUnknownTargets: false }
|
||||
);
|
||||
|
||||
function getBabelConfig(bundle) {
|
||||
const config = {
|
||||
@@ -62,7 +32,7 @@ function getBabelConfig(bundle) {
|
||||
},
|
||||
sourceType: "unambiguous",
|
||||
plugins: bundle.babelPlugins || [],
|
||||
compact: bundle.type === "plugin" ? false : "auto",
|
||||
compact: false,
|
||||
exclude: [/\/core-js\//],
|
||||
};
|
||||
const targets = { node: "10" };
|
||||
@@ -75,7 +45,9 @@ function getBabelConfig(bundle) {
|
||||
{
|
||||
targets,
|
||||
exclude: [
|
||||
"es.array.unscopables.flat",
|
||||
"es.array.unscopables.flat-map",
|
||||
"es.array.sort",
|
||||
"es.promise",
|
||||
"es.promise.finally",
|
||||
"es.string.replace",
|
||||
@@ -99,40 +71,12 @@ function getBabelConfig(bundle) {
|
||||
return config;
|
||||
}
|
||||
|
||||
function getRollupConfig(bundle) {
|
||||
const config = {
|
||||
input: path.join(PROJECT_ROOT, bundle.input),
|
||||
onwarn(warning) {
|
||||
if (
|
||||
// ignore `MIXED_EXPORTS` warn
|
||||
warning.code === "MIXED_EXPORTS" ||
|
||||
(warning.code === "CIRCULAR_DEPENDENCY" &&
|
||||
(warning.importer.startsWith("node_modules") ||
|
||||
warning.importer.startsWith("\x00polyfill-node."))) ||
|
||||
warning.code === "SOURCEMAP_ERROR" ||
|
||||
warning.code === "THIS_IS_UNDEFINED"
|
||||
) {
|
||||
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);
|
||||
},
|
||||
external: [],
|
||||
};
|
||||
|
||||
function* getEsbuildOptions(bundle, options) {
|
||||
const replaceStrings = {
|
||||
"process.env.PRETTIER_TARGET": JSON.stringify(bundle.target),
|
||||
"process.env.NODE_ENV": JSON.stringify("production"),
|
||||
// `tslib` exports global variables
|
||||
"createExporter(root": "createExporter({}",
|
||||
};
|
||||
if (bundle.target === "universal") {
|
||||
// We can't reference `process` in UMD bundles and this is
|
||||
@@ -148,12 +92,6 @@ function getRollupConfig(bundle) {
|
||||
"/prettier-security-dirname-placeholder"
|
||||
);
|
||||
}
|
||||
Object.assign(replaceStrings, bundle.replace);
|
||||
|
||||
const babelConfig = { babelHelpers: "bundled", ...getBabelConfig(bundle) };
|
||||
|
||||
const alias = { ...bundle.alias };
|
||||
alias.entries = [...entries, ...(alias.entries || [])];
|
||||
|
||||
const replaceModule = {};
|
||||
// Replace other bundled files
|
||||
@@ -171,7 +109,7 @@ function getRollupConfig(bundle) {
|
||||
// Universal bundle only use version info from package.json
|
||||
// Replace package.json with `{version: "{VERSION}"}`
|
||||
replaceModule[path.join(PROJECT_ROOT, "package.json")] = {
|
||||
code: `export default ${JSON.stringify({
|
||||
code: `module.exports = ${JSON.stringify({
|
||||
version: packageJson.version,
|
||||
})};`,
|
||||
};
|
||||
@@ -186,238 +124,125 @@ function getRollupConfig(bundle) {
|
||||
"src/language-markdown/parsers.js",
|
||||
"src/language-yaml/parsers.js",
|
||||
]) {
|
||||
replaceModule[path.join(PROJECT_ROOT, file)] = {
|
||||
code: "export default undefined;",
|
||||
};
|
||||
replaceModule[path.join(PROJECT_ROOT, file)] = { code: "" };
|
||||
}
|
||||
}
|
||||
|
||||
Object.assign(replaceModule, bundle.replaceModule);
|
||||
|
||||
config.plugins = [
|
||||
rollupPluginReplace({
|
||||
values: replaceStrings,
|
||||
delimiters: ["", ""],
|
||||
preventAssignment: true,
|
||||
}),
|
||||
rollupPluginExecutable(),
|
||||
rollupPluginEvaluate(),
|
||||
rollupPluginJson({
|
||||
exclude: Object.keys(replaceModule)
|
||||
.filter((file) => file.endsWith(".json"))
|
||||
.map((file) => path.relative(PROJECT_ROOT, file)),
|
||||
}),
|
||||
rollupPluginAlias(alias),
|
||||
rollupPluginNodeResolve({
|
||||
extensions: [".js", ".json"],
|
||||
preferBuiltins: bundle.target === "node",
|
||||
mainFields: ["main"],
|
||||
}),
|
||||
rollupPluginCommonjs({
|
||||
ignoreGlobal: bundle.target === "node",
|
||||
ignore:
|
||||
bundle.type === "plugin"
|
||||
? undefined
|
||||
: (id) => /\.\/parser-.*?/.test(id),
|
||||
requireReturnsDefault: "preferred",
|
||||
ignoreDynamicRequires: true,
|
||||
ignoreTryCatch: bundle.target === "node",
|
||||
...bundle.commonjs,
|
||||
}),
|
||||
rollupPluginReplaceModule(replaceModule),
|
||||
bundle.target === "universal" && rollupPluginPolyfillNode(),
|
||||
rollupPluginBabel(babelConfig),
|
||||
].filter(Boolean);
|
||||
|
||||
if (bundle.target === "node") {
|
||||
config.external.push(...builtinModules);
|
||||
}
|
||||
if (bundle.external) {
|
||||
config.external.push(...bundle.external);
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
function getRollupOutputOptions(bundle, buildOptions) {
|
||||
const options = {
|
||||
// Avoid warning form #8797
|
||||
exports: "auto",
|
||||
file: path.join(DIST_DIR, bundle.output),
|
||||
name: bundle.name,
|
||||
plugins: [],
|
||||
};
|
||||
|
||||
let shouldMinify = buildOptions.minify;
|
||||
let shouldMinify = options.minify;
|
||||
if (typeof shouldMinify !== "boolean") {
|
||||
shouldMinify = bundle.minify !== false && bundle.target === "universal";
|
||||
}
|
||||
|
||||
if (shouldMinify) {
|
||||
options.plugins.push(
|
||||
rollupPluginTerser({
|
||||
output: {
|
||||
ascii_only: true,
|
||||
},
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
if (bundle.target === "node") {
|
||||
options.format = "cjs";
|
||||
} else if (bundle.target === "universal") {
|
||||
if (!bundle.format && bundle.bundler !== "webpack") {
|
||||
return [
|
||||
{
|
||||
...options,
|
||||
format: "umd",
|
||||
},
|
||||
!buildOptions.playground && {
|
||||
...options,
|
||||
format: "esm",
|
||||
file: path.join(
|
||||
DIST_DIR,
|
||||
`esm/${bundle.output.replace(".js", ".mjs")}`
|
||||
),
|
||||
},
|
||||
].filter(Boolean);
|
||||
}
|
||||
options.format = bundle.format;
|
||||
}
|
||||
|
||||
if (buildOptions.playground && bundle.bundler !== "webpack") {
|
||||
return { skipped: true };
|
||||
}
|
||||
|
||||
return [options];
|
||||
}
|
||||
|
||||
function getWebpackConfig(bundle, buildOptions) {
|
||||
if (bundle.type !== "plugin" || bundle.target !== "universal") {
|
||||
throw new Error("Must use rollup for this bundle");
|
||||
}
|
||||
|
||||
const config = {
|
||||
mode: "production",
|
||||
performance: { hints: false },
|
||||
entry: path.resolve(PROJECT_ROOT, bundle.input),
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.js$/,
|
||||
use: {
|
||||
loader: "babel-loader",
|
||||
options: getBabelConfig(bundle),
|
||||
const esbuildOptions = {
|
||||
entryPoints: [path.join(PROJECT_ROOT, bundle.input)],
|
||||
bundle: true,
|
||||
metafile: true,
|
||||
plugins: [
|
||||
bundle.target === "universal" && esbuildPluginNodeGlobalsPolyfills(),
|
||||
bundle.target === "universal" && esbuildPluginNodeModulePolyfills(),
|
||||
esbuildPluginEvaluate(),
|
||||
esbuildPluginReplaceModule({ ...replaceModule, ...bundle.replaceModule }),
|
||||
esbuildPluginTextReplace({
|
||||
include: /\.[cm]?js$/,
|
||||
// TODO[@fisker]: Use RegExp when possible
|
||||
pattern: Object.entries({ ...replaceStrings, ...bundle.replace }),
|
||||
}),
|
||||
options.onLicenseFound &&
|
||||
esbuildPluginLicense({
|
||||
cwd: PROJECT_ROOT,
|
||||
thirdParty: {
|
||||
includePrivate: true,
|
||||
output: options.onLicenseFound,
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.js$/,
|
||||
use: {
|
||||
loader: "string-replace-loader",
|
||||
options: {
|
||||
multiple: Object.entries(bundle.replace).map(
|
||||
([search, replace]) => ({ search, replace })
|
||||
),
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
output: {
|
||||
path: DIST_DIR,
|
||||
filename: bundle.output,
|
||||
library: {
|
||||
type: "umd",
|
||||
name: bundle.name.split("."),
|
||||
},
|
||||
// https://github.com/webpack/webpack/issues/6642
|
||||
globalObject: 'new Function("return this")()',
|
||||
},
|
||||
optimization: {},
|
||||
resolve: {
|
||||
// Webpack@5 can't resolve "postcss/lib/parser" and "postcss/lib/stringifier"" imported by `postcss-scss`
|
||||
// Ignore `exports` field to fix bundle script
|
||||
exportsFields: [],
|
||||
},
|
||||
}),
|
||||
].filter(Boolean),
|
||||
minify: shouldMinify,
|
||||
legalComments: "none",
|
||||
external: [...(bundle.external || [])],
|
||||
// Disable esbuild auto discover `tsconfig.json` file
|
||||
tsconfig: path.join(__dirname, "empty-tsconfig.json"),
|
||||
mainFields: ["main"],
|
||||
target: ["node10"],
|
||||
logLevel: "error",
|
||||
};
|
||||
|
||||
let shouldMinify = buildOptions.minify;
|
||||
if (typeof shouldMinify !== "boolean") {
|
||||
shouldMinify = true;
|
||||
}
|
||||
if (bundle.target === "universal") {
|
||||
esbuildOptions.target.push(...umdTarget);
|
||||
|
||||
if (shouldMinify) {
|
||||
config.optimization.minimizer = [
|
||||
new WebpackPluginTerser({
|
||||
// prevent terser generate extra .LICENSE file
|
||||
extractComments: false,
|
||||
terserOptions: {
|
||||
// prevent U+FFFE in the output
|
||||
output: {
|
||||
ascii_only: true,
|
||||
},
|
||||
},
|
||||
}),
|
||||
];
|
||||
yield {
|
||||
...esbuildOptions,
|
||||
outfile: path.join(DIST_DIR, bundle.output),
|
||||
plugins: [
|
||||
esbuildPluginUmd({ name: bundle.name }),
|
||||
...esbuildOptions.plugins,
|
||||
],
|
||||
format: "umd",
|
||||
};
|
||||
|
||||
if (!bundle.format && !options.playground) {
|
||||
yield {
|
||||
...esbuildOptions,
|
||||
outfile: path.join(
|
||||
DIST_DIR,
|
||||
`esm/${bundle.output.replace(".js", ".mjs")}`
|
||||
),
|
||||
format: "esm",
|
||||
};
|
||||
}
|
||||
} else {
|
||||
config.optimization.minimize = false;
|
||||
}
|
||||
esbuildOptions.external.push(
|
||||
...builtinModules,
|
||||
"./package.json*",
|
||||
...bundles
|
||||
.filter((item) => item.input !== bundle.input)
|
||||
.map((item) => `./${item.output}*`)
|
||||
);
|
||||
|
||||
return webpackNativeShims(config, ["os", "path", "util", "url", "fs"]);
|
||||
yield {
|
||||
...esbuildOptions,
|
||||
outfile: path.join(DIST_DIR, bundle.output),
|
||||
format: "cjs",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function runWebpack(config) {
|
||||
return new Promise((resolve, reject) => {
|
||||
webpack(config, (error, stats) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
return;
|
||||
}
|
||||
async function runBuild(bundle, esbuildOptions) {
|
||||
const { format, plugins, outfile } = esbuildOptions;
|
||||
|
||||
if (stats.hasErrors()) {
|
||||
const { errors } = stats.toJson();
|
||||
const error = new Error(errors[0].message);
|
||||
error.errors = errors;
|
||||
reject(error);
|
||||
return;
|
||||
}
|
||||
await esbuild.build({
|
||||
...esbuildOptions,
|
||||
plugins: plugins.filter(({ name }) => name !== "umd"),
|
||||
format: format === "umd" ? "cjs" : format,
|
||||
minify: false,
|
||||
});
|
||||
|
||||
if (stats.hasWarnings()) {
|
||||
const { warnings } = stats.toJson();
|
||||
console.warn(warnings);
|
||||
}
|
||||
const text = await fs.readFile(outfile);
|
||||
|
||||
resolve();
|
||||
});
|
||||
const { code } = await babel.transformAsync(text, {
|
||||
filename: outfile,
|
||||
...getBabelConfig(bundle),
|
||||
});
|
||||
await fs.writeFile(outfile, code);
|
||||
|
||||
await esbuild.build({
|
||||
...esbuildOptions,
|
||||
plugins: plugins.filter(({ name }) => name === "umd"),
|
||||
entryPoints: [outfile],
|
||||
allowOverwrite: true,
|
||||
});
|
||||
}
|
||||
|
||||
async function createBundle(bundle, cache, options) {
|
||||
const inputOptions = getRollupConfig(bundle);
|
||||
const outputOptions = getRollupOutputOptions(bundle, options);
|
||||
|
||||
if (!Array.isArray(outputOptions) && outputOptions.skipped) {
|
||||
async function createBundle(bundle, options) {
|
||||
if (
|
||||
options.playground &&
|
||||
(bundle.target !== "universal" || bundle.output === "doc.js")
|
||||
) {
|
||||
return { skipped: true };
|
||||
}
|
||||
|
||||
if (
|
||||
cache &&
|
||||
(
|
||||
await Promise.all(
|
||||
outputOptions.map((outputOption) =>
|
||||
cache.isCached(inputOptions, outputOption)
|
||||
)
|
||||
)
|
||||
).every((cached) => cached)
|
||||
) {
|
||||
return { cached: true };
|
||||
}
|
||||
|
||||
if (bundle.bundler === "webpack") {
|
||||
await runWebpack(getWebpackConfig(bundle, options));
|
||||
} else {
|
||||
const result = await rollup(inputOptions);
|
||||
await Promise.all(outputOptions.map((option) => result.write(option)));
|
||||
const esbuildOptions = getEsbuildOptions(bundle, options);
|
||||
for (const options of esbuildOptions) {
|
||||
await runBuild(bundle, options);
|
||||
}
|
||||
|
||||
return { bundled: true };
|
||||
|
||||
@@ -1,160 +0,0 @@
|
||||
import { strict as assert } from "node:assert";
|
||||
import crypto from "node:crypto";
|
||||
import fs from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { rollup } from "rollup";
|
||||
import {
|
||||
PROJECT_ROOT,
|
||||
readJson,
|
||||
writeJson,
|
||||
copyFile,
|
||||
} from "../utils/index.mjs";
|
||||
|
||||
class Cache {
|
||||
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 = {};
|
||||
this.updated = {
|
||||
version: this.version,
|
||||
checksums: {},
|
||||
files: {},
|
||||
};
|
||||
}
|
||||
|
||||
// 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(
|
||||
path.join(PROJECT_ROOT, "yarn.lock"),
|
||||
"utf8"
|
||||
);
|
||||
const lockfileHash = hashString(lockfile);
|
||||
this.updated.checksums["yarn.lock"] = lockfileHash;
|
||||
|
||||
try {
|
||||
const { version, checksums, files } = await readJson(this.manifest);
|
||||
|
||||
// Ignore the cache if the version changed
|
||||
assert.strictEqual(this.version, version);
|
||||
|
||||
assert.ok(typeof checksums === "object");
|
||||
// If yarn.lock changed, rebuild everything
|
||||
assert.strictEqual(lockfileHash, checksums["yarn.lock"]);
|
||||
|
||||
assert.ok(typeof files === "object");
|
||||
|
||||
for (const modules of Object.values(files)) {
|
||||
assert.ok(Array.isArray(modules));
|
||||
}
|
||||
|
||||
this.checksums = checksums;
|
||||
this.files = files;
|
||||
} catch {
|
||||
// noop
|
||||
}
|
||||
}
|
||||
|
||||
// Run rollup to get the list of files included in the bundle and check if
|
||||
// any (or the list itself) have changed.
|
||||
// This takes the same rollup config used for bundling to include files that are
|
||||
// resolved by specific plugins.
|
||||
async checkBundle(id, inputOptions, outputOptions) {
|
||||
const files = new Set(this.files[id]);
|
||||
const newFiles = (this.updated.files[id] = []);
|
||||
|
||||
let dirty = false;
|
||||
|
||||
const bundle = await rollup(getRollupConfig(inputOptions));
|
||||
const { output } = await bundle.generate(outputOptions);
|
||||
|
||||
const modules = output
|
||||
.filter((mod) => !/\0/.test(mod.facadeModuleId))
|
||||
.map((mod) => [
|
||||
path.relative(PROJECT_ROOT, mod.facadeModuleId),
|
||||
mod.code,
|
||||
]);
|
||||
|
||||
for (const [id, code] of modules) {
|
||||
newFiles.push(id);
|
||||
// If we already checked this file for another bundle, reuse the hash
|
||||
if (!this.updated.checksums[id]) {
|
||||
this.updated.checksums[id] = hashString(code);
|
||||
}
|
||||
const hash = this.updated.checksums[id];
|
||||
|
||||
// Check if this file changed
|
||||
if (!this.checksums[id] || this.checksums[id] !== hash) {
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
// Check if this file is new
|
||||
if (!files.delete(id)) {
|
||||
dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Final check: if any file was removed, `files` is not empty
|
||||
return !dirty && files.size === 0;
|
||||
}
|
||||
|
||||
async save() {
|
||||
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 file = path.relative(this.distDir, outputOption.file);
|
||||
const useCache = await this.checkBundle(file, inputOptions, outputOption);
|
||||
|
||||
if (useCache) {
|
||||
try {
|
||||
await copyFile(
|
||||
path.join(this.cacheDir, "files", file),
|
||||
path.join(this.distDir, file)
|
||||
);
|
||||
|
||||
return true;
|
||||
} catch {
|
||||
// Proceed to build
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function required(name) {
|
||||
throw new Error(name + " is required");
|
||||
}
|
||||
|
||||
function hashString(string) {
|
||||
return crypto.createHash("md5").update(string).digest("hex");
|
||||
}
|
||||
|
||||
function getRollupConfig(rollupConfig) {
|
||||
return {
|
||||
...rollupConfig,
|
||||
onwarn() {},
|
||||
plugins: rollupConfig.plugins.filter(
|
||||
(plugin) =>
|
||||
// We're not interested in dependencies, we already check `yarn.lock`
|
||||
plugin.name !== "node-resolve" &&
|
||||
// This is really slow, we need this "preflight" to be fast
|
||||
plugin.name !== "babel"
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
export default Cache;
|
||||
+11
-10
@@ -1,4 +1,7 @@
|
||||
import path from "node:path";
|
||||
import createEsmUtils from "esm-utils";
|
||||
|
||||
const { require } = createEsmUtils(import.meta);
|
||||
|
||||
/**
|
||||
* @typedef {Object} Bundle
|
||||
@@ -7,8 +10,6 @@ import path from "node:path";
|
||||
* @property {string?} name - name for the UMD bundle (for plugins, it'll be `prettierPlugins.${name}`)
|
||||
* @property {'node' | 'universal'} target - should generate a CJS only for node or universal bundle
|
||||
* @property {'core' | 'plugin'} type - it's a plugin bundle or core part of prettier
|
||||
* @property {'rollup' | 'webpack'} [bundler='rollup'] - define which bundler to use
|
||||
* @property {CommonJSConfig} [commonjs={}] - options for `rollup-plugin-commonjs`
|
||||
* @property {string[]} external - array of paths that should not be included in the final bundle
|
||||
* @property {Object.<string, string | {code: string}>} replaceModule - module replacement path or code
|
||||
* @property {Object.<string, string>} replace - map of strings to replace when processing the bundle
|
||||
@@ -46,6 +47,7 @@ const parsers = [
|
||||
// `rollup-plugin-polyfill-node` don't have polyfill for these modules
|
||||
'require("perf_hooks")': "{}",
|
||||
'require("inspector")': "{}",
|
||||
"_fs.realpathSync.native": "_fs.realpathSync && _fs.realpathSync.native",
|
||||
// Dynamic `require()`s
|
||||
"ts.sys && ts.sys.require": "false",
|
||||
"require(etwModulePath)": "undefined",
|
||||
@@ -66,6 +68,9 @@ const parsers = [
|
||||
},
|
||||
{
|
||||
input: "src/language-js/parse/angular.js",
|
||||
replace: {
|
||||
"@angular/compiler/src": "@angular/compiler/esm2015/src",
|
||||
},
|
||||
},
|
||||
{
|
||||
input: "src/language-css/parser-postcss.js",
|
||||
@@ -77,22 +82,18 @@ const parsers = [
|
||||
"node.constructor.name === 'Word'": "node.type === 'word'",
|
||||
},
|
||||
},
|
||||
{
|
||||
input: "dist/parser-postcss.js",
|
||||
output: "esm/parser-postcss.mjs",
|
||||
format: "esm",
|
||||
},
|
||||
{
|
||||
input: "src/language-graphql/parser-graphql.js",
|
||||
},
|
||||
{
|
||||
input: "src/language-markdown/parser-markdown.js",
|
||||
replaceModule: {
|
||||
[require.resolve("parse-entities/decode-entity.browser.js")]:
|
||||
require.resolve("parse-entities/decode-entity.js"),
|
||||
},
|
||||
},
|
||||
{
|
||||
input: "src/language-handlebars/parser-glimmer.js",
|
||||
commonjs: {
|
||||
ignore: ["source-map"],
|
||||
},
|
||||
},
|
||||
{
|
||||
input: "src/language-html/parser-html.js",
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
{}
|
||||
@@ -0,0 +1,22 @@
|
||||
import createEsmUtils from "esm-utils";
|
||||
|
||||
const { require } = createEsmUtils(import.meta);
|
||||
|
||||
export default function esbuildPluginEvaluate() {
|
||||
return {
|
||||
name: "evaluate",
|
||||
|
||||
setup(build) {
|
||||
build.onLoad({ filter: /\.evaluate\.js$/ }, ({ path }) => {
|
||||
const json = JSON.stringify(require(path), (_, v) => {
|
||||
if (typeof v === "function") {
|
||||
throw new TypeError("Cannot evaluate functions.");
|
||||
}
|
||||
return v;
|
||||
});
|
||||
|
||||
return { loader: "json", contents: json };
|
||||
});
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import rollupPluginLicense from "rollup-plugin-license";
|
||||
|
||||
export default function esbuildPluginLicense(options) {
|
||||
const plugin = rollupPluginLicense(options);
|
||||
|
||||
return {
|
||||
name: "license",
|
||||
|
||||
setup(build) {
|
||||
build.initialOptions.metafile = true;
|
||||
|
||||
build.onEnd((result) => {
|
||||
const files = Object.keys(result.metafile.inputs);
|
||||
const chunk = {
|
||||
modules: Object.fromEntries(
|
||||
files.map((file) => [file, { renderedLength: 1 }])
|
||||
),
|
||||
};
|
||||
plugin.renderChunk("", chunk);
|
||||
plugin.generateBundle();
|
||||
});
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
import fs from "node:fs";
|
||||
|
||||
export default function esbuildPluginReplaceModule(replacements = {}) {
|
||||
return {
|
||||
name: "replace-module",
|
||||
setup(build) {
|
||||
build.onLoad({ filter: /./ }, ({ path }) => {
|
||||
if (!Reflect.has(replacements, path)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const replacement = replacements[path];
|
||||
|
||||
if (typeof replacement === "string") {
|
||||
return {
|
||||
contents: `module.exports = require(${JSON.stringify(
|
||||
replacement
|
||||
)});`,
|
||||
};
|
||||
}
|
||||
|
||||
if (replacement.file) {
|
||||
return {
|
||||
contents: fs.readFileSync(replacement.file, "utf8"),
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
contents: replacement.code,
|
||||
};
|
||||
});
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
import fs from "node:fs";
|
||||
import camelCase from "camelcase";
|
||||
import { outdent } from "outdent";
|
||||
|
||||
function getUmdWrapper(name, build) {
|
||||
const path = name.split(".");
|
||||
const { minify } = build.initialOptions;
|
||||
const temporaryName = minify ? "m" : camelCase(name);
|
||||
const placeholder = "/*! bundled code !*/";
|
||||
|
||||
let globalObjectText = [];
|
||||
for (let index = 0; index < path.length; index++) {
|
||||
const object = ["root", ...path.slice(0, index + 1)].join(".");
|
||||
if (index === path.length - 1) {
|
||||
globalObjectText.push(`${object} = factory();`);
|
||||
} else {
|
||||
globalObjectText.push(`${object} = ${object} || {};`);
|
||||
}
|
||||
}
|
||||
globalObjectText = globalObjectText
|
||||
.map((text) => `${" ".repeat(4)}${text}`)
|
||||
.join("\n");
|
||||
|
||||
let wrapper = outdent`
|
||||
(function (factory) {
|
||||
if (typeof exports === "object" && typeof module === "object") {
|
||||
module.exports = factory();
|
||||
} else if (typeof define === "function" && define.amd) {
|
||||
define(factory);
|
||||
} else {
|
||||
var root =
|
||||
typeof globalThis !== "undefined"
|
||||
? globalThis
|
||||
: typeof global !== "undefined"
|
||||
? global
|
||||
: typeof self !== "undefined"
|
||||
? self
|
||||
: this || {};
|
||||
${globalObjectText.trimStart()}
|
||||
}
|
||||
})(function() {
|
||||
${placeholder}
|
||||
return ${temporaryName};
|
||||
});
|
||||
`;
|
||||
|
||||
if (minify) {
|
||||
wrapper = build.esbuild
|
||||
.buildSync({ stdin: { contents: wrapper }, minify, write: false })
|
||||
.outputFiles[0].text.trim();
|
||||
}
|
||||
|
||||
const [intro, outro] = wrapper.split(placeholder);
|
||||
|
||||
return {
|
||||
name: temporaryName,
|
||||
intro,
|
||||
outro,
|
||||
expectedOutput: `"use strict";${minify ? "" : "\n"}var ${temporaryName}${
|
||||
minify ? "=" : " = "
|
||||
}`,
|
||||
};
|
||||
}
|
||||
|
||||
export default function esbuildPluginUmd({ name }) {
|
||||
return {
|
||||
name: "umd",
|
||||
setup(build) {
|
||||
const options = build.initialOptions;
|
||||
const { globalName, format, outfile } = options;
|
||||
|
||||
if (globalName) {
|
||||
throw new Error("'globalName' in options cannot be set.");
|
||||
}
|
||||
|
||||
if (format !== "umd") {
|
||||
throw new Error("'format' options must be 'umd'.");
|
||||
}
|
||||
|
||||
if (!outfile) {
|
||||
throw new Error("'outfile' options is required.");
|
||||
}
|
||||
|
||||
const {
|
||||
name: temporaryName,
|
||||
intro,
|
||||
outro,
|
||||
expectedOutput,
|
||||
} = getUmdWrapper(name, build);
|
||||
options.globalName = temporaryName;
|
||||
options.format = "iife";
|
||||
|
||||
build.onEnd(() => {
|
||||
if (!fs.existsSync(outfile)) {
|
||||
throw new Error(`${outfile} not exists`);
|
||||
}
|
||||
const text = fs.readFileSync(outfile, "utf8");
|
||||
const actualOutput = text.slice(0, expectedOutput.length);
|
||||
if (actualOutput !== expectedOutput) {
|
||||
console.log();
|
||||
console.error(outdent`
|
||||
Expected output starts with:
|
||||
${expectedOutput}
|
||||
|
||||
Got:
|
||||
${actualOutput}
|
||||
`);
|
||||
throw new Error("Unexpected output");
|
||||
}
|
||||
|
||||
fs.writeFileSync(outfile, intro + text.trim() + outro);
|
||||
});
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
import createEsmUtils from "esm-utils";
|
||||
|
||||
const { require } = createEsmUtils(import.meta);
|
||||
|
||||
export default function rollupPluginEvaluate() {
|
||||
return {
|
||||
name: "evaluate",
|
||||
|
||||
transform(_text, id) {
|
||||
if (!/\.evaluate\.js$/.test(id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const json = JSON.stringify(
|
||||
require(id.replace(/^\0commonjs-proxy:/, "")),
|
||||
(_, v) => {
|
||||
if (typeof v === "function") {
|
||||
throw new TypeError("Cannot evaluate functions.");
|
||||
}
|
||||
return v;
|
||||
}
|
||||
);
|
||||
|
||||
return {
|
||||
code: `export default ${json};`,
|
||||
map: { mappings: "" },
|
||||
};
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
|
||||
export default function rollupPluginExecutable() {
|
||||
let banner;
|
||||
let entry;
|
||||
let file;
|
||||
|
||||
return {
|
||||
name: "executable",
|
||||
|
||||
options(inputOptions) {
|
||||
entry = path.resolve(inputOptions.input);
|
||||
},
|
||||
|
||||
generateBundle(outputOptions) {
|
||||
file = outputOptions.file;
|
||||
},
|
||||
|
||||
load(id) {
|
||||
if (id !== entry) {
|
||||
return;
|
||||
}
|
||||
const source = fs.readFileSync(id, "utf-8");
|
||||
const match = source.match(/^\s*(#!.*)/);
|
||||
if (match) {
|
||||
banner = match[1];
|
||||
return (
|
||||
source.slice(0, match.index) +
|
||||
source.slice(match.index + banner.length)
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
renderChunk(code) {
|
||||
if (banner) {
|
||||
return { code: banner + "\n" + code };
|
||||
}
|
||||
},
|
||||
|
||||
writeBundle() {
|
||||
if (banner && file) {
|
||||
fs.chmodSync(file, 0o755 & ~process.umask());
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
export default function rollupPluginReplaceModule(replacements = {}) {
|
||||
return {
|
||||
name: "replace-module",
|
||||
|
||||
load(importee) {
|
||||
if (!Reflect.has(replacements, importee)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const replacement = replacements[importee];
|
||||
|
||||
if (typeof replacement === "string") {
|
||||
return `export default require(${JSON.stringify(replacement)});`;
|
||||
}
|
||||
|
||||
return replacement.code;
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
import path from "node:path";
|
||||
import { promises as fs } from "node:fs";
|
||||
import { outdent } from "outdent";
|
||||
import { DIST_DIR } from "../utils/index.mjs";
|
||||
|
||||
const file = path.join(DIST_DIR, "LICENSE");
|
||||
const separator = `\n${"-".repeat(40)}\n\n`;
|
||||
|
||||
async function saveLicenses(dependencies) {
|
||||
// Unique by `name` and `version`
|
||||
dependencies = dependencies.filter(
|
||||
(dependency, index) =>
|
||||
index ===
|
||||
dependencies.findIndex(
|
||||
({ name, version }) =>
|
||||
dependency.name === name && dependency.version === version
|
||||
)
|
||||
);
|
||||
|
||||
dependencies.sort(
|
||||
(dependencyA, dependencyB) =>
|
||||
dependencyA.name.localeCompare(dependencyB.name) ||
|
||||
dependencyA.version.localeCompare(dependencyB.version)
|
||||
);
|
||||
|
||||
const prettierLicense = await fs.readFile(file, "utf8");
|
||||
|
||||
const licenses = [
|
||||
...new Set(
|
||||
dependencies
|
||||
.filter(({ license }) => license)
|
||||
.map(({ license }) => license)
|
||||
),
|
||||
];
|
||||
const text = outdent`
|
||||
# Prettier license
|
||||
|
||||
Prettier is released under the MIT license:
|
||||
|
||||
${prettierLicense.trim()}
|
||||
|
||||
## Licenses of bundled dependencies
|
||||
|
||||
The published Prettier artifact additionally contains code with the following licenses:
|
||||
${licenses.join(", ")}
|
||||
|
||||
## Bundled dependencies
|
||||
`;
|
||||
|
||||
const content = dependencies
|
||||
.map((dependency) => {
|
||||
let text = `### ${dependency.name}@v${dependency.version}\n`;
|
||||
|
||||
const meta = [];
|
||||
|
||||
if (dependency.license) {
|
||||
meta.push(`License: ${dependency.license}`);
|
||||
}
|
||||
if (dependency.author?.name) {
|
||||
meta.push(`By: ${dependency.author.name}`);
|
||||
}
|
||||
if (dependency.repository?.url) {
|
||||
meta.push(`Repository: <${dependency.repository.url}>`);
|
||||
}
|
||||
|
||||
if (meta.length > 0) {
|
||||
text += "\n" + meta.join("\n") + "\n";
|
||||
}
|
||||
|
||||
if (dependency.licenseText) {
|
||||
text +=
|
||||
"\n" +
|
||||
dependency.licenseText
|
||||
.trim()
|
||||
.split("\n")
|
||||
.map((line) => (line ? `> ${line}` : ">"))
|
||||
.join("\n") +
|
||||
"\n";
|
||||
}
|
||||
return text;
|
||||
})
|
||||
.join(separator);
|
||||
|
||||
await fs.writeFile(file, text + "\n\n" + content);
|
||||
}
|
||||
|
||||
export default saveLicenses;
|
||||
@@ -1,4 +0,0 @@
|
||||
function assert() {}
|
||||
assert.ok = function () {};
|
||||
assert.strictEqual = function () {};
|
||||
export default assert;
|
||||
@@ -1 +0,0 @@
|
||||
export class EventEmitter {}
|
||||
@@ -1,4 +0,0 @@
|
||||
export const existsSync = () => false;
|
||||
export const readFileSync = () => "";
|
||||
const fs = { existsSync, readFileSync };
|
||||
export default fs;
|
||||
@@ -1,6 +0,0 @@
|
||||
const os = {
|
||||
EOL: "\n",
|
||||
platform: () => "browser",
|
||||
cpus: () => [{ model: "Prettier" }],
|
||||
};
|
||||
export default os;
|
||||
@@ -1,2 +0,0 @@
|
||||
export * from "path-browserify";
|
||||
export { default } from "path-browserify";
|
||||
@@ -1,6 +0,0 @@
|
||||
const tty = {
|
||||
isatty() {
|
||||
return false;
|
||||
},
|
||||
};
|
||||
export default tty;
|
||||
@@ -2,7 +2,7 @@ import chalk from "chalk";
|
||||
import { runYarn, logPromise, readJson } from "../utils.js";
|
||||
|
||||
export default async function generateBundles({ version }) {
|
||||
await logPromise("Generating bundles", runYarn(["build", "--no-cache"]));
|
||||
await logPromise("Generating bundles", runYarn(["build"]));
|
||||
|
||||
const builtPkg = await readJson("dist/package.json");
|
||||
if (builtPkg.version !== version) {
|
||||
|
||||
@@ -28,14 +28,12 @@ async function writeFile(file, content) {
|
||||
}
|
||||
|
||||
const PROJECT_ROOT = url.fileURLToPath(new URL("../../", import.meta.url));
|
||||
const BUILD_CACHE_DIR = path.join(PROJECT_ROOT, ".cache");
|
||||
const DIST_DIR = path.join(PROJECT_ROOT, "dist");
|
||||
const WEBSITE_DIR = path.join(PROJECT_ROOT, "website");
|
||||
|
||||
export {
|
||||
PROJECT_ROOT,
|
||||
DIST_DIR,
|
||||
BUILD_CACHE_DIR,
|
||||
WEBSITE_DIR,
|
||||
readJson,
|
||||
writeJson,
|
||||
|
||||
Reference in new issue
Block a user