diff --git a/lib/tools/broccoli/node-modules-dest-copy.ts b/lib/tools/broccoli/node-modules-dest-copy.ts index 9f33ee8e8a..45941440ec 100644 --- a/lib/tools/broccoli/node-modules-dest-copy.ts +++ b/lib/tools/broccoli/node-modules-dest-copy.ts @@ -30,41 +30,43 @@ export class DestCopy implements IBroccoliPlugin { public rebuildChangedDirectories(changedDirectories: string[], platform: string): void { _.each(changedDirectories, changedDirectoryAbsolutePath => { - let pathToPackageJson = path.join(changedDirectoryAbsolutePath, "package.json"); - let packageJsonFiles = fs.existsSync(pathToPackageJson) ? [pathToPackageJson] : []; - let nodeModulesFolderPath = path.join(changedDirectoryAbsolutePath, "node_modules"); - packageJsonFiles = packageJsonFiles.concat(this.enumeratePackageJsonFilesSync(nodeModulesFolderPath)); - - _.each(packageJsonFiles, packageJsonFilePath => { - let fileContent = require(packageJsonFilePath); - let isPlugin = fileContent.nativescript; - - if(!this.devDependencies[fileContent.name]) { // Don't flatten dev dependencies - - let currentDependency = { - name: fileContent.name, - version: fileContent.version, - directory: path.dirname(packageJsonFilePath), - isPlugin: isPlugin - }; + if(!this.devDependencies[path.basename(changedDirectoryAbsolutePath)]) { + let pathToPackageJson = path.join(changedDirectoryAbsolutePath, constants.PACKAGE_JSON_FILE_NAME); + let packageJsonFiles = fs.existsSync(pathToPackageJson) ? [pathToPackageJson] : []; + let nodeModulesFolderPath = path.join(changedDirectoryAbsolutePath, constants.NODE_MODULES_FOLDER_NAME); + packageJsonFiles = packageJsonFiles.concat(this.enumeratePackageJsonFilesSync(nodeModulesFolderPath)); - let addedDependency = this.dependencies[currentDependency.name]; - if (addedDependency) { - if (semver.gt(currentDependency.version, addedDependency.version)) { - let currentDependencyMajorVersion = semver.major(currentDependency.version); - let addedDependencyMajorVersion = semver.major(addedDependency.version); - - let message = `The depedency located at ${addedDependency.directory} with version ${addedDependency.version} will be replaced with dependency located at ${currentDependency.directory} with version ${currentDependency.version}`; - let logger = $injector.resolve("$logger"); - currentDependencyMajorVersion === addedDependencyMajorVersion ? logger.out(message) : logger.warn(message); + _.each(packageJsonFiles, packageJsonFilePath => { + let fileContent = require(packageJsonFilePath); + if(!this.devDependencies[fileContent.name]) { // Don't flatten dev dependencies + let isPlugin = fileContent.nativescript; + + let currentDependency = { + name: fileContent.name, + version: fileContent.version, + directory: path.dirname(packageJsonFilePath), + isPlugin: isPlugin + }; + + let addedDependency = this.dependencies[currentDependency.name]; + if (addedDependency) { + if (semver.gt(currentDependency.version, addedDependency.version)) { + let currentDependencyMajorVersion = semver.major(currentDependency.version); + let addedDependencyMajorVersion = semver.major(addedDependency.version); + + let message = `The depedency located at ${addedDependency.directory} with version ${addedDependency.version} will be replaced with dependency located at ${currentDependency.directory} with version ${currentDependency.version}`; + let logger = $injector.resolve("$logger"); + currentDependencyMajorVersion === addedDependencyMajorVersion ? logger.out(message) : logger.warn(message); + + this.dependencies[currentDependency.name] = currentDependency; + } + } else { this.dependencies[currentDependency.name] = currentDependency; } - } else { - this.dependencies[currentDependency.name] = currentDependency; } - } - }); + }); + } }); _.each(this.dependencies, dependency => { @@ -98,12 +100,12 @@ export class DestCopy implements IBroccoliPlugin { if(fs.existsSync(nodeModulesDirectoryPath)) { let contents = fs.readdirSync(nodeModulesDirectoryPath); for (let i = 0; i < contents.length; ++i) { - let packageJsonFilePath = path.join(nodeModulesDirectoryPath, contents[i], "package.json"); + let packageJsonFilePath = path.join(nodeModulesDirectoryPath, contents[i], constants.PACKAGE_JSON_FILE_NAME); if (fs.existsSync(packageJsonFilePath)) { foundFiles.push(packageJsonFilePath); } - var directoryPath = path.join(nodeModulesDirectoryPath, contents[i], "node_modules"); + var directoryPath = path.join(nodeModulesDirectoryPath, contents[i], constants.NODE_MODULES_FOLDER_NAME); if (fs.existsSync(directoryPath)) { this.enumeratePackageJsonFilesSync(directoryPath, foundFiles); } diff --git a/test/npm-support.ts b/test/npm-support.ts index 24888880a0..fff3f12ca7 100644 --- a/test/npm-support.ts +++ b/test/npm-support.ts @@ -83,6 +83,7 @@ function createProject(testInjector: IInjector, dependencies?: any): string { } }; packageJsonData["dependencies"] = dependencies; + packageJsonData["devDependencies"] = {}; testInjector.resolve("fs").writeJson(path.join(tempFolder, "package.json"), packageJsonData).wait(); return tempFolder; @@ -131,7 +132,7 @@ function setupProject(): IFuture { }).future()(); } -function addDependencies(testInjector: IInjector, projectFolder: string, dependencies: any): IFuture { +function addDependencies(testInjector: IInjector, projectFolder: string, dependencies: any, devDependencies?: any): IFuture { return (() => { let fs = testInjector.resolve("fs"); let packageJsonPath = path.join(projectFolder, "package.json"); @@ -139,6 +140,11 @@ function addDependencies(testInjector: IInjector, projectFolder: string, depende let currentDependencies = packageJsonData.dependencies; _.extend(currentDependencies, dependencies); + + if(devDependencies) { + let currentDevDependencies = packageJsonData.devDependencies; + _.extend(currentDevDependencies, devDependencies); + } fs.writeJson(packageJsonPath, packageJsonData).wait(); }).future()(); } @@ -176,4 +182,57 @@ describe("Npm support tests", () => { assert.isTrue(fs.exists(bplistCreatorFolderPath).wait()); assert.isTrue(fs.exists(bplistParserFolderPath).wait()); }); +}); + +describe("Flatten npm modules tests", () => { + it("Doesn't handle the dependencies of devDependencies", () => { + let projectSetup = setupProject().wait(); + let testInjector = projectSetup.testInjector; + let projectFolder = projectSetup.projectFolder; + let appDestinationFolderPath = projectSetup.appDestinationFolderPath; + + let devDependencies = { + "gulp": "3.9.0", + "gulp-jscs": "1.6.0", + "gulp-jshint": "1.11.0" + }; + + addDependencies(testInjector, projectFolder, {}, devDependencies).wait(); + + preparePlatform(testInjector).wait(); + + // Assert + let fs = testInjector.resolve("fs"); + let tnsModulesFolderPath = path.join(appDestinationFolderPath, "app", "tns_modules"); + + let lodashFolderPath = path.join(tnsModulesFolderPath, "lodash"); + assert.isTrue(fs.exists(lodashFolderPath).wait()); + + let gulpFolderPath = path.join(tnsModulesFolderPath, "gulp"); + assert.isFalse(fs.exists(gulpFolderPath).wait()); + + let gulpJscsFolderPath = path.join(tnsModulesFolderPath, "gulp-jscs"); + assert.isFalse(fs.exists(gulpJscsFolderPath).wait()); + + let gulpJshint = path.join(tnsModulesFolderPath, "gulp-jshint"); + assert.isFalse(fs.exists(gulpJshint).wait()); + + // Get all gulp dependencies + let gulpDependencies = fs.readDirectory(path.join(projectFolder, "node_modules", "gulp", "node_modules")).wait(); + _.each(gulpDependencies, dependency => { + assert.isFalse(fs.exists(path.join(tnsModulesFolderPath, dependency)).wait()); + }); + + // Get all gulp-jscs dependencies + let gulpJscsDependencies = fs.readDirectory(path.join(projectFolder, "node_modules", "gulp-jscs", "node_modules")).wait(); + _.each(gulpJscsDependencies, dependency => { + assert.isFalse(fs.exists(path.join(tnsModulesFolderPath, dependency)).wait()); + }); + + // Get all gulp-jshint dependencies + let gulpJshintDependencies = fs.readDirectory(path.join(projectFolder, "node_modules", "gulp-jshint", "node_modules")).wait(); + _.each(gulpJshintDependencies, dependency => { + assert.isFalse(fs.exists(path.join(tnsModulesFolderPath, dependency)).wait()); + }); + }); }); \ No newline at end of file