diff --git a/src/index.ts b/src/index.ts index f89a891c..27e1769b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -136,14 +136,17 @@ export class TypeScriptPlugin { } async copyExtras() { - // include node_modules into build - if (!fs.existsSync(path.resolve(path.join(buildFolder, 'node_modules')))) { - fs.symlinkSync(path.resolve('node_modules'), path.resolve(path.join(buildFolder, 'node_modules')), 'junction') + const outPkgPath = path.resolve(path.join(buildFolder, 'package.json')) + const outModulesPath = path.resolve(path.join(buildFolder, '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') } - // include package.json into build so Serverless can exlcude devDeps during packaging - if (!fs.existsSync(path.resolve(path.join(buildFolder, 'package.json')))) { - fs.symlinkSync(path.resolve('package.json'), path.resolve(path.join(buildFolder, 'package.json')), 'file') + if (!fs.existsSync(outPkgPath)) { + await this.linkOrCopy(path.resolve('package.json'), outPkgPath, 'file') } // include any "extras" from the "include" section @@ -209,6 +212,23 @@ export class TypeScriptPlugin { fs.removeSync(path.join(this.originalServicePath, buildFolder)) } + /** + * Attempt to symlink a given path or directory and copy if it fails with an + * `EPERM` error. + */ + private async linkOrCopy( + srcPath: string, + dstPath: string, + type?: 'dir' | 'junction' | 'file' + ): Promise { + return fs.symlink(srcPath, dstPath, type) + .catch(error => { + if (error.code === 'EPERM' && error.errno === -4048) { + return fs.copy(srcPath, dstPath) + } + throw error + }) + } } module.exports = TypeScriptPlugin