beesbuild
Version:
构建工具链
268 lines (267 loc) • 9.13 kB
JavaScript
import path from "path";
import chalk from "chalk-unified";
import { consola, generateExternal, getBuildConfig, parseManifest, target } from "@beesbuild/utils";
import { copy, existsSync, rm, rmSync } from "fs-extra";
import { rollup } from "rollup";
import { defu } from "defu";
import { flattenDeep, fromPairs, merge, omit } from "lodash-unified";
import { default as terserPlugin } from "@rollup/plugin-terser";
import { minify as minifyPlugin } from "rollup-plugin-esbuild";
import { arrayIncludes, getpkg } from "../utils.mjs";
import { BUILD_CACHE_DIR } from "../variables.mjs";
import getRollupPlugins from "./plugins/index.mjs";
import { rollupWatch } from "./watch.mjs";
function getRollupOptions(ctx) {
var _a, _b, _c;
const rollup2 = ctx.options.rollup;
const external = generateExternal({
full: false,
dependencies: ctx.options.dependencies,
peerDependencies: ctx.options.peerDependencies
});
const plugins = getRollupPlugins(ctx);
const entries = ctx.options.entries;
const externals = ctx.options.externals;
const input = entries.filter((entry) => entry.builder === "rollup").map((entry) => path.resolve(ctx.options.rootDir, entry.input));
let logLevel = "warn";
if (((_a = ctx.options) == null ? void 0 : _a.debug) === true) {
logLevel = "info";
} else if (((_b = ctx.options) == null ? void 0 : _b.verbose) === true) {
logLevel = "warn";
}
return {
input,
plugins: plugins.length > 0 ? plugins : null,
external(id, importer, isResolved) {
var _a2;
const pkg = getpkg(id);
const isExplicitExternal = arrayIncludes(externals, pkg) || arrayIncludes(externals, id);
if (isExplicitExternal) {
return true;
}
if (rollup2.inlineDependencies || id[0] === "." || path.isAbsolute(id) || /src[/\\]/.test(id) || id.startsWith(ctx.pkg.name)) {
return external(id, importer, isResolved);
}
if (!isExplicitExternal) {
((_a2 = ctx.options) == null ? void 0 : _a2.debug) && consola.warn(`Inlined implicit external ${id}`);
return external(id, importer, isResolved);
}
return isExplicitExternal;
},
treeshake: (_c = ctx.options) == null ? void 0 : _c.treeshake,
logLevel
};
}
async function rollupBuild(ctx) {
var _a, _b;
const options = getRollupOptions(ctx);
await ctx.hooks.callHook("rollup:options", ctx, options);
if (Object.keys(options.input).length === 0) {
return;
}
const rollupBundle = await rollup(options);
await ctx.hooks.callHook("rollup:build", ctx, rollupBundle);
const rollupOptions = ctx.options.rollup;
const entries = ctx.options.entries;
const rootDir = ctx.options.rootDir;
const outDir = ctx.options.outDir || ".";
const entryFile = entries.find(({ isEntry }) => isEntry);
const buildEntries = getBuildConfig({
rootDir,
outDir,
manifest: merge({}, ctx.pkg, ctx.pkg.publishConfig),
rollup: omit(rollupOptions, "vue", "vueJsx", "vueMacros"),
entryFile: entryFile == null ? void 0 : entryFile.input
});
const rollupOutput = (_a = rollupOptions == null ? void 0 : rollupOptions.output) != null ? _a : {};
consola.info(
buildEntries.map(([module]) => module),
"buildEntries"
);
const preserveModulesRoot = path.join(rootDir, "src");
((_b = ctx == null ? void 0 : ctx.argv) == null ? void 0 : _b.debug) && consola.info(chalk.gray(preserveModulesRoot, "preserveModulesRoot"));
const outputs = buildEntries.map(
([
module,
{
format,
root,
optionConfig,
bundle: bundle2,
ext,
output: { name: outputName }
}
]) => {
var _a2, _b2, _c, _d;
const options2 = (_a2 = rollupOutput == null ? void 0 : rollupOutput[module]) != null ? _a2 : {};
const output = defu(
{ _module: module },
options2,
optionConfig,
{
preserveModules: true,
preserveModulesRoot
}
);
output.entryFileNames = `[name].${ext}`;
if (module !== "umd") {
output.dir = path.resolve(root, ".", BUILD_CACHE_DIR, outputName);
} else {
output.file = bundle2.path;
}
if (optionConfig == null ? void 0 : optionConfig.exports) {
output.exports = optionConfig.exports;
}
if ((_b2 = ctx.options) == null ? void 0 : _b2.sourcemap) {
output.sourcemap = true;
}
if (((_c = ctx.options) == null ? void 0 : _c.minify) && ["cjs", "umd"].includes(format)) {
const minify = (_d = ctx.options) == null ? void 0 : _d.minify;
const plugins = flattenDeep([output.plugins]);
switch (true) {
case minify === true:
case minify === "esbuild":
output.plugins = [
minifyPlugin({
target,
drop: ["debugger", "console"]
})
].concat(plugins);
break;
default:
output.plugins = [
terserPlugin({
compress: {
drop_console: true,
drop_debugger: true
// // 在 `compress` 选项中,你可以指定自定义的规则来处理 `console.log`
// global_defs: {
// 'console.log': () => '', // 将 `console.log` 替换为一个空函数
// },
}
})
].concat(plugins);
}
output.plugins = output.plugins.filter(Boolean);
}
return output;
}
);
const watchOptions = {
...rollupOptions,
output: outputs
};
function getBundleOptions(module, files) {
const { root, output, ext } = bundle.buildConfig[module];
const src = path.resolve(root, ".", BUILD_CACHE_DIR, output.name);
let filesPaths = [];
if (files && files.length > 0) {
filesPaths = files.map((filePath) => {
const { dir, name } = parseManifest(filePath, rootDir);
const relativeFilePath = path.join(
path.relative(preserveModulesRoot, dir),
`${name}.${ext}`
);
consola.info(chalk.cyan(`Start for copy file: ${relativeFilePath} generated`));
return {
cacheFilePath: path.resolve(src, relativeFilePath),
outputFilePath: path.resolve(output.path, relativeFilePath)
};
});
}
return {
cacheDir: src,
outputDir: output.path,
filesPaths
};
}
const bundle = {
...rollupBundle,
buildConfig: fromPairs(buildEntries),
delete: (module, files) => {
const { cacheDir, outputDir, filesPaths } = getBundleOptions(module, files);
const paths = [];
if (filesPaths) {
for (const { cacheFilePath, outputFilePath } of filesPaths) {
paths.push(cacheFilePath, outputFilePath);
}
} else {
paths.push(cacheDir, outputDir);
}
return Promise.allSettled(
paths.map((file) => {
if (existsSync(file)) {
consola.info(
chalk.cyan(
`Start for delete file: `,
path.relative(ctx.options.rootDir, file),
` generated`
)
);
return rm(file, { recursive: true });
}
return Promise.resolve();
})
);
},
copy: (module, files) => {
const { cacheDir, outputDir, filesPaths } = getBundleOptions(module, files);
const paths = [];
if (filesPaths && filesPaths.length > 0) {
for (const { cacheFilePath, outputFilePath } of filesPaths) {
paths.push([cacheFilePath, outputFilePath]);
}
} else {
paths.push([cacheDir, outputDir]);
}
consola.info(chalk.cyan("Start for copy file!"));
return Promise.allSettled(
paths.map(([form, to]) => {
consola.info(
chalk.cyan(
`Start for copy \u6765\u6E90: `,
path.relative(ctx.options.rootDir, form),
` ==> `,
path.relative(ctx.options.rootDir, to),
` generated`
)
);
return copy(form, to, {
overwrite: true
});
})
);
},
build: () => writeBundles(rollupBundle, outputs)
};
return {
watchOptions,
build: () => writeBundles(rollupBundle, outputs),
copy: () => copyBundles(bundle, buildEntries),
watch: () => rollupWatch(ctx, watchOptions, bundle)
};
}
const copyBundles = (bundle, options) => {
return Promise.allSettled(
options.map(async ([module]) => {
(bundle == null ? void 0 : bundle.copy) && await bundle.copy(module);
return Promise.resolve();
})
);
};
async function writeBundles(bundle, options) {
await Promise.allSettled(
options.map(async (option) => {
option.dir && existsSync(option.dir) && rmSync(option.dir, { recursive: true });
(bundle == null ? void 0 : bundle.write) && await bundle.write(option);
return Promise.resolve();
})
);
return Promise.resolve();
}
export {
copyBundles,
getRollupOptions,
rollupBuild,
writeBundles
};