mirror of
https://github.com/toss/es-toolkit.git
synced 2024-11-28 03:34:26 +03:00
831501ad92
* config: disable sourcemaps for esm & cjs builds * config: keep jsdoc comments when not generating sourcemaps * config: tweak browser build minification for readability * config(terser): use ecma:2020 option, since tsconfig target is es2020
190 lines
5.0 KiB
JavaScript
190 lines
5.0 KiB
JavaScript
// @ts-check
|
|
|
|
import fs from 'node:fs';
|
|
import { createRequire } from 'node:module';
|
|
import { dirname, join } from 'node:path';
|
|
import { fileURLToPath } from 'node:url';
|
|
import terserPlugin from '@rollup/plugin-terser';
|
|
import tsPlugin from '@rollup/plugin-typescript';
|
|
import dtsPlugin from 'rollup-plugin-dts';
|
|
|
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
|
|
/**
|
|
* @type {{
|
|
* exports: Record<string, string>;
|
|
* publishConfig: { browser: string };
|
|
* }}
|
|
*/
|
|
const packageJson = createRequire(import.meta.url)('./package.json');
|
|
|
|
const testPatterns = ['**/*.bench.ts', '**/*.spec.ts', '**/*.test.ts'];
|
|
|
|
export default () => {
|
|
clearDir('dist');
|
|
|
|
const entrypoints = Object.values(packageJson.exports).filter(f => /^(\.\/)?src\//.test(f) && f.endsWith('.ts'));
|
|
|
|
return [
|
|
libBuildOptions({
|
|
format: 'esm',
|
|
extension: 'mjs',
|
|
entrypoints,
|
|
outDir: 'dist',
|
|
sourcemap: false,
|
|
}),
|
|
libBuildOptions({
|
|
format: 'cjs',
|
|
extension: 'js',
|
|
entrypoints,
|
|
outDir: 'dist',
|
|
sourcemap: false,
|
|
}),
|
|
declarationOptions({
|
|
entrypoints,
|
|
outDir: 'dist',
|
|
}),
|
|
browserBuildConfig({
|
|
inputFile: './src/compat/index.ts',
|
|
outFile: packageJson.publishConfig.browser,
|
|
name: '_',
|
|
sourcemap: true,
|
|
}),
|
|
];
|
|
};
|
|
|
|
/**
|
|
* @type {(options: {
|
|
* entrypoints: string[];
|
|
* format: 'esm' | 'cjs';
|
|
* extension: 'js' | 'cjs' | 'mjs';
|
|
* outDir: string;
|
|
* sourcemap: boolean;
|
|
* }) => import('rollup').RollupOptions}
|
|
*/
|
|
function libBuildOptions({ entrypoints, extension, format, outDir, sourcemap }) {
|
|
const isESM = format === 'esm';
|
|
|
|
return {
|
|
input: mapInputs(entrypoints),
|
|
plugins: [
|
|
tsPlugin({
|
|
exclude: [...testPatterns],
|
|
compilerOptions: {
|
|
sourceMap: sourcemap,
|
|
inlineSources: sourcemap || undefined,
|
|
removeComments: !sourcemap,
|
|
declaration: false,
|
|
},
|
|
}),
|
|
],
|
|
output: {
|
|
format,
|
|
dir: outDir,
|
|
...fileNames(extension),
|
|
// Using preserveModules disables bundling and the creation of chunks,
|
|
// leading to a result that is a mirror of the input module graph.
|
|
preserveModules: isESM,
|
|
sourcemap,
|
|
generatedCode: 'es2015',
|
|
// Hoisting transitive imports adds bare imports in modules,
|
|
// which can make imports by JS runtimes slightly faster,
|
|
// but makes the generated code harder to follow.
|
|
hoistTransitiveImports: false,
|
|
},
|
|
};
|
|
}
|
|
|
|
/**
|
|
* @type {(options: {inputFile: string; outFile: string; name: string, sourcemap: boolean}) => import('rollup').RollupOptions}
|
|
*/
|
|
function browserBuildConfig({ inputFile, outFile, name, sourcemap }) {
|
|
return {
|
|
input: inputFile,
|
|
plugins: [
|
|
tsPlugin({
|
|
exclude: [...testPatterns],
|
|
compilerOptions: {
|
|
sourceMap: sourcemap,
|
|
inlineSources: sourcemap || undefined,
|
|
removeComments: true,
|
|
declaration: false,
|
|
},
|
|
}),
|
|
],
|
|
output: {
|
|
plugins: [
|
|
// Minify with terser, but with a configuration that optimizes for
|
|
// readability in browser DevTools (after re-indenting by DevTools).
|
|
terserPlugin({
|
|
// Terser defaults to ES5 for syntax it adds or rewrites
|
|
ecma: 2020,
|
|
// Readable function names (not just in final export)
|
|
keep_fnames: true,
|
|
// Turn off compress.sequences to keep the assignments to the toolkit
|
|
// object readable, instead of turning them into a huge list of
|
|
// comma-separated expressions.
|
|
compress: { sequences: false },
|
|
}),
|
|
],
|
|
format: 'iife',
|
|
name,
|
|
file: outFile,
|
|
sourcemap,
|
|
generatedCode: 'es2015',
|
|
},
|
|
};
|
|
}
|
|
|
|
/**
|
|
* @type {(options: {entrypoints: string[]; outDir: string}) => import('rollup').RollupOptions}
|
|
*/
|
|
function declarationOptions({ entrypoints, outDir }) {
|
|
return {
|
|
plugins: [dtsPlugin()],
|
|
input: mapInputs(entrypoints),
|
|
output: [
|
|
{
|
|
format: 'esm',
|
|
dir: outDir,
|
|
generatedCode: 'es2015',
|
|
...fileNames('d.mts'),
|
|
preserveModules: true,
|
|
preserveModulesRoot: 'src',
|
|
},
|
|
{
|
|
format: 'cjs',
|
|
dir: outDir,
|
|
generatedCode: 'es2015',
|
|
...fileNames('d.ts'),
|
|
preserveModules: true,
|
|
preserveModulesRoot: 'src',
|
|
},
|
|
],
|
|
};
|
|
}
|
|
|
|
/** @type {(srcFiles: string[]) => Record<string, string>} */
|
|
function mapInputs(srcFiles) {
|
|
return Object.fromEntries(
|
|
srcFiles.map(file => [file.replace(/^(\.\/)?src\//, '').replace(/\.[cm]?(js|ts)$/, ''), join(__dirname, file)])
|
|
);
|
|
}
|
|
|
|
function fileNames(extension = 'js') {
|
|
return {
|
|
entryFileNames: `[name].${extension}`,
|
|
chunkFileNames: `_chunk/[name]-[hash:6].${extension}`,
|
|
};
|
|
}
|
|
|
|
/** @type {(dir: string) => void} */
|
|
function clearDir(dir) {
|
|
const dirPath = join(__dirname, dir);
|
|
if (dir && fs.existsSync(dirPath)) {
|
|
fs.rmSync(dirPath, { recursive: true, force: true });
|
|
console.log(`cleared: ${dir}`);
|
|
}
|
|
}
|