UNPKG

varan

Version:

A webpack starter kit for offline-first bring-your-own-code apps with server side rendering

172 lines 9.75 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const lodash_1 = require("lodash"); const path_1 = __importDefault(require("path")); const webpack_1 = __importDefault(require("webpack")); const chalk_1 = __importDefault(require("chalk")); const listr_1 = __importDefault(require("listr")); const webpack_stats_plugin_1 = require("webpack-stats-plugin"); const fs_extra_1 = __importDefault(require("fs-extra")); const filesize_1 = __importDefault(require("filesize")); const emojis_1 = __importDefault(require("./emojis")); const getBuildStatsFromManifest_1 = __importDefault(require("./getBuildStatsFromManifest")); const getCompilerStats_1 = __importDefault(require("./getCompilerStats")); const getConfigs_1 = __importDefault(require("./getConfigs")); const BuildError_1 = __importDefault(require("./BuildError")); const createServerConfig_1 = __importDefault(require("../webpack/createServerConfig")); const createClientConfig_1 = __importDefault(require("../webpack/createClientConfig")); // Init const getOpts = (options) => lodash_1.defaults({}, options, { verbose: true, configs: [createServerConfig_1.default, createClientConfig_1.default], warnAssetSize: 512 * 1024, warnChunkSize: 1024 * 1024, env: 'production', appDir: process.cwd(), inputFileSystem: undefined, outputFileSystem: undefined, }); // Exports async function build(options) { const opts = getOpts(options); // Setup process.env.BABEL_ENV = opts.env; const configs = getConfigs_1.default(opts.configs, opts); const multiCompiler = webpack_1.default(configs.map((c) => lodash_1.omit(c, ['devServer']))); if (opts.inputFileSystem) multiCompiler.inputFileSystem = opts.inputFileSystem; if (opts.outputFileSystem) multiCompiler.outputFileSystem = opts.outputFileSystem; const taskOptions = { showSubtasks: true, renderer: opts.verbose ? 'default' : 'silent', nonTTYRenderer: opts.verbose ? 'verbose' : 'silent', }; const tasks = new listr_1.default([ { title: 'Build', task: () => new listr_1.default([ ...multiCompiler.compilers.map((compiler, i) => ({ title: `Build ${path_1.default.resolve(typeof opts.configs[i] === 'string' ? opts.configs[i].toString() : compiler.options.name || i.toString())}`, task: () => new listr_1.default([ { title: 'Prepare', task: (ctx) => { if (!ctx.stats) ctx.stats = []; ctx.stats[i] = { errors: [], warnings: [], }; return `${chalk_1.default.green(emojis_1.default.success)} Preparations completed successfully`; }, }, { title: 'Measure previous build', skip: () => opts.silent || compiler.options.target === 'node', task: async (ctx) => { const statsPlugin = compiler.options.plugins && compiler.options.plugins.find((p) => p instanceof webpack_stats_plugin_1.StatsWriterPlugin); if (statsPlugin) { try { const searchPath = compiler.outputPath; const manifestFile = path_1.default.resolve(searchPath, statsPlugin.opts.filename); const manifestRaw = await fs_extra_1.default.readFile(manifestFile); const manifest = JSON.parse(manifestRaw.toString()); ctx.stats[i].previousBuild = await getBuildStatsFromManifest_1.default(searchPath, manifest); } catch (err) { // Empty } } }, }, { title: 'Build', task: (ctx) => new Promise((resolve, reject) => { compiler.run((err, stats) => { if (err) return reject(err); const info = stats.toJson(); ctx.stats[i].errors = info.errors; ctx.stats[i].warnings = info.warnings; if (stats.hasErrors() || info.errors.length > 0) { const buildError = new BuildError_1.default('Build failed with errors'); buildError.errors = ctx.stats[i].errors; buildError.warnings = ctx.stats[i].warnings; return reject(buildError); } // Send data const config = compiler.options; ctx.stats[i].build = { config, stats, configFile: path_1.default.resolve(typeof opts.configs[i] === 'string' ? opts.configs[i].toString() : config.name || i.toString()), outputPath: (config.output && config.output.path && path_1.default.dirname(config.output.path)) || undefined, }; return resolve(`${chalk_1.default.green(emojis_1.default.success)} Build completed successfully!`); }); }), }, { title: 'Measure current build', skip: () => opts.silent || compiler.options.target === 'node', task: async (ctx) => { const statsPlugin = compiler.options.plugins && compiler.options.plugins.find((p) => p instanceof webpack_stats_plugin_1.StatsWriterPlugin); if (statsPlugin) { try { const searchPath = compiler.outputPath; const manifestFile = path_1.default.resolve(searchPath, statsPlugin.opts.filename); const manifestRaw = await fs_extra_1.default.readFile(manifestFile); const manifest = JSON.parse(manifestRaw.toString()); ctx.stats[i].currentBuild = await getBuildStatsFromManifest_1.default(searchPath, manifest); // Check for chunk size violations if (ctx.stats[i].currentBuild && Object.values(ctx.stats[i].currentBuild.chunks).some((chunk) => chunk.size > opts.warnChunkSize)) { ctx.stats[i].warnings.push(`one or more chunks exceeds the set ${chalk_1.default.cyan('opts.warnChunkSize')} limit of ${chalk_1.default.cyan(filesize_1.default(opts.warnChunkSize))}.`); } // Check for asset size violations if (ctx.stats[i].currentBuild && Object.values(ctx.stats[i].currentBuild.assets).some((asset) => asset.size > opts.warnAssetSize)) { ctx.stats[i].warnings.push(`one or more assets exceeds the set ${chalk_1.default.cyan('opts.warnAssetSize')} limit of ${chalk_1.default.cyan(filesize_1.default(opts.warnAssetSize))}`); } } catch (err) { // Empty } } }, }, ]), })), ], { showSubtasks: true, concurrent: true, }), }, { title: 'Calculate build stats', task: (ctx) => { const stats = Object.values(ctx.stats) .filter((s) => s.build && s.build.stats) .map((s) => s.build.stats); ctx.totals = getCompilerStats_1.default(stats); return `${chalk_1.default.green(emojis_1.default.success)} Build statistics calculated successfully`; }, }, ], taskOptions); /** * Build project */ return { result: await tasks.run(), options: opts }; } exports.default = build; //# sourceMappingURL=build.js.map