UNPKG

@pega/custom-dx-components

Version:

Utility for building custom UI components

244 lines (207 loc) 7.13 kB
import chalk from 'chalk'; import fs from 'fs-extra'; import webpack from 'webpack'; import FileSizeReporter from 'react-dev-utils/FileSizeReporter.js'; import printBuildError from 'react-dev-utils/printBuildError.js'; import { getUseWebPackPromotion, addDebugLog, emptyDirSync } from '../../../util.js'; import paths from './paths.js'; // Do this as the first thing so that any code reading it knows the right env. let Env = 'production'; if (process.argv.includes('development')) { Env = 'development'; } if (process.argv.includes('source-map')) { process.env.SOURCE_MAP = true; } // Do this as the first thing so that any code reading it knows the right env. process.env.BABEL_ENV = Env; process.env.NODE_ENV = Env; // Makes the script crash on unhandled rejections instead of silently // ignoring them. In the future, promise rejections that are not handled will // terminate the Node.js process with a non-zero exit code. process.on('unhandledRejection', err => { console.log(err); // process.exit(1); }); const measureFileSizesBeforeBuild = FileSizeReporter.measureFileSizesBeforeBuild; const printFileSizesAfterBuild = FileSizeReporter.printFileSizesAfterBuild; // These sizes are pretty large. We'll warn for bundles exceeding them. const WARN_AFTER_BUNDLE_GZIP_SIZE = 512 * 1024; const WARN_AFTER_CHUNK_GZIP_SIZE = 1024 * 1024; let compilationErrors = null; // Create the build and print the deployment instructions. function build(config, previousFileSizes, showStats = true) { addDebugLog("bundle build", `config: ${JSON.stringify(config)}, \npreviousFileSizes: ${JSON.stringify(previousFileSizes)}, showStats: ${showStats}`, ""); if (showStats) { console.log(`Creating a ${Env} build...`); } const compiler = webpack(config); return new Promise((resolve, reject) => { compiler.run((err, stats) => { if (err != null && typeof (err) == "object") { if (err.error != undefined) { //store and print elsewhere compilationErrors = err.error; //console.log("err:" + err); } } if (stats != null & typeof (stats) == "object") { if (stats.errors != undefined) { if (showStats) { console.log("stats:" + stats); } } else if (stats.compilation != undefined && stats.compilation.errors != undefined) { //store and print elsewhere compilationErrors = stats.compilation.errors; if (showStats) { console.log("stats:" + stats); } } } let messages; if (err) { if (!err.message) { return reject(err); } let errMessage = err.message; // Add additional information for postcss errors if (Object.prototype.hasOwnProperty.call(err, 'postcssNode')) { errMessage += `\nCompileError: Begins at CSS selector ${err.postcssNode.selector}`; } messages = { errors: [errMessage], warnings: [] }; } else { messages = stats.toJson({ all: false, warnings: true, errors: true }); } if (messages.errors.length) { // Only keep the first error. Others are often indicative // of the same problem, but confuse the reader with noise. if (messages.errors.length > 1) { messages.errors.length = 1; } return reject(new Error(messages.errors)); } if ( process.env.CI && (typeof process.env.CI !== 'string' || process.env.CI.toLowerCase() !== 'false') && messages.warnings.length ) { console.log( chalk.yellow( '\nTreating warnings as errors because process.env.CI = true.\n' + 'Most CI servers set it automatically.\n' ) ); return reject(new Error(messages.warnings.join('\n\n'))); } const resolveArgs = { stats, previousFileSizes, warnings: messages.warnings }; return resolve(resolveArgs); }); }); } export default async ({ inputFile, outputFile, componentKey, externals, globals, sourceMap, devBuild, showStats }) => { const usePromoted = await getUseWebPackPromotion(); // used by promote and revert webPack commands, do not change const configFactory = ( await import(`${usePromoted ? `../../../../../../../webpack.config.js` : `./webpack.config.js`}`) ).default; // Generate configuration const config = configFactory(Env, { inputFile, outputFile, componentKey, externals, globals, sourceMap, devBuild }); if (devBuild) { Env = 'development'; } return new Promise((resolve, reject) => { measureFileSizesBeforeBuild(paths.appBuild) .then(previousFileSizes => { // Remove all content but keep the directory so that // if you're in it, you don't end up in Trash emptyDirSync(paths.appBuild); // Start the webpack build return build(config, previousFileSizes, showStats); }) .then( ({ stats, previousFileSizes, warnings }) => { if (showStats) { if (warnings.length) { //console.log(chalk.yellow('Compiled with warnings.\n'), warnings[0].message); console.log(chalk.yellow('Compiled with warnings.\n')); for (let warning in warnings) { console.log(chalk.yellow("Warning.."), warnings[warning].message); } } else { console.log(chalk.green('Compiled successfully.\n')); } console.log('File sizes after gzip:\n'); printFileSizesAfterBuild( stats, previousFileSizes, paths.appBuild, WARN_AFTER_BUNDLE_GZIP_SIZE, WARN_AFTER_CHUNK_GZIP_SIZE ); } else { } resolve('done emitting'); }, err => { reject(); const tscCompileOnError = process.env.TSC_COMPILE_ON_ERROR === 'true'; if (tscCompileOnError) { console.log( chalk.yellow( 'Compiled with the following type errors (you may want to check these before deploying your app):\n' ) ); printBuildError(err); } else if (compilationErrors != null) { if (compilationErrors.length == undefined) { console.log(chalk.red("Error..."), compilationErrors.message); } else { for (let error in compilationErrors) { console.log(chalk.red("Error..."), compilationErrors[error].message); } } // process.exit(1); } else { console.log(chalk.red('Failed to compile.\n')); printBuildError(JSON.stringify(err)); } } ) .catch(err => { reject(); if (err && err.message) { console.log(err.message); } // process.exit(1); }); }); };