如何使用 angular-cli 构建多个应用程序?

How to build multiple applications with angular-cli?

angular-cli.json文件中的属性apps为数组类型。如果我将第二个元素添加到此数组中,我如何指示 ng build 构建这两个元素?

我搜索了 angular-cli 源代码,但找不到任何对迭代或以其他方式检查 apps 内容作为数组的代码的引用。

截至目前(angular-cli 版本 1.0.0-beta.15),处理 apps 的每个代码实例都使用硬编码数组的第一个元素(apps[0] ).似乎没有办法 select 应用程序来构建或更改使用数组第一个元素的默认行为。

apps 元素的 JSON 架构是这样描述的:

此项目中不同应用程序的属性。

/**
 * Properties of the different applications in this project.
 */
apps?: {
    root?: string;
    outDir?: string;
    assets?: string;
    index?: string;
    main?: string;
    test?: string;
    tsconfig?: string;
    prefix?: string;
    mobile?: boolean;
    /**
     * Global styles to be included in the build.
     */
    styles?: string[];
    /**
     * Global scripts to be included in the build.
     */
    scripts?: string[];
    /**
     * Name and corresponding file for environment config.
     */
    environments?: {
        [name: string]: any;
    };
}[];

该项目的未来意图似乎是支持从同一代码库构建多个应用程序,但目前看来这并不可行(1.0.0-beta.15 版本)。

目前v1.0.0您只能select您想要通过以下命令构建的应用程序:

ng build -a appName

ng build --app appName

您还需要将 name 属性 添加到 apps 数组中的每个元素,这样您就会得到类似的内容:

"apps": [ { "name": "app1", "root": "src/app1root", ... }, { "name": "app2", "root": "src/app2root", ... }, ... ]

您也可以使用 ng build -a 0ng build -a 1 等应用索引,在这种情况下您不需要指定应用名称。

从 angular-cli sorces 你可以看到不可能 运行 一个命令中的所有应用程序,你应该指定索引或应用程序名称否则 apps[0] 将被使用,因此您无法使用一个 ng build 调用同时构建所有应用程序。

仍然没有任何标志 ng build --app 可以使用一个命令构建所有应用程序,因此解决此问题的最佳方法是在根目录中创建 Makefile 文件项目:

my-app
  --dist/
  --e2e/
  --src/
  .angular-cli.json
  package.json
  Makefile 

Makefiles 允许根据您提供的说明组织代码编译。 因此,我们需要提供指令以将所有应用程序的前端构建到输出目录中。 现在 Makefile 文件看起来像这样:

help:
    @echo "_______BUILD ANGULAR FRONTEND______\n"
    @echo "To build all apps run make make build-frontend"

build-frontend:
    ng build -a=0 &&\
    ng build -a=1 

但是,在您复制粘贴上面的代码后,将空格更改为制表符。否则你会得到无效的 Makefile *** missing separator error

导航到根项目并进行测试,在终端中键入 make,您应该会打印帮助消息。在那个类型之后:

make build-frontend

现在您只需一个命令即可构建多个应用程序。

我也在这里回答了类似的问题 -> Angular 6 CLI -> how to make ng build build project + libraries

这适用于 >= ng6。如果你想要旧版本的 cli,你可以看看这个版本 -> https://gist.github.com/bmarti44/f6b8d3d7b331cd79305ca8f45eb8997b/03c3b788551cd43db38d2f48e207a730aaba5b6f

我创建了一个脚本,当它与 angular.json 放在同一个文件夹中时,它将拉入文件,循环遍历项目,并异步地批量构建它们。

这是一个快速要点,您可以切换输出路径和异步构建的数量。我暂时排除了 e2e,但您可以删除对 filteredProjects 函数的引用,对于作为项目的 e2e,它也会 运行。将它作为 npm 运行 脚本添加到 package.json 也很容易。到目前为止,它一直运行良好。

https://gist.github.com/bmarti44/f6b8d3d7b331cd79305ca8f45eb8997b

const fs = require('fs'),
  spawn = require('child_process').spawn,
  // Custom output path.
  outputPath = '/nba-angular',
  // Number of projects to build asynchronously.
  batch = 3;

let ngCli;

function buildProject(project) {
  return new Promise((resolve, reject) => {
    let child = spawn('ng', ['build', '--project', project, '--prod', '--extract-licenses', '--build-optimizer', `--output-path=${outputPath}/dist/` + project]);

    child.stdout.on('data', (data) => {
      console.log(data.toString());
    });

    child.stderr.on('data', (data) => {
      process.stdout.write('.');
    });

    child.on('close', (code) => {
      if (code === 0) {
        resolve(code);
      } else {
        reject(code);
      }
    });
  })
}

function filterProjects(projects) {
  return Object.keys(projects).filter(project => project.indexOf('e2e') === -1);
}

function batchProjects(projects) {
  let currentBatch = 0,
    i,
    batches = {};

  for (i = 0; i < projects.length; i += 1) {
    if ((i) % batch === 0) {
      currentBatch += 1;
    }
    if (typeof (batches['batch' + currentBatch]) === 'undefined') {
      batches['batch' + currentBatch] = [];
    }

    batches['batch' + currentBatch].push(projects[i]);
  }
  return batches;
}

fs.readFile('angular.json', 'utf8', async (err, data) => {
  let batches = {},
    batchesArray = [],
    i;

  if (err) {
    throw err;
  }

  ngCli = JSON.parse(data);

  batches = batchProjects(filterProjects(ngCli.projects));
  batchesArray = Object.keys(batches);

  for (i = 0; i < batchesArray.length; i += 1) {
    let promises = [];

    batches[batchesArray[i]].forEach((project) => {
      promises.push(buildProject(project));
    });

    console.log('Building projects ' + batches[batchesArray[i]].join(','));

    await Promise.all(promises).then(statusCode => {
      console.log('Projects ' + batches[batchesArray[i]].join(',') + ' built successfully!');
      if (i + 1 === batchesArray.length) {
        process.exit(0);
      }
    }, (reject) => {
      console.log(reject);
      process.exit(1);
    });
  }
});

对于 Angular 6+:

**Dev build**

ng build --project="second-app"

**Prod build**

ng build --configuration production --project="second-app"

截至2019年10月28日构建具体项目的正确方法from the docs

ng build <app name>

有一个 open issue in GitHub 添加一次构建多个项目的能力。

使用你的package.json:

"scripts": {
   "build-projects": "ng build project1 && ng build project2",
}

然后 运行: npm run build projects.