diff --git a/src/index.ts b/src/index.ts index 9fc38f05..10fcb5e7 100644 --- a/src/index.ts +++ b/src/index.ts @@ -24,21 +24,41 @@ export class TypeScriptPlugin { this.hooks = { 'before:run:run': async () => { await this.compileTs() + await this.copyExtras() + await this.copyDependencies() }, 'before:offline:start': async () => { await this.compileTs() + await this.copyExtras() + await this.copyDependencies() this.watchAll() }, 'before:offline:start:init': async () => { await this.compileTs() + await this.copyExtras() + await this.copyDependencies() this.watchAll() }, - 'before:package:createDeploymentArtifacts': this.compileTs.bind(this), - 'after:package:createDeploymentArtifacts': this.cleanup.bind(this), - 'before:deploy:function:packageFunction': this.compileTs.bind(this), - 'after:deploy:function:packageFunction': this.cleanup.bind(this), + 'before:package:createDeploymentArtifacts': async () => { + await this.compileTs() + await this.copyExtras() + await this.copyDependencies(true) + }, + 'after:package:createDeploymentArtifacts': async () => { + await this.cleanup() + }, + 'before:deploy:function:packageFunction': async () => { + await this.compileTs() + await this.copyExtras() + await this.copyDependencies(true) + }, + 'after:deploy:function:packageFunction': async () => { + await this.cleanup() + }, 'before:invoke:local:invoke': async () => { const emitedFiles = await this.compileTs() + await this.copyExtras() + await this.copyDependencies() if (this.isWatching) { emitedFiles.forEach(filename => { const module = require.resolve(path.resolve(this.originalServicePath, filename)) @@ -133,29 +153,17 @@ export class TypeScriptPlugin { tsconfig.outDir = BUILD_FOLDER const emitedFiles = await typescript.run(this.rootFileNames, tsconfig) - await this.copyExtras() this.serverless.cli.log('Typescript compiled.') return emitedFiles } /** Link or copy extras such as node_modules or package.include definitions */ async copyExtras() { - const outPkgPath = path.resolve(path.join(BUILD_FOLDER, 'package.json')) - const outModulesPath = path.resolve(path.join(BUILD_FOLDER, 'node_modules')) - - // Link or copy node_modules and package.json to .build so Serverless can - // exlcude devDeps during packaging - if (!fs.existsSync(outModulesPath)) { - await this.linkOrCopy(path.resolve('node_modules'), outModulesPath, 'junction') - } - - if (!fs.existsSync(outPkgPath)) { - await this.linkOrCopy(path.resolve('package.json'), outPkgPath, 'file') - } + const { service } = this.serverless // include any "extras" from the "include" section - if (this.serverless.service.package.include && this.serverless.service.package.include.length > 0) { - const files = await globby(this.serverless.service.package.include) + if (service.package.include && service.package.include.length > 0) { + const files = await globby(service.package.include) for (const filename of files) { const destFileName = path.resolve(path.join(BUILD_FOLDER, filename)) @@ -172,6 +180,37 @@ export class TypeScriptPlugin { } } + /** + * Copy the `node_modules` folder and `package.json` files to the output + * directory. + * @param isPackaging Provided if serverless is packaging the service for deployment + */ + async copyDependencies(isPackaging = false) { + const outPkgPath = path.resolve(path.join(BUILD_FOLDER, 'package.json')) + const outModulesPath = path.resolve(path.join(BUILD_FOLDER, 'node_modules')) + + // copy development dependencies during packaging + if (isPackaging) { + if (fs.existsSync(outModulesPath)) { + fs.unlinkSync(outModulesPath) + } + + fs.copySync( + path.resolve('node_modules'), + path.resolve(path.join(BUILD_FOLDER, 'node_modules')) + ) + } else { + if (!fs.existsSync(outModulesPath)) { + await this.linkOrCopy(path.resolve('node_modules'), outModulesPath, 'junction') + } + } + + // copy/link package.json + if (!fs.existsSync(outPkgPath)) { + await this.linkOrCopy(path.resolve('package.json'), outPkgPath, 'file') + } + } + /** * Move built code to the serverless folder, taking into account individual * packaging preferences.