UNPKG

serverless-webpack

Version:

Serverless plugin to bundle your javascript with Webpack

268 lines (238 loc) 8.95 kB
'use strict'; const BbPromise = require('bluebird'); const _ = require('lodash'); const validate = require('./lib/validate'); const compile = require('./lib/compile'); const wpwatch = require('./lib/wpwatch'); const cleanup = require('./lib/cleanup'); const run = require('./lib/run'); const prepareLocalInvoke = require('./lib/prepareLocalInvoke'); const runPluginSupport = require('./lib/runPluginSupport'); const prepareOfflineInvoke = require('./lib/prepareOfflineInvoke'); const prepareStepOfflineInvoke = require('./lib/prepareStepOfflineInvoke'); const packExternalModules = require('./lib/packExternalModules'); const packageModules = require('./lib/packageModules'); const { isNodeRuntime } = require('./lib/utils'); const { extendFunctionProperties } = require('./lib/extendServerless'); const lib = require('./lib'); class ServerlessWebpack { static get lib() { return lib; } constructor(serverless, options, v3Utils) { this.serverless = serverless; extendFunctionProperties(this.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) && _.endsWith(this.serverless.service.custom.webpack, '.ts')) || (_.has(this.serverless, 'service.custom.webpack.webpackConfig') && _.endsWith(this.serverless.service.custom.webpack.webpackConfig, '.ts'))) && !process[Symbol.for('ts-node.register.instance')] ) { try { require('ts-node/register'); } catch (e) { throw new Error('If you want to use TypeScript with serverless-webpack, please add "ts-node" as dependency.'); } } _.assign( this, validate, compile, wpwatch, cleanup, run, packExternalModules, packageModules, prepareLocalInvoke, runPluginSupport, prepareOfflineInvoke, prepareStepOfflineInvoke ); this.commands = { webpack: { usage: 'Bundle with Webpack', lifecycleEvents: ['webpack'], options: { out: { usage: 'Path to output directory', shortcut: 'o', type: 'string' } }, commands: { validate: { type: 'entrypoint', lifecycleEvents: ['validate'] }, compile: { type: 'entrypoint', lifecycleEvents: ['compile'], commands: { watch: { type: 'entrypoint', lifecycleEvents: ['compile'] } } }, package: { type: 'entrypoint', lifecycleEvents: ['packExternalModules', 'packageModules', 'copyExistingArtifacts'] } } }, invoke: { commands: { local: { options: { 'skip-build': { usage: 'Skip Webpack compilation', type: 'boolean' }, watch: { usage: 'Flag to watch changes', type: 'boolean' }, 'webpack-use-polling': { usage: 'Define time (in ms) for polling for changes. Default: `3000`', type: 'string' } } } } }, offline: { options: { 'webpack-no-watch': { usage: 'Disable automatic watch mode from Serverless Webpack', type: 'boolean' }, 'skip-build': { usage: 'Skip Webpack compilation', type: 'boolean' } }, commands: { start: { options: { 'webpack-no-watch': { usage: 'Disable automatic watch mode from Serverless Webpack', type: 'boolean' }, 'skip-build': { usage: 'Skip Webpack compilation', type: 'boolean' } } } } } }; this.hooks = { initialize: () => { // serverless.processedInput does not exist in serverless@<2.0.0. This ensure the retrocompatibility with serverless v1 if (this.serverless.processedInput && this.serverless.processedInput.options) { this.options = this.serverless.processedInput.options; } }, 'before:package:createDeploymentArtifacts': () => 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.log && this.progress.get('webpack').remove()), 'after:package:createDeploymentArtifacts': () => BbPromise.bind(this).then(this.cleanup), 'before:deploy:function:packageFunction': () => { const runtime = this.serverless.service.getFunction(this.options.function).runtime || this.serverless.service.provider.runtime || 'nodejs'; if (isNodeRuntime(runtime)) { return BbPromise.bind(this) .then(() => this.serverless.pluginManager.spawn('webpack:validate')) .then(() => this.serverless.pluginManager.spawn('webpack:compile')) .then(() => this.serverless.pluginManager.spawn('webpack:package')); } }, 'before:invoke:local:invoke': () => BbPromise.bind(this) .then(() => { lib.webpack.isLocal = true; return this.serverless.pluginManager.spawn('webpack:validate'); }) .then(() => (this.skipCompile ? BbPromise.resolve() : this.serverless.pluginManager.spawn('webpack:compile'))) .then(this.prepareLocalInvoke), 'after:invoke:local:invoke': () => BbPromise.bind(this).then(() => { if (this.options.watch && !this.isWatching) { return this.watch('invoke:local'); } return BbPromise.resolve(); }), 'before:run:run': () => BbPromise.bind(this) .then(() => _.set(this.serverless, 'service.package.individually', false)) .then(() => this.serverless.pluginManager.spawn('webpack:validate')) .then(() => this.serverless.pluginManager.spawn('webpack:compile')) .then(this.packExternalModules) .then(this.prepareRun), 'after:run:run': () => BbPromise.bind(this).then(() => { if (this.options.watch && !this.isWatching) { return this.watch(this.watchRun.bind(this)); } return BbPromise.resolve(); }), 'webpack:webpack': () => BbPromise.bind(this) .then(() => this.serverless.pluginManager.spawn('webpack:validate')) .then(() => this.serverless.pluginManager.spawn('webpack:compile')) .then(() => this.serverless.pluginManager.spawn('webpack:package')), /* * Internal webpack events (can be hooked by plugins) */ 'webpack:validate:validate': () => BbPromise.bind(this).then(this.validate), 'webpack:compile:compile': () => BbPromise.bind(this).then(this.compile), 'webpack:compile:watch:compile': () => BbPromise.resolve(), 'webpack:package:packExternalModules': () => BbPromise.bind(this).then(this.packExternalModules), 'webpack:package:packageModules': () => BbPromise.bind(this).then(this.packageModules), 'webpack:package:copyExistingArtifacts': () => BbPromise.bind(this).then(this.copyExistingArtifacts), 'before:offline:start': () => BbPromise.bind(this) .tap(() => { lib.webpack.isLocal = true; // --skip-build override if (this.options['skip-build'] === false) { this.skipCompile = true; } }) .then(this.prepareOfflineInvoke) .then(() => (this.skipCompile ? BbPromise.resolve() : this.wpwatch())), 'before:offline:start:init': () => BbPromise.bind(this) .tap(() => { lib.webpack.isLocal = true; // --skip-build override if (this.options['skip-build'] === false) { this.skipCompile = true; } }) .then(this.prepareOfflineInvoke) .then(() => (this.skipCompile ? BbPromise.resolve() : this.wpwatch())), 'before:step-functions-offline:start': () => BbPromise.bind(this) .tap(() => { lib.webpack.isLocal = true; }) .then(this.prepareStepOfflineInvoke) .then(() => this.serverless.pluginManager.spawn('webpack:compile')) }; } } module.exports = ServerlessWebpack;