UNPKG

@strapi/pack-up

Version:

Simple tools for creating interoperable CJS & ESM packages.

520 lines (519 loc) 18.4 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); const path = require("path"); const chalk = require("chalk"); const os = require("os"); const rxjs = require("rxjs"); const ts = require("typescript"); const errors = require("./errors-BG4CMlQA.js"); const createBuildContext = require("./createBuildContext-Degoc55x.js"); const react = require("@vitejs/plugin-react-swc"); const node_module = require("node:module"); const _interopDefault = (e) => e && e.__esModule ? e : { default: e }; const path__default = /* @__PURE__ */ _interopDefault(path); const chalk__default = /* @__PURE__ */ _interopDefault(chalk); const os__default = /* @__PURE__ */ _interopDefault(os); const ts__default = /* @__PURE__ */ _interopDefault(ts); const react__default = /* @__PURE__ */ _interopDefault(react); const createTasks = (mode) => async (ctx) => { const tasks = []; const dtsTask = { type: `${mode}:dts`, entries: [] }; const viteTasks = {}; const createViteTask = (format, runtime, { output, ...restEntry }) => { const buildId = `${format}:${output}`; if (viteTasks[buildId]) { viteTasks[buildId]?.entries.push(restEntry); if (output !== viteTasks[buildId]?.output) { ctx.logger.warn( "Multiple entries with different outputs for the same format are not supported. The first output will be used." ); } } else { viteTasks[buildId] = { type: `${mode}:js`, format, output, runtime, entries: [restEntry] }; } }; const exps = Object.entries(ctx.exports).map(([exportPath, exportEntry]) => ({ ...exportEntry, _path: exportPath })); for (const exp of exps) { if (exp.types) { const importId = path__default.default.join(ctx.pkg.name, exp._path); dtsTask.entries.push({ importId, exportPath: exp._path, sourcePath: exp.source, targetPath: exp.types }); } if (exp.require) { createViteTask("cjs", ctx.runtime ?? "*", { path: exp._path, entry: exp.source, output: exp.require }); } if (exp.import) { createViteTask("es", ctx.runtime ?? "*", { path: exp._path, entry: exp.source, output: exp.import }); } if (exp.browser?.require) { createViteTask("cjs", "web", { path: exp._path, entry: exp.browser?.source || exp.source, output: exp.browser.require }); } if (exp.browser?.import) { createViteTask("cjs", "web", { path: exp._path, entry: exp.browser?.source || exp.source, output: exp.browser.import }); } } const bundles = ctx.config.bundles ?? []; for (const bundle of bundles) { const idx = bundles.indexOf(bundle); if (bundle.require) { createViteTask("cjs", (bundle.runtime || ctx.runtime) ?? "*", { path: `bundle_cjs_${idx}`, entry: bundle.source, output: bundle.require }); } if (bundle.import) { createViteTask("es", (bundle.runtime || ctx.runtime) ?? "*", { path: `bundle_esm_${idx}`, entry: bundle.source, output: bundle.import }); } if (bundle.types) { const importId = path__default.default.join(ctx.pkg.name, bundle.source); dtsTask.entries.push({ importId, exportPath: bundle.source, sourcePath: bundle.source, targetPath: bundle.types, tsconfig: bundle.tsconfig }); } } if (dtsTask.entries.length) { tasks.push(dtsTask); } if (Object.values(viteTasks).length) { tasks.push(...Object.values(viteTasks)); } return tasks; }; const createBuildTasks = createTasks("build"); const createWatchTasks = createTasks("watch"); const printDiagnostic = (diagnostic, { logger, cwd }) => { let output = ts__default.default.flattenDiagnosticMessageText(diagnostic.messageText, ts__default.default.sys.newLine); if (diagnostic.file && diagnostic.start) { const { line, character } = ts__default.default.getLineAndCharacterOfPosition(diagnostic.file, diagnostic.start); const message = ts__default.default.flattenDiagnosticMessageText(diagnostic.messageText, ts__default.default.sys.newLine); const file = path__default.default.relative(cwd, diagnostic.file.fileName); output = [ `${chalk__default.default.cyan(file)}:${chalk__default.default.cyan(line + 1)}:${chalk__default.default.cyan(character + 1)} - `, `${chalk__default.default.gray(`TS${diagnostic.code}:`)} ${message}` ].join(""); } switch (diagnostic.category) { case ts__default.default.DiagnosticCategory.Error: logger.error(output); break; case ts__default.default.DiagnosticCategory.Warning: logger.warn(output); break; case ts__default.default.DiagnosticCategory.Message: logger.info(output); break; case ts__default.default.DiagnosticCategory.Suggestion: logger.info(output); break; } }; const dtsBuildTask = { print(ctx, task) { const entries = [ " entries:", ...task.entries.map( (entry) => [ " – ", chalk__default.default.green(`${entry.importId} `), `${chalk__default.default.cyan(entry.sourcePath)} ${chalk__default.default.gray("->")} ${chalk__default.default.cyan(entry.targetPath)}` ].join("") ) ]; ctx.logger.log(["Building type files:", ...entries].join(os__default.default.EOL)); }, run$(ctx, task) { return new rxjs.Observable((subscriber) => { Promise.all( task.entries.map(async (entry) => { const tsconfig = entry.tsconfig ? createBuildContext.loadTsConfig({ cwd: ctx.cwd, path: entry.tsconfig, logger: ctx.logger }) : ctx.ts; if (!tsconfig) { ctx.logger.warn( `You've added a types entry but no tsconfig.json was found for ${entry.targetPath}. Skipping...` ); return; } const program = ts__default.default.createProgram(tsconfig.config.fileNames, tsconfig.config.options); const emitResult = program.emit(); const allDiagnostics = ts__default.default.getPreEmitDiagnostics(program).concat(emitResult.diagnostics); for (const diagnostic of allDiagnostics) { printDiagnostic(diagnostic, { logger: ctx.logger, cwd: ctx.cwd }); } const errors2 = allDiagnostics.filter( (diag) => diag.category === ts__default.default.DiagnosticCategory.Error ); if (errors2.length) { throw new Error("Failed to compile TypeScript definitions"); } }) ).then(() => { subscriber.complete(); }).catch((err) => { subscriber.error(err); }); }); }, async success(ctx, task) { const msg = [ "Built types, entries:", task.entries.map( (entry) => ` ${chalk__default.default.blue(`${entry.importId}`)}: ${entry.sourcePath} -> ${entry.targetPath}` ).join(os__default.default.EOL) ]; ctx.logger.success(msg.join(os__default.default.EOL)); }, async fail(ctx, task, err) { if (errors.isError(err)) { ctx.logger.error(err.message); } } }; const dtsWatchTask = { print(ctx, task) { const msg = [ "Building Types, entries:", task.entries.map( (entry) => ` ${chalk__default.default.blue(`${entry.importId}`)}: ${entry.sourcePath} -> ${entry.targetPath}` ).join(os__default.default.EOL) ]; ctx.logger.success(msg.join(os__default.default.EOL)); }, run$(ctx, task) { let programs = []; return new rxjs.Observable((subscriber) => { Promise.all( task.entries.map(async (entry) => { const tsconfig = entry.tsconfig ? createBuildContext.loadTsConfig({ cwd: ctx.cwd, path: entry.tsconfig, logger: ctx.logger }) : ctx.ts; if (!tsconfig) { ctx.logger.warn( `You've added a types entry but no tsconfig.json was found for ${entry.targetPath}. Skipping...` ); return; } const compilerHost = ts__default.default.createWatchCompilerHost( tsconfig.path, tsconfig.config.options, ts__default.default.sys, ts__default.default.createEmitAndSemanticDiagnosticsBuilderProgram, (diagnostic) => { subscriber.next(diagnostic); }, (diagnostic) => { subscriber.next(diagnostic); } ); return ts__default.default.createWatchProgram(compilerHost); }) ).then((progs) => { programs = progs; }).catch((err) => { subscriber.error(err); }); return () => { programs.forEach((prog) => { prog?.close(); }); }; }); }, async success(ctx, task, diagnostic) { const { logger, cwd } = ctx; if (diagnostic.code === 6194) { this.print(ctx, task); } if (diagnostic.category === ts__default.default.DiagnosticCategory.Message || diagnostic.category === ts__default.default.DiagnosticCategory.Suggestion) { return; } printDiagnostic(diagnostic, { logger, cwd }); }, async fail(ctx, task, err) { if (errors.isError(err)) { ctx.logger.error(err); } } }; const resolveViteConfig = async (ctx, task) => { const { cwd, distPath, targets, external, extMap, pkg, exports: exportMap } = ctx; const { entries, format, output, runtime } = task; const outputExt = extMap[pkg.type || "commonjs"][format]; const outDir = path__default.default.relative(cwd, distPath); const { createLogger } = await import("vite"); const customLogger = createLogger(); customLogger.warn = (msg) => ctx.logger.warn(msg); customLogger.warnOnce = (msg) => ctx.logger.warn(msg); customLogger.error = (msg) => ctx.logger.error(msg); customLogger.info = () => { }; const exportIds = Object.keys(exportMap).map((exportPath) => path__default.default.join(pkg.name, exportPath)); const sourcePaths = Object.values(exportMap).map((exp) => path__default.default.resolve(cwd, exp.source)); const basePlugins = runtime === "node" ? [] : [react__default.default()]; const plugins = ctx.config.plugins ? typeof ctx.config.plugins === "function" ? ctx.config.plugins({ runtime }) : ctx.config.plugins : []; const config = { configFile: false, root: cwd, mode: "production", logLevel: "warn", clearScreen: false, customLogger, build: { minify: createBuildContext.resolveConfigProperty(ctx.config.minify, false), sourcemap: createBuildContext.resolveConfigProperty(ctx.config.sourcemap, true), /** * The task runner will clear this for us */ emptyOutDir: false, target: targets[runtime], outDir, lib: { entry: entries.map((e) => e.entry), formats: [format], /** * this enforces the file name to match what the output we've * determined from the package.json exports. However, when preserving modules * we want to let Rollup handle the file names. */ fileName: createBuildContext.resolveConfigProperty(ctx.config.preserveModules, false) ? void 0 : () => { return `${path__default.default.relative(outDir, output).replace(/\.[^/.]+$/, "")}${outputExt}`; } }, rollupOptions: { external(id, importer) { if (exportIds?.includes(id)) { return true; } if (importer && (id.startsWith(".") || id.startsWith("/"))) { const idPath = path__default.default.resolve(path__default.default.dirname(importer), id); if (sourcePaths?.includes(idPath)) { ctx.logger.warn( `detected self-referencing import – treating as external: ${path__default.default.relative( cwd, idPath )}` ); return true; } } const idParts = id.split("/"); const name = idParts[0]?.startsWith("@") ? `${idParts[0]}/${idParts[1]}` : idParts[0]; const builtinModulesWithNodePrefix = [ ...node_module.builtinModules, ...node_module.builtinModules.map((modName) => `node:${modName}`) ]; if (name && external.includes(name) || name && builtinModulesWithNodePrefix.includes(name)) { return true; } return false; }, output: { preserveModules: createBuildContext.resolveConfigProperty(ctx.config.preserveModules, false), /** * Mimic TypeScript's behavior, by setting the value to "auto" to control * how Rollup handles default, namespace and dynamic imports from external * dependencies in formats like CommonJS that do not natively support * these concepts. Mainly styled-components@5 * * For more info see https://rollupjs.org/configuration-options/#output-interop */ interop: "auto", chunkFileNames() { const parts = outputExt.split("."); if (parts.length === 3) { return `_chunks/[name]-[hash].${parts[2]}`; } return `_chunks/[name]-[hash]${outputExt}`; } } } }, plugins: [...basePlugins, ...plugins] }; return import("vite").then( ({ mergeConfig }) => mergeConfig(config, ctx.config.unstable_viteConfig ?? {}) ); }; const viteBuildTask = { print(ctx, task) { const targetLines = [ " target:", ...ctx.targets[task.runtime].map((t) => chalk__default.default.cyan(` - ${t}`)) ]; const entries = [ " entries:", ...task.entries.map( (entry) => [ " – ", chalk__default.default.green(`${path__default.default.join(ctx.pkg.name, entry.path)}: `), `${chalk__default.default.cyan(entry.entry)} ${chalk__default.default.gray("→")} ${chalk__default.default.cyan(task.output)}` ].join("") ) ]; ctx.logger.log( ["Building javascript files:", ` format: ${task.format}`, ...targetLines, ...entries].join( os__default.default.EOL ) ); }, run$(ctx, task) { return new rxjs.Observable((subscriber) => { resolveViteConfig(ctx, task).then((config) => { ctx.logger.debug("Vite config:", os__default.default.EOL, config); import("vite").then(({ build }) => { build(config).then(() => { subscriber.complete(); }).catch((err) => { subscriber.error(err); }); }); }); }); }, async success(ctx, task) { const msg = [ `Built javascript (runtime: ${task.runtime} – target: ${task.format})`, task.entries.map( (e) => ` ${chalk__default.default.blue(path__default.default.join(ctx.pkg.name, e.path))}: ${e.entry} -> ${task.output}` ).join(os__default.default.EOL) ]; ctx.logger.success(msg.join(os__default.default.EOL)); }, async fail(ctx, task, err) { if (errors.isError(err)) { ctx.logger.error(err.message); } } }; const viteWatchTask = { print(ctx, task) { const msg = [ `Building Javascript (runtime: ${task.runtime} – target: ${task.format})`, task.entries.map( (e) => ` ${chalk__default.default.blue(path__default.default.join(ctx.pkg.name, e.path))}: ${e.entry} -> ${task.output}` ).join(os__default.default.EOL) ]; ctx.logger.success(msg.join(os__default.default.EOL)); }, run$(ctx, task) { return new rxjs.Observable((subscriber) => { let watcher = null; resolveViteConfig(ctx, task).then((config) => { ctx.logger.debug(`Vite config:${os__default.default.EOL}`, config); import("vite").then(({ build }) => { build({ ...config, mode: "development", build: { ...config.build, watch: {} } }).then((rollupWatcher) => { watcher = rollupWatcher; if ("on" in watcher && typeof watcher.on === "function") { watcher.on("event", (ev) => { subscriber.next(ev); }); } }); }); }); return () => { if (watcher !== null && "close" in watcher && typeof watcher.close === "function") { watcher.close(); } }; }); }, success(ctx, task, result) { switch (result.code) { case "BUNDLE_END": this.print(ctx, task); break; case "ERROR": ctx.logger.error(result.error); break; } }, fail(ctx, task, err) { if (errors.isError(err)) { ctx.logger.error(err); } } }; const taskHandlers = { "build:js": viteBuildTask, "build:dts": dtsBuildTask, "watch:js": viteWatchTask, "watch:dts": dtsWatchTask }; exports.createBuildTasks = createBuildTasks; exports.createWatchTasks = createWatchTasks; exports.taskHandlers = taskHandlers; //# sourceMappingURL=index-DxTZekLC.js.map