示例#1
0
  run(builderConfig: BuilderConfiguration<BrowserBuilderSchema>): Observable<BuildEvent> {
    const options = builderConfig.options;
    const root = this.context.workspace.root;
    const projectRoot = resolve(root, builderConfig.root);
    const host = new virtualFs.AliasHost(this.context.host as virtualFs.Host<fs.Stats>);
    const webpackBuilder = new WebpackBuilder({ ...this.context, host });

    return of(null).pipe(
      concatMap(() => options.deleteOutputPath
        ? this._deleteOutputDir(root, normalize(options.outputPath), this.context.host)
        : of(null)),
      concatMap(() => normalizeFileReplacements(options.fileReplacements, host, root)),
      tap(fileReplacements => options.fileReplacements = fileReplacements),
      concatMap(() => normalizeAssetPatterns(
        options.assets, host, root, projectRoot, builderConfig.sourceRoot)),
      // Replace the assets in options with the normalized version.
      tap((assetPatternObjects => options.assets = assetPatternObjects)),
      concatMap(() => {
        // Ensure Build Optimizer is only used with AOT.
        if (options.buildOptimizer && !options.aot) {
          throw new Error('The `--build-optimizer` option cannot be used without `--aot`.');
        }

        let webpackConfig;
        try {
          webpackConfig = this.buildWebpackConfig(root, projectRoot, host,
            options as NormalizedBrowserBuilderSchema);
        } catch (e) {
          return throwError(e);
        }

        return webpackBuilder.runWebpack(webpackConfig, getBrowserLoggingCb(options.verbose));
      }),
      concatMap(buildEvent => {
        if (buildEvent.success && !options.watch && options.serviceWorker) {
          return new Observable(obs => {
            augmentAppWithServiceWorker(
              this.context.host,
              root,
              projectRoot,
              resolve(root, normalize(options.outputPath)),
              options.baseHref || '/',
              options.ngswConfigPath,
            ).then(
              () => {
                obs.next({ success: true });
                obs.complete();
              },
              (err: Error) => {
                obs.error(err);
              },
            );
          });
        } else {
          return of(buildEvent);
        }
      }),
    );
  }
示例#2
0
  run(builderConfig: BuilderConfiguration<ExtractI18nBuilderOptions>): Observable<BuildEvent> {
    const architect = this.context.architect;
    const options = builderConfig.options;
    const root = this.context.workspace.root;
    const projectRoot = resolve(root, builderConfig.root);
    const [project, targetName, configuration] = options.browserTarget.split(':');
    // Override browser build watch setting.
    const overrides = { watch: false };

    const browserTargetSpec = { project, target: targetName, configuration, overrides };
    const browserBuilderConfig = architect.getBuilderConfiguration<BrowserBuilderSchema>(
      browserTargetSpec);
    const webpackBuilder = new WebpackBuilder(this.context);

    const loggingCb: LoggingCallback = (stats, config, logger) => {
      const json = stats.toJson();
      if (stats.hasWarnings()) {
        this.context.logger.warn(statsWarningsToString(json, config.stats));
      }

      if (stats.hasErrors()) {
        this.context.logger.error(statsErrorsToString(json, config.stats));
      }
    };

    return architect.getBuilderDescription(browserBuilderConfig).pipe(
      concatMap(browserDescription =>
        architect.validateBuilderOptions(browserBuilderConfig, browserDescription)),
      map(browserBuilderConfig => browserBuilderConfig.options),
      concatMap((validatedBrowserOptions) => {
        const browserOptions = validatedBrowserOptions;

        // We need to determine the outFile name so that AngularCompiler can retrieve it.
        let outFile = options.outFile || getI18nOutfile(options.i18nFormat);
        if (options.outputPath) {
          // AngularCompilerPlugin doesn't support genDir so we have to adjust outFile instead.
          outFile = path.join(options.outputPath, outFile);
        }

        // Extracting i18n uses the browser target webpack config with some specific options.
        const webpackConfig = this.buildWebpackConfig(root, projectRoot, {
          // todo: remove this casting when 'CurrentFileReplacement' is changed to 'FileReplacement'
          ...(browserOptions as NormalizedBrowserBuilderSchema),
          optimization: false,
          i18nLocale: options.i18nLocale,
          i18nFormat: options.i18nFormat,
          i18nFile: outFile,
          aot: true,
          progress: options.progress,
          assets: [],
          scripts: [],
          styles: [],
        });

        return webpackBuilder.runWebpack(webpackConfig, loggingCb);
      }),
    );
  }
示例#3
0
 private _gitInit(): Observable<void> {
   return this._exec('git', ['init']).pipe(
     concatMap(() => this._exec('git', ['config', 'user.email', '*****@*****.**'])),
     concatMap(() => this._exec('git', ['config', 'user.name', 'Angular DevKit Tests'])),
     concatMap(() => this._exec('git', ['add', '--all'])),
     concatMap(() => this._exec('git', ['commit', '-am', '"Initial commit"'])),
     map(() => { }),
   );
 }
示例#4
0
  it('lint works', (done) => {
    const targetSpec: TargetSpecifier = { project: 'lib', target: 'lint' };

    return workspace.loadWorkspaceFromHost(workspaceFile).pipe(
      concatMap(ws => new Architect(ws).loadArchitect()),
      concatMap(arch => arch.run(arch.getBuilderConfiguration(targetSpec))),
      tap((buildEvent) => expect(buildEvent.success).toBe(true)),
    ).subscribe(undefined, done.fail, done);
  }, 30000);
示例#5
0
  buildBrowserConfig(options: CordovaBuildBuilderSchema): Observable<BuilderConfiguration<BrowserBuilderSchema>> {
    let browserConfig: BuilderConfiguration<BrowserBuilderSchema>;

    return of(null).pipe(// tslint:disable-line:no-null-keyword
      concatMap(() => this._getBrowserConfig(options)),
      tap(config => browserConfig = config),
      tap(() => this.prepareBrowserConfig(options, browserConfig.options)),
      concatMap(() => of(browserConfig))
    );
  }
  it('supports options', (done) => {
    host.writeMultipleFiles({ 'src/styles.css': `h1 { background: url('./spectrum.png')}` });
    host.writeMultipleFiles(lazyModuleFiles);
    host.writeMultipleFiles(lazyModuleImport);

    const overrides = { outputHashing: 'all', extractCss: true };

    // We must do several builds instead of a single one in watch mode, so that the output
    // path is deleted on each run and only contains the most recent files.
    // 'all' should hash everything.
    runTargetSpec(host, browserTargetSpec, overrides, DefaultTimeout * 2).pipe(
      tap(() => {
        expect(host.fileMatchExists('dist', /runtime\.[0-9a-f]{20}\.js/)).toBeTruthy();
        expect(host.fileMatchExists('dist', /main\.[0-9a-f]{20}\.js/)).toBeTruthy();
        expect(host.fileMatchExists('dist', /polyfills\.[0-9a-f]{20}\.js/)).toBeTruthy();
        expect(host.fileMatchExists('dist', /vendor\.[0-9a-f]{20}\.js/)).toBeTruthy();
        expect(host.fileMatchExists('dist', /styles\.[0-9a-f]{20}\.css/)).toBeTruthy();
        expect(host.fileMatchExists('dist', /spectrum\.[0-9a-f]{20}\.png/)).toBeTruthy();
      }),
      // 'none' should hash nothing.
      concatMap(() => runTargetSpec(host, browserTargetSpec,
        { outputHashing: 'none', extractCss: true })),
      tap(() => {
        expect(host.fileMatchExists('dist', /runtime\.[0-9a-f]{20}\.js/)).toBeFalsy();
        expect(host.fileMatchExists('dist', /main\.[0-9a-f]{20}\.js/)).toBeFalsy();
        expect(host.fileMatchExists('dist', /polyfills\.[0-9a-f]{20}\.js/)).toBeFalsy();
        expect(host.fileMatchExists('dist', /vendor\.[0-9a-f]{20}\.js/)).toBeFalsy();
        expect(host.fileMatchExists('dist', /styles\.[0-9a-f]{20}\.css/)).toBeFalsy();
        expect(host.fileMatchExists('dist', /spectrum\.[0-9a-f]{20}\.png/)).toBeFalsy();
      }),
      // 'media' should hash css resources only.
      concatMap(() => runTargetSpec(host, browserTargetSpec,
        { outputHashing: 'media', extractCss: true })),
      tap(() => {
        expect(host.fileMatchExists('dist', /runtime\.[0-9a-f]{20}\.js/)).toBeFalsy();
        expect(host.fileMatchExists('dist', /main\.[0-9a-f]{20}\.js/)).toBeFalsy();
        expect(host.fileMatchExists('dist', /polyfills\.[0-9a-f]{20}\.js/)).toBeFalsy();
        expect(host.fileMatchExists('dist', /vendor\.[0-9a-f]{20}\.js/)).toBeFalsy();
        expect(host.fileMatchExists('dist', /styles\.[0-9a-f]{20}\.css/)).toBeFalsy();
        expect(host.fileMatchExists('dist', /spectrum\.[0-9a-f]{20}\.png/)).toBeTruthy();
      }),
      // 'bundles' should hash bundles only.
      concatMap(() => runTargetSpec(host, browserTargetSpec,
        { outputHashing: 'bundles', extractCss: true })),
      tap(() => {
        expect(host.fileMatchExists('dist', /runtime\.[0-9a-f]{20}\.js/)).toBeTruthy();
        expect(host.fileMatchExists('dist', /main\.[0-9a-f]{20}\.js/)).toBeTruthy();
        expect(host.fileMatchExists('dist', /polyfills\.[0-9a-f]{20}\.js/)).toBeTruthy();
        expect(host.fileMatchExists('dist', /vendor\.[0-9a-f]{20}\.js/)).toBeTruthy();
        expect(host.fileMatchExists('dist', /styles\.[0-9a-f]{20}\.css/)).toBeTruthy();
        expect(host.fileMatchExists('dist', /spectrum\.[0-9a-f]{20}\.png/)).toBeFalsy();
      }),
    ).toPromise().then(done, done.fail);
  });
示例#7
0
  it('works', (done) => {
    const overrides: Partial<DevServerBuilderOptions> = { servePath: 'test/' };

    runTargetSpec(host, devServerTargetSpec, overrides).pipe(
      tap((buildEvent) => expect(buildEvent.success).toBe(true)),
      concatMap(() => from(request('http://localhost:4200/test/'))),
      tap(response => expect(response).toContain('<title>HelloWorldApp</title>')),
      concatMap(() => from(request('http://localhost:4200/test/abc/'))),
      tap(response => expect(response).toContain('<title>HelloWorldApp</title>')),
      take(1),
    ).subscribe(undefined, done.fail, done);
  }, 30000);
示例#8
0
文件: index.ts 项目: iwe7/devkit
  run(builderConfig: BuilderConfiguration<BuildWebpackServerSchema>): Observable<BuildEvent> {
    const options = builderConfig.options;
    const root = this.context.workspace.root;
    const projectRoot = resolve(root, builderConfig.root);
    const host = new virtualFs.AliasHost(this.context.host as virtualFs.Host<Stats>);

    // TODO: verify using of(null) to kickstart things is a pattern.
    return of(null).pipe(
      concatMap(() => options.deleteOutputPath
        ? this._deleteOutputDir(root, normalize(options.outputPath), this.context.host)
        : of(null)),
      concatMap(() => addFileReplacements(root, host, options.fileReplacements)),
      concatMap(() => new Observable(obs => {
        // Ensure Build Optimizer is only used with AOT.
        const webpackConfig = this.buildWebpackConfig(root, projectRoot, host, options);
        const webpackCompiler = webpack(webpackConfig);
        const statsConfig = getWebpackStatsConfig(options.verbose);

        const callback: webpack.compiler.CompilerCallback = (err, stats) => {
          if (err) {
            return obs.error(err);
          }

          const json = stats.toJson(statsConfig);
          if (options.verbose) {
            this.context.logger.info(stats.toString(statsConfig));
          } else {
            this.context.logger.info(statsToString(json, statsConfig));
          }

          if (stats.hasWarnings()) {
            this.context.logger.warn(statsWarningsToString(json, statsConfig));
          }
          if (stats.hasErrors()) {
            this.context.logger.error(statsErrorsToString(json, statsConfig));
          }

          obs.next({ success: !stats.hasErrors() });
          obs.complete();
        };

        try {
          webpackCompiler.run(callback);
        } catch (err) {
          if (err) {
            this.context.logger.error(
              '\nAn error occured during the build:\n' + ((err && err.stack) || err));
          }
          throw err;
        }
      })),
    );
  }
示例#9
0
  run(builderConfig: BuilderConfiguration<BrowserBuilderSchema>): Observable<BuildEvent> {
    const root = this.context.workspace.root;
    const projectRoot = resolve(root, builderConfig.root);
    const host = new virtualFs.AliasHost(this.context.host as virtualFs.Host<fs.Stats>);
    const webpackBuilder = this.createWebpackBuilder({ ...this.context, host });
    const getLoggingCb = this.createLoggingFactory();

    const options = normalizeBuilderSchema(
      host,
      root,
      builderConfig,
    );

    return of(null).pipe(
      concatMap(() => options.deleteOutputPath
        ? this._deleteOutputDir(root, normalize(options.outputPath), this.context.host)
        : of(null)),
      concatMap(() => {
        let webpackConfig;
        try {
          webpackConfig = this.buildWebpackConfig(root, projectRoot, host, options);
        } catch (e) {
          return throwError(e);
        }

        return webpackBuilder.runWebpack(webpackConfig, getLoggingCb(options.verbose));
      }),
      concatMap(buildEvent => {
        if (buildEvent.success && !options.watch && options.serviceWorker) {
          return new Observable(obs => {
            augmentAppWithServiceWorker(
              this.context.host,
              root,
              projectRoot,
              resolve(root, normalize(options.outputPath)),
              options.baseHref || '/',
              options.ngswConfigPath,
            ).then(
              () => {
                obs.next({ success: true });
                obs.complete();
              },
              (err: Error) => {
                obs.error(err);
              },
            );
          });
        } else {
          return of(buildEvent);
        }
      }),
    );
  }
示例#10
0
export function runTargetSpec(
  host: TestProjectHost,
  targetSpec: TargetSpecifier,
  overrides = {},
  logger: logging.Logger = new logging.NullLogger(),
): Observable<BuildEvent> {
  targetSpec = { ...targetSpec, overrides };
  const workspace = new experimental.workspace.Workspace(workspaceRoot, host);

  return workspace.loadWorkspaceFromHost(workspaceFile).pipe(
    concatMap(ws => new Architect(ws).loadArchitect()),
    concatMap(arch => arch.run(arch.getBuilderConfiguration(targetSpec), { logger })),
  );
}