前提

随便找个空文件夹,运行 npm i @angular/cli@19.0.7

使用 npx --package=<pkg>[@<version>] -- <cmd> [args...] 运行 ng new myworkspace

C:\Users\zhouhuajian\Desktop\demo>npx --package=@angular/cli -- ng new myworkspace
√ Which stylesheet format would you like to use? CSS            
√ Do you want to enable Server-Side Rendering (SSR) and Static Site Generation (SSG/Prerendering)? No
CREATE myworkspace/angular.json (2706 bytes)
CREATE myworkspace/package.json (1080 bytes)
CREATE myworkspace/README.md (1533 bytes)
CREATE myworkspace/tsconfig.json (942 bytes)
CREATE myworkspace/.editorconfig (331 bytes)
CREATE myworkspace/.gitignore (629 bytes)
CREATE myworkspace/tsconfig.app.json (439 bytes)
CREATE myworkspace/tsconfig.spec.json (449 bytes)
CREATE myworkspace/.vscode/extensions.json (134 bytes)
CREATE myworkspace/.vscode/launch.json (490 bytes)
CREATE myworkspace/.vscode/tasks.json (980 bytes)
CREATE myworkspace/src/main.ts (256 bytes)
CREATE myworkspace/src/index.html (310 bytes)
CREATE myworkspace/src/styles.css (81 bytes)
CREATE myworkspace/src/app/app.component.html (20239 bytes)
CREATE myworkspace/src/app/app.component.spec.ts (960 bytes)
CREATE myworkspace/src/app/app.component.ts (299 bytes)
CREATE myworkspace/src/app/app.component.css (0 bytes)
CREATE myworkspace/src/app/app.config.ts (318 bytes)
CREATE myworkspace/src/app/app.routes.ts (80 bytes)
CREATE myworkspace/public/favicon.ico (15086 bytes)
√ Packages installed successfully.
    Successfully initialized git.

这输出,大家熟悉吗?

问题来了,工作区或者项目的代码,从哪里来?🤔🤔🤔

可能要提前了解的东东

要想读懂 ng new 源码,可能要先了解了解这两个东西

1. Angular Schematics

https://www.npmjs.com/package/@angular-devkit/schematics

这家伙非常晦涩难懂,大家简单理解为,它可以帮你根据一定规则,创建项目文件、修改项目文件、删除项目文件。

嗯,大家到网上搜搜吧,虽然相关资料很少

2. RxJS

https://www.npmjs.com/package/rxjs

这个应该相对好理解些,据说它可以让异步编程更容易。

真的更容易吗?I'm not sure.

直接讲重点

源码比绕口令还要绕,直接上重点 😂😂😂

运行 ng new 会运行 NewCommandModulerun 方法

node_modules\@angular\cli\src\commands\new\cli.js

// 省略了代码
class NewCommandModule extends schematics_command_module_1.SchematicsCommandModule {
  // 这个很重要,表示后续要用 ng-new 这个 schematic 
  schematicName = 'ng-new';
  command = 'new [name]';
  describe = 'Creates a new Angular workspace.';
  // run run run 跑起来
  async run(options) {
    // 运行 ng-new 这个 schematic
    return this.runSchematic({
      collectionName,
      schematicName: this.schematicName,
      schematicOptions,
      executionOptions: {
        dryRun,
        force,
        interactive,
        defaults,
      },
    });
  }
}

ng-new 这个 schematic 在这里 node_modules\@schematics\angular\ng-new

运行 ng-new 这个 schematic 时,又运行了 application schematic

node_modules\@schematics\angular\application

img.png

没错,你项目里的很多文件就来自这个 application schematic

img2.png

看看这些文件,是不是很熟悉?🙂‍↕️🙂‍↕️🙂‍↕️

最后再说说 Git

Successfully initialized git.

创建好项目,Angular 还会帮大家创建一个 Git 仓库

node_modules\@angular-devkit\schematics\tasks\repo-init\executor.js

// 省略了代码
const child_process_1 = require("child_process");
function default_1(factoryOptions = {}) {
  return async (options = {}, context) => {
    const execute = (args, ignoreErrorStream) => {
      // 在这里执行 git 命令
      return new Promise((resolve, reject) => {
        (0, child_process_1.spawn)('git', args, spawnOptions).on('close', (code) => {
          if (code === 0) {
            resolve();
          }
          else {
            reject(code);
          }
        });
      });
    };
    // 用 git --version 判断是否有 全局的 git 命令,没有就直接返回,不初始化 Git 仓库
    const hasCommand = await execute(['--version']).then(() => true, () => false);
    if (!hasCommand) {
      return;
    }
    // 用 git rev-parse --is-inside-work-tree 判断是否已经有 Git 仓库了
    const insideRepo = await execute(['rev-parse', '--is-inside-work-tree'], true).then(() => true, () => false);
    if (insideRepo) {
      context.logger.info(core_1.tags.oneLine`
        Directory is already under version control.
        Skipping initialization of git.
      `);
      return;
    }
    try {
      // 执行 git init
      await execute(['init']);
      // 执行 git add .
      await execute(['add', '.']);
      if (options.commit) {
        const message = options.message || 'initial commit';
        // 执行 git commit -m "initial commit"
        await execute(['commit', `-m "${message}"`]);
      }
      context.logger.info('Successfully initialized git.');
    }
    catch { }
  };
}

好了,现在 AI 技术可牛了,剩下的内容,交给 AI 去写吧。

ChatGPT 小兄弟,能帮忙写写么?🥺🥺🥺


Huajianketang wrote it without AI.


华健课堂
1 声望0 粉丝