196 lines
4.7 KiB
TypeScript
Executable File
196 lines
4.7 KiB
TypeScript
Executable File
#!/usr/bin/env tsx
|
|
import { promises as fs } from 'node:fs';
|
|
import { isBuiltin } from 'node:module';
|
|
import { relative, resolve } from 'node:path';
|
|
|
|
import esbuild from 'esbuild';
|
|
import type { Plugin } from 'esbuild';
|
|
import { memoize } from 'lodash-es';
|
|
import c from 'picocolors';
|
|
import { minify_sync } from 'terser';
|
|
|
|
import { dependencies } from '../dist/package.json';
|
|
|
|
import { dts } from './dts';
|
|
import { babelPlugin } from './modifier';
|
|
|
|
const ENV = (process.env.NODE_ENV ??= 'production');
|
|
const PROD = ENV === 'production';
|
|
|
|
const { gray, green } = c;
|
|
|
|
declare global {
|
|
interface Array<T> {
|
|
filter(
|
|
predicate: BooleanConstructor,
|
|
): Exclude<T, null | undefined | false | '' | 0>[];
|
|
}
|
|
}
|
|
|
|
const log = memoize(console.log);
|
|
|
|
const plugins: Plugin[] = [
|
|
babelPlugin,
|
|
{
|
|
name: 'alias',
|
|
setup(build) {
|
|
build.onResolve({ filter: /^jsx-ast-utils$/ }, () => ({
|
|
path: resolve('./packages/jsx-ast-utils/src/index.js'),
|
|
}));
|
|
build.onResolve({ filter: /^jsx-ast-utils\/.+$/ }, ({ path }) => ({
|
|
path:
|
|
resolve('./packages/jsx-ast-utils/', path.slice('jsx-ast-utils/'.length)) +
|
|
'.js',
|
|
}));
|
|
},
|
|
},
|
|
];
|
|
|
|
if (process.env.DEBUG) {
|
|
plugins.push({
|
|
name: 'deps-check',
|
|
setup(build) {
|
|
const declared = new Set(Object.keys(dependencies));
|
|
|
|
build.onResolve({ filter: /^.*$/ }, ({ path, importer }) => {
|
|
if (
|
|
!path.startsWith('./') &&
|
|
!path.startsWith('../') &&
|
|
!isBuiltin(path) &&
|
|
path !== 'eslint' &&
|
|
!path.startsWith('eslint/') &&
|
|
!path.startsWith('eslint-module-utils/') &&
|
|
!declared.has(path)
|
|
) {
|
|
log(green(path), gray('from'), './' + relative(process.cwd(), importer));
|
|
}
|
|
return null;
|
|
});
|
|
},
|
|
});
|
|
}
|
|
|
|
async function bundle(
|
|
entry: string,
|
|
outfile: string,
|
|
options?: esbuild.BuildOptions & { treeShaking?: boolean },
|
|
) {
|
|
const output = await esbuild.build({
|
|
entryPoints: [entry],
|
|
outfile,
|
|
bundle: true,
|
|
minify: PROD,
|
|
platform: 'node',
|
|
packages: 'external',
|
|
sourcemap: 'linked',
|
|
plugins,
|
|
define: {},
|
|
alias: {},
|
|
format: 'esm',
|
|
banner: {
|
|
js: '/* eslint-disable */',
|
|
},
|
|
...options,
|
|
});
|
|
|
|
if (options?.treeShaking) {
|
|
const [text, setText] = await useText(outfile);
|
|
const minified = minify_sync(text, {
|
|
module: true,
|
|
compress: {
|
|
conditionals: true,
|
|
dead_code: true,
|
|
defaults: false,
|
|
evaluate: true,
|
|
passes: 3,
|
|
pure_new: true,
|
|
side_effects: true,
|
|
unused: true,
|
|
},
|
|
mangle: false,
|
|
format: {
|
|
comments: true,
|
|
},
|
|
});
|
|
await setText(minified.code!);
|
|
}
|
|
|
|
return output;
|
|
}
|
|
|
|
async function editPackageJson() {
|
|
const [state, setState] = await useText('./dist/package.json');
|
|
const distPackageJson = JSON.parse(state);
|
|
|
|
const overrideList = await fs.readdir('dist/overrides');
|
|
const npmOverrides = Object.fromEntries(
|
|
overrideList.map(name => [name, `file:./overrides/${name}`]),
|
|
);
|
|
Object.assign(distPackageJson, {
|
|
overrides: npmOverrides,
|
|
resolutions: Object.fromEntries(
|
|
overrideList.map(name => [`**/${name}`, `file:./overrides/${name}`]),
|
|
),
|
|
pnpm: { overrides: npmOverrides },
|
|
});
|
|
|
|
await setState(JSON.stringify(distPackageJson, null, 2) + '\n');
|
|
}
|
|
|
|
async function useText(path: string) {
|
|
const state = await fs.readFile(path, 'utf8');
|
|
const setState = (text: string) => fs.writeFile(path, text);
|
|
return [state, setState] as const;
|
|
}
|
|
|
|
function bundleType(source: string, output: string) {
|
|
try {
|
|
return dts({
|
|
source,
|
|
dist: output,
|
|
project: './tsconfig.build.json',
|
|
});
|
|
} catch {
|
|
// noop
|
|
}
|
|
}
|
|
|
|
async function main() {
|
|
console.log('Building type definitions…');
|
|
try {
|
|
await fs.rm('dist/config', { recursive: true });
|
|
} catch {
|
|
// noop
|
|
}
|
|
|
|
bundleType('./src/prettier.ts', './dist/prettier.d.ts');
|
|
bundleType('./src/types.ts', './dist/types.d.ts');
|
|
|
|
const unminify = { minify: false };
|
|
|
|
console.log('Building packages…');
|
|
await Promise.all([
|
|
bundle('./src/index.ts', undefined!, {
|
|
format: 'esm',
|
|
splitting: true,
|
|
outdir: './dist/config',
|
|
...unminify,
|
|
}),
|
|
bundle('./src/types.ts', './dist/types.js', unminify),
|
|
bundle('./src/prettier.ts', './dist/prettier.js', unminify),
|
|
bundle('./src/install.ts', './dist/install.js', {
|
|
treeShaking: true,
|
|
minify: false,
|
|
banner: {
|
|
js: '#!/usr/bin/env node\n/* eslint-disable */',
|
|
},
|
|
}),
|
|
editPackageJson(),
|
|
]);
|
|
|
|
// bundleType('./src/index.ts', './dist/config/index.d.ts');
|
|
await fs.copyFile('./src/config.d.ts', './dist/config/index.d.ts');
|
|
}
|
|
|
|
void main();
|