diff --git a/.circleci/config.yml b/.circleci/config.yml index 65a26772e3..b4c1540b06 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -465,12 +465,14 @@ jobs: - when: condition: << parameters.ivy >> steps: - # Rename the Ivy packages dist folder to "dist/packages-dist" as the AIO - # package installer picks up the locally built packages from that location. + # Rename the "dist/*-dist-ivy-aot" packages directories (persisted to the workspace by + # the `build-ivy-npm-packages` job) to "dist/*-dist" as the AIO package installer + # picks up the locally built packages from that location. # *Note*: We could also adjust the packages installer, but given we won't have # two different folders of Angular distributions in the future, we should keep # the packages installer unchanged. - run: mv dist/packages-dist-ivy-aot dist/packages-dist + - run: mv dist/zone.js-dist-ivy-aot dist/zone.js-dist # Run examples tests. The "CIRCLE_NODE_INDEX" will be set if "parallelism" is enabled. # Since the parallelism is set to "5", there will be five parallel CircleCI containers. # with either "0", "1", etc as node index. This can be passed to the "--shard" argument. @@ -552,6 +554,7 @@ jobs: root: *workspace_location paths: - ng/dist/packages-dist-ivy-aot + - ng/dist/zone.js-dist-ivy-aot # We run a subset of the integration tests outside of Bazel that track # payload size. diff --git a/aio/tools/ng-packages-installer/index.js b/aio/tools/ng-packages-installer/index.js index 46249c18ad..b76d4abd4b 100644 --- a/aio/tools/ng-packages-installer/index.js +++ b/aio/tools/ng-packages-installer/index.js @@ -14,11 +14,12 @@ const LOCAL_MARKER_PATH = 'node_modules/_local_.json'; const ANGULAR_ROOT_DIR = path.resolve(__dirname, '../../..'); const ANGULAR_DIST_PACKAGES_DIR = path.join(ANGULAR_ROOT_DIR, 'dist/packages-dist'); +const ZONEJS_DIST_PACKAGES_DIR = path.join(ANGULAR_ROOT_DIR, 'dist/zone.js-dist'); const DIST_PACKAGES_BUILD_SCRIPT = path.join(ANGULAR_ROOT_DIR, 'scripts/build/build-packages-dist.js'); const DIST_PACKAGES_BUILD_CMD = `"${process.execPath}" "${DIST_PACKAGES_BUILD_SCRIPT}"`; /** - * A tool that can install Angular dependencies for a project from NPM or from the + * A tool that can install Angular/Zone.js dependencies for a project from NPM or from the * locally built distributables. * * This tool is used to change dependencies of the `aio` application and the example @@ -33,7 +34,7 @@ class NgPackagesInstaller { * @param {object} options - a hash of options for the install: * * `debug` (`boolean`) - whether to display debug messages. * * `force` (`boolean`) - whether to force a local installation even if there is a local marker file. - * * `buildPackages` (`boolean`) - whether to build the local Angular packages before using them. + * * `buildPackages` (`boolean`) - whether to build the local Angular/Zone.js packages before using them. * (NOTE: Building the packages is currently not supported on Windows, so a message is printed instead.) * * `ignorePackages` (`string[]`) - a collection of names of packages that should not be copied over. */ @@ -52,7 +53,7 @@ class NgPackagesInstaller { /** * Check whether the dependencies have been overridden with locally built - * Angular packages. This is done by checking for the `_local_.json` marker file. + * Angular/Zone.js packages. This is done by checking for the `_local_.json` marker file. * This will emit a warning to the console if the dependencies have been overridden. */ checkDependencies() { @@ -62,8 +63,8 @@ class NgPackagesInstaller { } /** - * Install locally built Angular dependencies, overriding the dependencies in the package.json - * This will also write a "marker" file (`_local_.json`), which contains the overridden package.json + * Install locally built Angular/Zone.js dependencies, overriding the dependencies in the `package.json`. + * This will also write a "marker" file (`_local_.json`), which contains the overridden `package.json` * contents and acts as an indicator that dependencies have been overridden. */ installLocalDependencies() { @@ -86,13 +87,13 @@ class NgPackagesInstaller { // Prevent accidental publishing of the package, if something goes wrong. tmpConfig.private = true; - // Overwrite project dependencies/devDependencies to Angular packages with local files. + // Overwrite project dependencies/devDependencies to Angular/Zone.js packages with local files. ['dependencies', 'devDependencies'].forEach(prop => { const deps = tmpConfig[prop] || {}; Object.keys(deps).forEach(key2 => { const pkg2 = packages[key2]; if (pkg2) { - // point the core Angular packages at the distributable folder + // point the local packages at the distributable folder deps[key2] = `file:${pkg2.packageDir}`; this._log(`Overriding dependency of local ${key} with local package: ${key2}: ${deps[key2]}`); } @@ -125,8 +126,8 @@ class NgPackagesInstaller { fs.writeFileSync(pathToPackageConfig, packageConfigFile); } } finally { - // Restore local Angular packages dependencies to other Angular packages. - this._log(`Restoring original ${PACKAGE_JSON} for local Angular packages.`); + // Restore local Angular/Zone.js packages dependencies to other Angular packages. + this._log(`Restoring original ${PACKAGE_JSON} for local packages.`); Object.keys(packages).forEach(key => { const pkg = packages[key]; fs.writeFileSync(pkg.packageJsonPath, JSON.stringify(pkg.config, null, 2)); @@ -167,7 +168,7 @@ class NgPackagesInstaller { } /** - * Build the local Angular packages. + * Build the local Angular/Zone.js packages. * * NOTE: * Building the packages is currently not supported on Windows, so a message is printed instead, prompting the user to @@ -177,14 +178,14 @@ class NgPackagesInstaller { const canBuild = process.platform !== 'win32'; if (canBuild) { - this._log(`Building the Angular packages with: ${DIST_PACKAGES_BUILD_SCRIPT}`); + this._log(`Building the local packages with: ${DIST_PACKAGES_BUILD_SCRIPT}`); shelljs.exec(DIST_PACKAGES_BUILD_CMD); } else { this._warn([ - 'Automatically building the local Angular packages is currently not supported on Windows.', - `Please, ensure '${ANGULAR_DIST_PACKAGES_DIR}' exists and is up-to-date (e.g. by running ` + - `'${DIST_PACKAGES_BUILD_SCRIPT}' in Git Bash for Windows, Windows Subsystem for Linux or a Linux docker ` + - 'container or VM).', + 'Automatically building the local Angular/Zone.js packages is currently not supported on Windows.', + `Please, ensure '${ANGULAR_DIST_PACKAGES_DIR}' and '${ZONEJS_DIST_PACKAGES_DIR}' exist and are up-to-date ` + + `(e.g. by running '${DIST_PACKAGES_BUILD_SCRIPT}' in Git Bash for Windows, Windows Subsystem for Linux or ` + + 'a Linux docker container or VM).', '', 'Proceeding anyway...', ].join('\n')); @@ -204,7 +205,7 @@ class NgPackagesInstaller { // grab peer dependencies const sourcePackagePeerDeps = sourcePackage.config.peerDependencies || {}; Object.keys(sourcePackagePeerDeps) - // ignore peerDependencies which are already core Angular packages + // ignore peerDependencies which are already core Angular/Zone.js packages .filter(key => !packages[key]) .forEach(key => peerDependencies[key] = sourcePackagePeerDeps[key]); } @@ -214,11 +215,13 @@ class NgPackagesInstaller { } /** - * A hash of Angular package configs. - * (Detected as directories in '/dist/packages-dist/' that contain a top-level 'package.json' file.) + * A hash of Angular/Zone.js package configs. + * (Detected as directories in '/dist/packages-dist/' and '/dist/zone.js-dist/' that contain a top-level + * 'package.json' file.) */ _getDistPackages() { this._log(`Angular distributable directory: ${ANGULAR_DIST_PACKAGES_DIR}.`); + this._log(`Zone.js distributable directory: ${ZONEJS_DIST_PACKAGES_DIR}.`); if (this.buildPackages) { this._buildDistPackages(); @@ -254,7 +257,10 @@ class NgPackagesInstaller { return packages; }; - const packageConfigs = collectPackages(ANGULAR_DIST_PACKAGES_DIR); + const packageConfigs = { + ...collectPackages(ANGULAR_DIST_PACKAGES_DIR), + ...collectPackages(ZONEJS_DIST_PACKAGES_DIR), + }; this._log('Found the following Angular distributables:', Object.keys(packageConfigs).map(key => `\n - ${key}`)); return packageConfigs; @@ -343,7 +349,7 @@ class NgPackagesInstaller { // Log a warning. this._warn([ - `The project at "${absoluteProjectDir}" is running against the local Angular build.`, + `The project at "${absoluteProjectDir}" is running against the local Angular/Zone.js build.`, '', 'To restore the npm packages run:', '', @@ -396,10 +402,10 @@ function main() { .option('debug', { describe: 'Print additional debug information.', default: false }) .option('force', { describe: 'Force the command to execute even if not needed.', default: false }) - .option('build-packages', { describe: 'Build the local Angular packages, before using them.', default: false }) - .option('ignore-packages', { describe: 'List of Angular packages that should not be used in local mode.', default: [], array: true }) + .option('build-packages', { describe: 'Build the local Angular/Zone.js packages, before using them.', default: false }) + .option('ignore-packages', { describe: 'List of Angular/Zone.js packages that should not be used in local mode.', default: [], array: true }) - .command('overwrite [--force] [--debug] [--ignore-packages package1 package2]', 'Install dependencies from the locally built Angular distributables.', () => {}, argv => { + .command('overwrite [--force] [--debug] [--ignore-packages package1 package2]', 'Install dependencies from the locally built Angular/Zone.js distributables.', () => {}, argv => { createInstaller(argv).installLocalDependencies(); }) .command('restore [--debug]', 'Install dependencies from the npm registry.', () => {}, argv => { diff --git a/aio/tools/ng-packages-installer/index.spec.js b/aio/tools/ng-packages-installer/index.spec.js index 3878859d3c..d54153f177 100644 --- a/aio/tools/ng-packages-installer/index.spec.js +++ b/aio/tools/ng-packages-installer/index.spec.js @@ -15,6 +15,7 @@ describe('NgPackagesInstaller', () => { const yarnLockPath = path.resolve(absoluteProjectDir, 'yarn.lock'); const ngRootDir = path.resolve(__dirname, '../../..'); const packagesDir = path.join(ngRootDir, 'dist/packages-dist'); + const zoneJsDir = path.join(ngRootDir, 'dist/zone.js-dist'); const toolsDir = path.join(ngRootDir, 'dist/tools/@angular'); let installer; @@ -51,7 +52,7 @@ describe('NgPackagesInstaller', () => { describe('installLocalDependencies()', () => { const copyJsonObj = obj => JSON.parse(JSON.stringify(obj)); - let dummyNgPackages, dummyPackage, dummyPackageJson, expectedModifiedPackage, expectedModifiedPackageJson; + let dummyLocalPackages, dummyPackage, dummyPackageJson, expectedModifiedPackage, expectedModifiedPackageJson; beforeEach(() => { spyOn(installer, '_checkLocalMarker'); @@ -60,17 +61,18 @@ describe('NgPackagesInstaller', () => { spyOn(installer, '_parseLockfile').and.returnValue({ 'rxjs@^6.3.0': {version: '6.3.3'}, - 'zone.js@^0.8.26': {version: '0.8.27'} + 'rxjs-dev@^6.3.0': {version: '6.4.2'} }); // These are the packages that are "found" in the dist directory - dummyNgPackages = { + dummyLocalPackages = { '@angular/core': { packageDir: `${packagesDir}/core`, packageJsonPath: `${packagesDir}/core/package.json`, config: { peerDependencies: { 'rxjs': '^6.4.0', + 'rxjs-dev': '^6.4.0', 'some-package': '5.0.1', 'zone.js': '~0.8.26' } @@ -101,32 +103,40 @@ describe('NgPackagesInstaller', () => { devDependencies: { '@angular/common': '4.4.4-1ab23cd4' }, peerDependencies: { tsickle: '^1.4.0' } } - } + }, + 'zone.js': { + packageDir: `${zoneJsDir}/zone.js`, + packageJsonPath: `${zoneJsDir}/zone.js/package.json`, + config: { + devDependencies: { typescript: '^2.4.2' } + } + }, }; - spyOn(installer, '_getDistPackages').and.callFake(() => copyJsonObj(dummyNgPackages)); + spyOn(installer, '_getDistPackages').and.callFake(() => copyJsonObj(dummyLocalPackages)); // This is the package.json in the "test" folder dummyPackage = { dependencies: { '@angular/core': '4.4.1', '@angular/common': '4.4.1', - rxjs: '^6.3.0' + rxjs: '^6.3.0', + 'zone.js': '^0.8.26' }, devDependencies: { '@angular/compiler-cli': '4.4.1', - 'zone.js': '^0.8.26' + 'rxjs-dev': '^6.3.0' } }; dummyPackageJson = JSON.stringify(dummyPackage); fs.readFileSync.and.returnValue(dummyPackageJson); // This is the package.json that is temporarily written to the "test" folder - // Note that the Angular (dev)dependencies have been modified to use a "file:" path - // And that the peerDependencies from `dummyNgPackages` have been updated or added as + // Note that the Angular/Zone.js (dev)dependencies have been modified to use a "file:" path + // and that the peerDependencies from `dummyLocalPackages` have been updated or added as // (dev)dependencies (unless the current version in lockfile satisfies semver). // - // For example, `zone.js@0.8.27` (from lockfile) satisfies `zone.js@~0.8.26` (from - // `@angular/core`), thus `zone.js: ^0.8.26` (from original `package.json`) is retained. + // For example, `rxjs-dev@6.4.2` (from lockfile) satisfies `rxjs-dev@^6.4.0` (from + // `@angular/core`), thus `rxjs-dev: ^6.3.0` (from original `package.json`) is retained. // In contrast, `rxjs@6.3.3` (from lockfile) does not satisfy `rxjs@^6.4.0 (from // `@angular/core`), thus `rxjs: ^6.3.0` (from original `package.json`) is replaced with // `rxjs: ^6.4.0` (from `@angular/core`). @@ -134,11 +144,12 @@ describe('NgPackagesInstaller', () => { dependencies: { '@angular/core': `file:${packagesDir}/core`, '@angular/common': `file:${packagesDir}/common`, - 'rxjs': '^6.4.0' + 'rxjs': '^6.4.0', + 'zone.js': `file:${zoneJsDir}/zone.js`, }, devDependencies: { '@angular/compiler-cli': `file:${toolsDir}/compiler-cli`, - 'zone.js': '^0.8.26', + 'rxjs-dev': '^6.3.0', 'some-package': '5.0.1', typescript: '^2.4.2' }, @@ -182,31 +193,56 @@ describe('NgPackagesInstaller', () => { }); it('should temporarily overwrite the package.json files of local Angular packages', () => { - const pkgJsonFor = pkgName => dummyNgPackages[`@angular/${pkgName}`].packageJsonPath; - const pkgConfigFor = pkgName => copyJsonObj(dummyNgPackages[`@angular/${pkgName}`].config); + const pkgJsonPathFor = pkgName => dummyLocalPackages[pkgName].packageJsonPath; + const pkgConfigFor = pkgName => copyJsonObj(dummyLocalPackages[pkgName].config); const overwriteConfigFor = (pkgName, newProps) => Object.assign(pkgConfigFor(pkgName), newProps); const stringifyConfig = config => JSON.stringify(config, null, 2); const allArgs = fs.writeFileSync.calls.allArgs(); - const firstFiveArgs = allArgs.slice(0, 5); - const lastFiveArgs = allArgs.slice(-5); + const firstSixArgs = allArgs.slice(0, 6); + const lastSixArgs = allArgs.slice(-6); - expect(firstFiveArgs).toEqual([ - [pkgJsonFor('core'), stringifyConfig(overwriteConfigFor('core', {private: true}))], - [pkgJsonFor('common'), stringifyConfig(overwriteConfigFor('common', {private: true}))], - [pkgJsonFor('compiler'), stringifyConfig(overwriteConfigFor('compiler', {private: true}))], - [pkgJsonFor('compiler-cli'), stringifyConfig(overwriteConfigFor('compiler-cli', { - private: true, - dependencies: { '@angular/tsc-wrapped': `file:${toolsDir}/tsc-wrapped` } - }))], - [pkgJsonFor('tsc-wrapped'), stringifyConfig(overwriteConfigFor('tsc-wrapped', { - private: true, - devDependencies: { '@angular/common': `file:${packagesDir}/common` } - }))], + expect(firstSixArgs).toEqual([ + [ + pkgJsonPathFor('@angular/core'), + stringifyConfig(overwriteConfigFor('@angular/core', {private: true})), + ], + [ + pkgJsonPathFor('@angular/common'), + stringifyConfig(overwriteConfigFor('@angular/common', {private: true})), + ], + [ + pkgJsonPathFor('@angular/compiler'), + stringifyConfig(overwriteConfigFor('@angular/compiler', {private: true})), + ], + [ + pkgJsonPathFor('@angular/compiler-cli'), + stringifyConfig(overwriteConfigFor('@angular/compiler-cli', { + private: true, + dependencies: { '@angular/tsc-wrapped': `file:${toolsDir}/tsc-wrapped` }, + })), + ], + [ + pkgJsonPathFor('@angular/tsc-wrapped'), + stringifyConfig(overwriteConfigFor('@angular/tsc-wrapped', { + private: true, + devDependencies: { '@angular/common': `file:${packagesDir}/common` }, + })), + ], + [ + pkgJsonPathFor('zone.js'), + stringifyConfig(overwriteConfigFor('zone.js', {private: true})), + ], ]); - expect(lastFiveArgs).toEqual(['core', 'common', 'compiler', 'compiler-cli', 'tsc-wrapped'] - .map(pkgName => [pkgJsonFor(pkgName), stringifyConfig(pkgConfigFor(pkgName))])); + expect(lastSixArgs).toEqual([ + '@angular/core', + '@angular/common', + '@angular/compiler', + '@angular/compiler-cli', + '@angular/tsc-wrapped', + 'zone.js', + ].map(pkgName => [pkgJsonPathFor(pkgName), stringifyConfig(pkgConfigFor(pkgName))])); }); it('should load the package.json', () => { @@ -280,7 +316,7 @@ describe('NgPackagesInstaller', () => { expect(shelljs.exec).not.toHaveBeenCalled(); expect(warning).toContain( - 'Automatically building the local Angular packages is currently not supported on Windows.'); + 'Automatically building the local Angular/Zone.js packages is currently not supported on Windows.'); expect(warning).toContain('Git Bash for Windows'); expect(warning).toContain('Windows Subsystem for Linux'); expect(warning).toContain('Linux docker container or VM'); @@ -309,8 +345,8 @@ describe('NgPackagesInstaller', () => { expect(installer._buildDistPackages).not.toHaveBeenCalled(); }); - it('should include top level Angular packages', () => { - const ngPackages = installer._getDistPackages(); + it('should include top level Angular and Zone.js packages', () => { + const localPackages = installer._getDistPackages(); const expectedValue = jasmine.objectContaining({ packageDir: jasmine.any(String), packageJsonPath: jasmine.any(String), @@ -318,28 +354,30 @@ describe('NgPackagesInstaller', () => { }); // For example... - expect(ngPackages['@angular/common']).toEqual(expectedValue); - expect(ngPackages['@angular/core']).toEqual(expectedValue); - expect(ngPackages['@angular/router']).toEqual(expectedValue); - expect(ngPackages['@angular/upgrade']).toEqual(expectedValue); + expect(localPackages['@angular/common']).toEqual(expectedValue); + expect(localPackages['@angular/core']).toEqual(expectedValue); + expect(localPackages['@angular/router']).toEqual(expectedValue); + expect(localPackages['@angular/upgrade']).toEqual(expectedValue); + expect(localPackages['zone.js']).toEqual(expectedValue); - expect(ngPackages['@angular/upgrade/static']).not.toBeDefined(); + expect(localPackages['@angular/upgrade/static']).not.toBeDefined(); }); it('should store each package\'s directory', () => { - const ngPackages = installer._getDistPackages(); + const localPackages = installer._getDistPackages(); // For example... - expect(ngPackages['@angular/core'].packageDir).toBe(path.join(packagesDir, 'core')); - expect(ngPackages['@angular/router'].packageDir).toBe(path.join(packagesDir, 'router')); + expect(localPackages['@angular/core'].packageDir).toBe(path.join(packagesDir, 'core')); + expect(localPackages['@angular/router'].packageDir).toBe(path.join(packagesDir, 'router')); + expect(localPackages['zone.js'].packageDir).toBe(path.join(zoneJsDir, 'zone.js')); }); it('should not include packages that have been ignored', () => { installer = new NgPackagesInstaller(projectDir, { ignorePackages: ['@angular/router'] }); - const ngPackages = installer._getDistPackages(); + const localPackages = installer._getDistPackages(); - expect(ngPackages['@angular/common']).toBeDefined(); - expect(ngPackages['@angular/router']).toBeUndefined(); + expect(localPackages['@angular/common']).toBeDefined(); + expect(localPackages['@angular/router']).toBeUndefined(); }); }); @@ -480,7 +518,7 @@ describe('NgPackagesInstaller', () => { describe('_printWarning()', () => { it('should mention the message passed in the warning', () => { installer._printWarning(); - expect(console.warn.calls.argsFor(0)[0]).toContain('is running against the local Angular build'); + expect(console.warn.calls.argsFor(0)[0]).toContain('is running against the local Angular/Zone.js build'); }); it('should mention the command to restore the Angular packages in any warning', () => { diff --git a/scripts/build/build-ivy-npm-packages.js b/scripts/build/build-ivy-npm-packages.js index 04bdec2776..77447dfaad 100755 --- a/scripts/build/build-ivy-npm-packages.js +++ b/scripts/build/build-ivy-npm-packages.js @@ -9,8 +9,18 @@ 'use strict'; +const {buildZoneJsPackage} = require('./zone-js-builder'); const {buildTargetPackages} = require('./package-builder'); // Build the ivy packages into `dist/packages-dist-ivy-aot/`. buildTargetPackages('dist/packages-dist-ivy-aot', true, 'Ivy AOT'); + +// Build the `zone.js` npm package into `dist/zone.js-dist-ivy-aot/`, because it might be needed by +// other scripts/tests. +// +// NOTE: +// The `-ivy-aot` suffix is only used to differentiate from the packages built by the +// `build-packages-dist.js` script, so that there is no conflict when persisting them to the +// workspace on CI. +buildZoneJsPackage('dist/zone.js-dist-ivy-aot'); diff --git a/scripts/build/build-packages-dist.js b/scripts/build/build-packages-dist.js index 821bb4f456..3e7c9bd5bd 100755 --- a/scripts/build/build-packages-dist.js +++ b/scripts/build/build-packages-dist.js @@ -19,7 +19,7 @@ buildTargetPackages('dist/packages-dist', false, 'Production'); // Build the `zone.js` npm package into `dist/zone.js-dist/`, because it might be needed by other // scripts/tests. -buildZoneJsPackage(); +buildZoneJsPackage('dist/zone.js-dist'); // Build the `angular-dev-infra` npm package into `dist/packages-dist/@angular/dev-infra-private` buildDevInfraPackage(); diff --git a/scripts/build/package-builder.js b/scripts/build/package-builder.js index b5c2d53350..f1b153bc21 100644 --- a/scripts/build/package-builder.js +++ b/scripts/build/package-builder.js @@ -51,7 +51,7 @@ module.exports = { }; /** - * Build the packages. + * Build the Angular packages. * * @param {string} destPath Path to the output directory into which we copy the npm packages. * This path should either be absolute or relative to the project root. diff --git a/scripts/build/zone-js-builder.js b/scripts/build/zone-js-builder.js index 59cb8de31f..d43489df37 100644 --- a/scripts/build/zone-js-builder.js +++ b/scripts/build/zone-js-builder.js @@ -8,7 +8,8 @@ 'use strict'; -const {chmod, cp, mkdir, rm} = require('shelljs'); +const {resolve} = require('path'); +const {chmod, cp, mkdir, rm, test} = require('shelljs'); const {baseDir, bazelBin, bazelCmd, exec, scriptPath} = require('./package-builder'); @@ -18,27 +19,33 @@ module.exports = { /** * Build the `zone.js` npm package into `dist/bin/packages/zone.js/npm_package/` and copy it to - * `dist/zone.js-dist/` for other scripts/tests to use. + * `destPath` for other scripts/tests to use. * * NOTE: The `zone.js` package is not built as part of `package-builder`'s `buildTargetPackages()` * nor is it copied into the same directory as the Angular packages (e.g. * `dist/packages-dist/`) despite its source's being inside `packages/`, because it is not * published to npm under the `@angular` scope (as happens for the rest of the packages). + * + * @param {string} destPath Path to the output directory into which we copy the npm package. + * This path should either be absolute or relative to the project root. */ -function buildZoneJsPackage() { +function buildZoneJsPackage(destPath) { console.info('##############################'); console.info(`${scriptPath}:`); console.info(' Building zone.js npm package'); console.info('##############################'); exec(`${bazelCmd} build //packages/zone.js:npm_package`); - // Copy artifacts to `dist/zone.js-dist/`, so they can be easier persisted on CI and used by - // non-bazel scripts/tests. + // Create the output directory. + const absDestPath = resolve(baseDir, destPath); + if (!test('-d', absDestPath)) mkdir('-p', absDestPath); + + // Copy artifacts to `destPath`, so they can be easier persisted on CI and used by non-bazel + // scripts/tests. const buildOutputDir = `${bazelBin}/packages/zone.js/npm_package`; - const distTargetDir = `${baseDir}/dist/zone.js-dist/zone.js`; + const distTargetDir = `${absDestPath}/zone.js`; console.info(`# Copy artifacts to ${distTargetDir}`); - mkdir('-p', distTargetDir); rm('-rf', distTargetDir); cp('-R', buildOutputDir, distTargetDir); chmod('-R', 'u+w', distTargetDir);