diff --git a/example/package.json b/example/package.json index 0d704530..8c0c8e77 100644 --- a/example/package.json +++ b/example/package.json @@ -5,6 +5,7 @@ }, "devDependencies": { "@types/lodash": "4.14.91", + "@types/node": "^11.13.0", "serverless-plugin-typescript": "1.1.5" } } diff --git a/package.json b/package.json index 8130bbf9..c6de7b5e 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "scripts": { "prepublish": "npm run build", "precommit": "npm run test", - "build": "rm -rf dist && tsc", + "build": "rimraf dist && tsc", "pretest": "npm run lint", "test": "jest", "lint": "tslint -c tslint.json 'src/**/*.ts'" @@ -32,6 +32,7 @@ "@types/lodash": "4.14.123", "jest": "24.5.0", "mock-fs": "4.8.0", + "rimraf": "^2.6.3", "ts-jest": "24.0.1", "tslint": "5.14.0", "typescript": "^3.4.1" 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 diff --git a/yarn.lock b/yarn.lock index 1abd2c6b..4df663f3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2974,7 +2974,7 @@ ret@~0.1.10: resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== -rimraf@^2.5.4, rimraf@^2.6.2: +rimraf@^2.5.4, rimraf@^2.6.2, rimraf@^2.6.3: version "2.6.3" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==