Skip to content

Commit

Permalink
feat: Configure modern logs
Browse files Browse the repository at this point in the history
  • Loading branch information
medikoo committed Dec 2, 2021
1 parent 2776bcf commit f277364
Show file tree
Hide file tree
Showing 24 changed files with 471 additions and 136 deletions.
31 changes: 31 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -97,3 +97,34 @@ jobs:

- name: "Run tests"
run: "npm run test"

serverless-v3-pre:
runs-on: ${{ matrix.os }}
name: Node.js ${{ matrix.node }} on ${{ matrix.os }} with Serverless v3 pre-release

strategy:
matrix:
os:
- ubuntu-20.04
node:
- "14"

steps:
- name: "Checkout"
uses: actions/checkout@v2
with:
fetch-depth: 2

- name: "Install Node.js"
uses: actions/setup-node@v2
with:
node-version: "${{ matrix.node }}"

- name: "Install Serverless v3 pre-release"
run: npm install serverless@pre-3

- name: "Install dependencies"
run: npm ci

- name: "Run tests"
run: "npm run test"
10 changes: 8 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,15 @@ class ServerlessWebpack {
return lib;
}

constructor(serverless, options) {
constructor(serverless, options, v3Utils) {
this.serverless = serverless;
this.options = options;

if (v3Utils) {
this.log = v3Utils.log;
this.progress = v3Utils.progress;
}

if (
((_.has(this.serverless, 'service.custom.webpack') &&
_.isString(this.serverless.service.custom.webpack) &&
Expand Down Expand Up @@ -101,7 +106,8 @@ class ServerlessWebpack {
BbPromise.bind(this)
.then(() => this.serverless.pluginManager.spawn('webpack:validate'))
.then(() => (this.skipCompile ? BbPromise.resolve() : this.serverless.pluginManager.spawn('webpack:compile')))
.then(() => this.serverless.pluginManager.spawn('webpack:package')),
.then(() => this.serverless.pluginManager.spawn('webpack:package'))
.then(() => this.log && this.progress.get('webpack').remove()),

'after:package:createDeploymentArtifacts': () => BbPromise.bind(this).then(this.cleanup),

Expand Down
2 changes: 1 addition & 1 deletion index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ describe('ServerlessWebpack', () => {
});

beforeEach(() => {
serverless = new Serverless();
serverless = new Serverless({ commands: ['print'], options: {} });
serverless.cli = {
log: sandbox.stub(),
consoleLog: sandbox.stub()
Expand Down
27 changes: 23 additions & 4 deletions lib/cleanup.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,35 @@ module.exports = {
const cli = this.options.verbose ? this.serverless.cli : { log: _.noop };

if (!keepOutputDirectory) {
cli.log(`Remove ${webpackOutputPath}`);
if (this.log) {
this.log.verbose(`Remove ${webpackOutputPath}`);
} else {
cli.log(`Remove ${webpackOutputPath}`);
}
if (this.serverless.utils.dirExistsSync(webpackOutputPath)) {
// Remove async to speed up process
fse
.remove(webpackOutputPath)
.then(() => cli.log(`Removing ${webpackOutputPath} done`))
.catch(error => cli.log(`Error occurred while removing ${webpackOutputPath}: ${error}`));
.then(() => {
if (this.log) {
this.log.verbose(`Removing ${webpackOutputPath} done`);
} else {
cli.log(`Removing ${webpackOutputPath} done`);
}
return null;
})
.catch(error => {
if (this.log) {
this.log.error(`Error occurred while removing ${webpackOutputPath}: ${error}`);
} else {
cli.log(`Error occurred while removing ${webpackOutputPath}: ${error}`);
}
});
}
} else {
cli.log(`Keeping ${webpackOutputPath}`);
if (!this.log) {
cli.log(`Keeping ${webpackOutputPath}`);
}
}

return BbPromise.resolve();
Expand Down
51 changes: 33 additions & 18 deletions lib/compile.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ function ensureArray(obj) {
return _.isArray(obj) ? obj : [obj];
}

function getStatsLogger(statsConfig, consoleLog) {
function getStatsLogger(statsConfig, consoleLog, { log, ServerlessError }) {
return stats => {
logStats(stats, statsConfig, consoleLog);
logStats(stats, statsConfig, consoleLog, { log, ServerlessError });
};
}

Expand Down Expand Up @@ -79,17 +79,12 @@ function getExternalModules({ compilation }) {
return Array.from(externals);
}

function webpackCompile(config, logStats, ServerlessError) {
function webpackCompile(config, logStats) {
return BbPromise.fromCallback(cb => webpack(config).run(cb)).then(stats => {
// ensure stats in any array in the case of concurrent build.
stats = stats.stats ? stats.stats : [stats];

_.forEach(stats, compileStats => {
logStats(compileStats);
if (compileStats.hasErrors()) {
throw _.assign(new ServerlessError('Webpack compilation error, see stats above'), { stats: compileStats });
}
});
_.forEach(stats, logStats);

return _.map(stats, compileStats => ({
outputPath: compileStats.compilation.compiler.outputPath,
Expand All @@ -103,39 +98,59 @@ function webpackConcurrentCompile(configs, logStats, concurrency, ServerlessErro
return BbPromise.map(
configs,
config =>
webpackCompile(config, logStats, ServerlessError).catch(error => {
webpackCompile(config, logStats).catch(error => {
errors.push(error);
return error.stats;
}),
{ concurrency }
).then(stats => {
if (errors.length) {
if (errors.length === 1) throw errors[0];
throw new ServerlessError('Webpack compilation errors, see stats above');
if (!this.log) {
if (errors.length === 1) {
throw errors[0];
}
throw new ServerlessError('Webpack compilation errors, see stats above');
}
throw new ServerlessError(
`Webpack compilation failed:\n\n${_.join(
_.map(errors, error => error.message),
'\n\n'
)}`
);
}
return _.flatten(stats);
});
}

module.exports = {
compile() {
this.serverless.cli.log('Bundling with Webpack...');
if (this.log) {
this.log.verbose('[Webpack] Building with Webpack');
this.progress.get('webpack').update('[Webpack] Building with Webpack');
} else {
this.serverless.cli.log('Bundling with Webpack...');
}

const configs = ensureArray(this.webpackConfig);
if (configs[0] === undefined) {
return BbPromise.reject('Unable to find Webpack configuration');
}

const logStats = getStatsLogger(configs[0].stats, this.serverless.cli.consoleLog);
const logStats = getStatsLogger(configs[0].stats, this.serverless.cli.consoleLog, {
log: this.log,
ServerlessError: this.serverless.classes.Error
});

if (!this.configuration) {
return BbPromise.reject(new this.serverless.classes.Error('Missing plugin configuration'));
}
const concurrency = this.configuration.concurrency;

return webpackConcurrentCompile(configs, logStats, concurrency, this.serverless.classes.Error).then(stats => {
this.compileStats = { stats };
return BbPromise.resolve();
});
return webpackConcurrentCompile
.call(this, configs, logStats, concurrency, this.serverless.classes.Error)
.then(stats => {
this.compileStats = { stats };
return BbPromise.resolve();
});
}
};
51 changes: 48 additions & 3 deletions lib/logStats.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use strict';

const _ = require('lodash');
const tty = require('tty');

const defaultStatsConfig = {
Expand All @@ -10,9 +11,53 @@ const defaultStatsConfig = {
children: false
};

module.exports = function (stats, statsConfig, consoleLog) {
module.exports = function (stats, statsConfig, consoleLog, { log, ServerlessError }) {
const statsOutput = stats.toString(statsConfig || defaultStatsConfig);
if (statsOutput) {
consoleLog(statsOutput);
if (!log) {
if (statsOutput) {
consoleLog(statsOutput);
}
} else {
if (statsConfig) {
if (!statsOutput) {
return;
}
log();
log(`${_.split(_.trim(statsOutput), '\n').join('\n ')}`);
} else {
const warningsOutput = stats.toString({
all: false,
errors: false,
errorsCount: false,
warnings: true,
warningsCount: false,
logging: 'warn'
});
if (warningsOutput) {
log.warning();
log.warning(`${_.split(_.trim(_.replace(warningsOutput, /WARNING /g, '')), '\n').join('\n ')}`);
}
}
}
if (!stats.hasErrors()) {
return;
}
if (!log) {
throw _.assign(new ServerlessError('Webpack compilation error, see stats above'), { stats });
}
const errorsOutput = stats.toString({
all: false,
errors: true,
errorsCount: false,
errorDetails: true,
warnings: false,
warningsCount: false,
logging: 'error'
});
if (errorsOutput) {
throw _.assign(
new ServerlessError(`${_.split(_.trim(_.replace(errorsOutput, /ERROR /g, '')), '\n').join('\n ')}`),
{ stats }
);
}
};
Loading

0 comments on commit f277364

Please sign in to comment.