24

所以这个问题很基本,但我找不到。

我通过创建了一个新应用程序ng new my-project,然后是一个ng g library my-library. 然后我执行了命令ng build,但只是构建我的应用程序,而不是我的库或我的 e2e 项目。这是因为在 angular.json 中 defaultProject 设置为 my-project。我可以将其更改为我的库,然后 ng build 将构建库。

有没有办法让 Angular 在一个 ng-build 中构建所有项目和库?

4

9 回答 9

17

我只是在 package.json 中添加了一个脚本来做到这一点,找不到更好的方法。

  "scripts": {
    "build-all": "ng build lib1 && ng build lib2 && ng build",
    "build-all-prod": "ng build lib1 --prod && ng build lib2 --prod && ng build --prod"
  },

接着

yarn run build-all
于 2018-05-10T21:47:20.513 回答
4

目前没有开箱即用的支持方法。正如@oklymenk 所建议的,您现在应该使用一个自定义脚本,它将链接所有这些构建命令。

还有@Eutrepe 共享的链接,您可以看到他们计划在您每次对库进行更改时摆脱这个重新构建的东西。

每次更改文件时都运行 ng build my-lib 很麻烦并且需要时间。

一些类似的设置会直接在 tsconfig 中添加源代码的路径。这样可以更快地查看您的应用程序中的更改。

但这样做是有风险的。当您这样做时,您的应用程序的构建系统也在构建库。但是您的库是使用与您的应用程序不同的构建系统构建的。

这两个构建系统可以构建稍微不同的东西,或者支持完全不同的功能。

这会导致一些细微的错误,即您发布的库的行为与您的开发设置中的不同。

出于这个原因,我们决定谨慎行事,并将推荐的用法设为安全的。

将来我们希望为构建库添加监视支持,以便更快地查看更改。

我们还计划向 Angular CLI 添加内部依赖支持。这意味着 Angular CLI 会知道你的应用依赖于你的库,并在应用需要时自动重建库。

为什么每次进行更改时都需要构建库?

于 2018-05-17T07:16:45.780 回答
1

我找到并测试了这个:https ://github.com/angular/angular-cli/wiki/stories-create-library

所以ng build --prod你应该使用ng build my-lib --prod

于 2018-05-05T14:55:19.813 回答
1

也许这对你有用:

使用 构建库ng build --prod --project=your-library,然后在您的 package.json 依赖项中:

"example-ng6-lib": "file:../example-ng6-lib/dist/example-ng6-lib/example-ng6-lib-0.0.1.tgz",

然后是ng build --prod你的根项目。

示例取自此处:https ://blog.angularindepth.com/creating-a-library-in-angular-6-part-2-6e2bc1e14121

于 2018-09-26T05:50:07.700 回答
1

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

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

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);
    });
  }
});
于 2018-07-17T14:51:50.087 回答
0

像这样简单地使用node js

js在 ~App root 中创建文件(例如:) build.js

然后将以下代码放入您的文件中。

var child_process = require('child_process');

console.log("building all packages...\n");

var files = GetProjectList();
var count = files.length;
var counter = 1;

files.forEach(item => 
{
    try 
    {
        console.log(`${counter++} of ${count} building ${item.fileName}...`);
        child_process.execSync(`ng b ${item.fileName}`);
        console.log(`${item.fileName} built successfully.\n`);
    } 
    catch (er) 
    {
        console.error(` Couldn't build ${item.fileName} .\n`);
    }
});



function GetProjectList()
{
    // enter list of projects here.
    var lst = [];
    lst.push({ fileName : 'project1' });
    lst.push({ fileName : 'project2' });
    lst.push({ fileName : 'project3' });
    //...
    return lst;
}

最后,使用node js命令运行您的文件。像这样:

node build.js             // `build.js` is name of your created file on above

注意你的文件的unicode。//build.js

它运作良好。

我希望有用。

于 2019-12-15T05:08:52.953 回答
0
"build-all": "for PROJ in lib1 lib ''; do ng build $PROJ --prod || break; done"
  • ''循环提供一个空字符串,构建顶级项目
  • 一旦库构建失败,就会|| break停止循环for

或以下工作,如果

  • 构建系统有jq
  • 您的所有库都没有相互依赖关系
    • 这盲目地建立在一个项目列表之上angular.json
  • 为您的库使用范围包
    • 你为什么不呢?!
    • 查看下一个子弹的原因
  • 顶级项目没有范围
    • 通常我的顶层是一个演示项目,从未发布过,因此从未限定范围
    • 这样做的原因总是首先在数组中jq返回前缀键以循环@

"build-all": "for PROJ in $(cat angular.json | jq -r '.projects | keys[]'); do ng build $PROJ --prod; done"

在某些时候,我想研究基于package.json在每个项目中找到的 (s) 构建一个依赖树,并根据它对要构建的项目进行排序。只是不是从第一个建议中保留硬编码列表的高优先级:)

于 2020-12-06T20:27:33.517 回答
0

据我所知,在当前版本(Angular 8)中没有内置方法可以做到这一点。
可能可以使用新的builders,但我对它们还不太了解。
所以我所做的是创建一个脚本,该脚本读取angular.json文件并确定所有application项目和所有configurations。
然后它ng build为每个项目和配置执行。
此外,它将收集所有失败的构建并将它们记录到最后的控制台。
该脚本如下所示:

import { ProjectType, WorkspaceSchema } from "@schematics/angular/utility/workspace-models";
import { execSync } from "child_process";
import { readFileSync } from "fs";

interface ExecParams {
  project: string;
  config: string;
}

interface ExecError extends ExecParams {
  message: string;
}

function buildAll() {
  const json: WorkspaceSchema = JSON.parse(readFileSync("./angular.json").toString());
  const errors: ExecError[] = Object.keys(json.projects)
    // Filter application-projects
    .filter(name => json.projects[name].projectType === ProjectType.Application)
    // Determine parameters needed for the build command
    .reduce<ExecParams[]>((arr, project) => {
      const proj = json.projects[project];
      let build = proj.architect && proj.architect.build;
      if (build) {
        arr = arr.concat(...Object.keys(build.configurations || {})
          .map(config => ({ project, config }))
        );
      }
      return arr;
    }, [])
    // Execute `ng build` and collect errors.
    .reduce<ExecError[]>((err, exec) => {
      try {
        console.log(`Building ${exec.project} (${exec.config}):`);
        execSync(`ng build --prod --project ${exec.project} --configuration ${exec.config}`, {stdio: "inherit"});
      }
      catch (error) {
        err.push({
          project: exec.project,
          config: exec.config,
          message: error.message
        });
      }
      console.log("\n");
      return err;
    }, []);

  // Conditionally log errors
  if (errors.length === 0)
    console.log("Completed");
  else {
    console.log("\n");
    errors.forEach(error => {
      console.error(`Building ${error.project} (${error.config}) failed:\n\t${error.message}`);
    });
  }
}

buildAll();

您可以使用编译它tsc,然后使用NodeJs.

于 2019-08-29T05:53:46.573 回答
-2

ng-build 已经在 main.js 包中包含了你的库。无需单独构建每个库。

于 2019-06-12T10:26:30.940 回答