Angular如何构建和运行

sto*_*tom 66 build typescript angular-cli angular

只是想了解如何Angular在幕后构建和运行?

以下是我迄今所理解的内容.想知道我是否错过了什么.

Angular的构建方式

在使用我们的角度应用程序编码后TypeScript,我们使用Angular CLICommand来构建应用程序.

ng buildcommand将应用程序编译到输出目录中,构建工件将存储在dist/目录中.

内部流程

1. Angular CLI运行Webpack以构建和捆绑所有JavaScript和CSS代码.

2. 依次Webpack调用TypeScriptLoaders,它们获取.ts角项目中的所有文件,然后将它们转换JavaScript.js文件,浏览器可以理解.

这篇文章说Angular有两个编译器:

  • 查看编译器

  • 模块编译器

有关构建的问题

调用构建过程的顺序是什么?

Angular CLI First调用在Typescript =>中编写的angular内置编译器,然后调用Typescript Transpiler =>然后调用Webpack进行捆绑并存储在dist/目录中.

Angular如何运行

构建完成后,我们所有应用程序的组件,服务,模块等都会转换为Javascript .js文件,用于在浏览器中运行角度应用程序.

Angular Docs中的陈述

  1. 当您使用AppComponent类引导(在main.ts中)时,Angular <app-root>在其中index.html查找a ,找到它,实例化AppComponent的实例,并将其呈现在<app-root>标记内.

  2. 当用户在应用程序中移动时,Angular会创建,更新和销毁组件.

关于运行的问题

尽管main.ts在上面的Statement中用于解释引导过程,但是不是角度应用程序是自引导还是使用Javascript .js文件启动?

是不是所有上述语句都是使用Javascript .js文件运行时完成的?

有谁知道所有部分如何深入融合?

Pac*_*ace 68

(当我说Angular我的意思是Angular 2+并且如果我提到角度1那将明确地说出angular-js).

前奏:令人困惑

Angular,可能更准确的angular-cli已经将Javascript中的一些趋势工具合并在一起,这些工具涉及构建过程.它确实会引起一些混乱.

为了进一步混淆,这个术语compile经常在angular-js中用来指代获取模板的伪html并将其转换为DOM元素的过程.这是编译器所做的一部分,但是其中一个较小的部分.

首先,不需要使用TypeScript,angular-cli或Webpack来运行Angular.回答你的问题.我们应该看一个简单的问题:"什么是Angular?"

Angular:它做了什么?

这部分可能会引起争议,我们会看到. Angular提供的服务的核心是一种依赖注入机制,可以在Javascript,HTML和CSS中运行. 你可以单独编写所有的小部件,并在每个小部件中按照Angular的规则来引用其他部分.Angular然后以某种方式完全编织.

(稍微)更具体:

  • 模板允许HTML连接到Javascript组件.这允许用户在DOM本身上输入(例如,单击按钮)以输入Javascript组件,并且还允许Javascript组件中的变量控制DOM中的结构和值.
  • Javascript类(包括Javascript组件)需要能够访问它们依赖的其他Javascript类的实例(例如经典依赖注入).BookListComponent需要BookListService的实例,该实例可能需要BookListPolicy的实例或类似的东西.这些类中的每一个都有不同的生命周期(例如,服务通常是单例,组件通常不是单例),而Angular必须管理所有这些生命周期,组件的创建以及依赖关系的连接.
  • 需要以这样的方式加载CSS规则:它们仅应用于DOM的子集(组件的样式是该组件的本地样式).

一个可能需要注意的重要事项是Angular不负责Javascript文件如何引用其他Javascript文件(例如import关键字).这由Webpack负责.

编译器做什么?

现在您已经了解Angular的内容,我们可以讨论编译器的功能.我会避免过于技术化,主要是因为我无知.然而,在依赖注入系统,您通常具有某种元数据来表达你的依赖关系(例如,如何一类说I can be injected,My lifetime is blahYou can think of me as a Component type of instance).在Java中,Spring最初使用XML文件执行此操作.Java后来采用了注释,它们已成为表达元数据的首选方式.C#使用属性来表达元数据.

Javascript没有很好的机制来公开内置的元数据.angular-js做了一次尝试并且它并不坏但是有很多规则不容易检查并且有点令人困惑.使用Angular,有两种支持的方法来指定元数据.您可以编写纯Javascript并手动指定元数据,有点类似于angular-js,只需遵守规则并编写额外的泛型代码.或者,您可以切换到TypeScript,就像它恰好一样,@它具有用于表示元数据的装饰器(那些符号).

所以这是我们最终可以进入编译器的地方.编译器的工作是获取元数据并创建作为应用程序的工作系统.您专注于所有部分和所有元数据,并且编译器构建一个大的互连应用程序.

编译器是如何做到的?

编译器可以通过两种方式工作,运行时和提前.从这里开始,我将假设您正在使用TypeScript:

  • 运行时: 当typescript编译器运行时,它会获取所有装饰器信息并将其推送到附加到装饰类,方法和字段的Javascript代码中.在index.html你的引用你main.jsbootstrap方法调用方法.该方法通过了您的顶级模块.

bootstrap方法触发运行时编译器并为其提供对该顶级模块的引用.然后,运行时编译器开始对该模块,该模块引用的所有服务,组件等以及所有关联的元数据进行爬网,并构建应用程序.

  • AOT: Angular不是在运行时完成所有工作,而是提供了一种在构建时完成大部分工作的机制.这几乎总是使用webpack插件完成(这必须是最流行但最不为人知的npm包之一).它在打字脚本编译运行后运行,因此它看到与运行时编译器基本相同的输入.AOT编译器就像运行时编译器一样构建应用程序,然后将其保存回Javascript中.

这里的优点不仅在于您可以节省编译本身所需的CPU时间,还可以减少应用程序的大小.

具体答案

Angular CLI First调用在Typescript =>中编写的angular内置编译器,然后调用Typescript Transpiler =>然后调用Webpack捆绑并存储在dist /目录中.

没有.Angular CLI调用Webpack(Angular CLI的实际服务是配置webpack.当你运行ng build它时,它只不过是启动Webpack的代理).Webpack首先调用Typescript编译器,然后调用角度编译器(假设是AOT),同时将代码捆绑在一起.

尽管main.ts在上面的Statement中用于解释引导过程,但是不是使用Javascript .js文件引导或启动角度应用程序吗?

我不完全确定你在这里问的是什么. main.ts将被转移到Javascript中.该Javascript将包含一个调用,bootstrap该调用是Angular的入口点.当bootstrap完成后,你将有你的全角应用程序运行.

这篇文章说Angular有两个编译器:

查看编译器

模块编译器

说实话,我只会在这里声称无知.我认为在我们的水平上我们可以把它想象成一个大的编译器.

有谁知道所有部分如何深入融合?

我希望上面对此感到满意.

不要@ Me:Angular不仅仅是依赖注入

当然.它可以进行路由,查看构建,更改检测以及各种其他内容.编译器确实为视图构建和更改检测生成Javascript.当我说它只是依赖注入时我撒了谎.但是,依赖注入是核心,足以驱动其余的答案.

我们应该称它为编译器吗?

它可能会进行大量的解析和lexing,并且肯定会生成大量代码,因此您可以将其称为编译器.

另一方面,它并没有真正将您的代码转换为仅仅是不同的表示.相反,它采用了大量不同的代码并将它们编织成更大系统的可消耗部分.然后(在编译之后,如果需要的话)引导过程获取这些片段并将它们插入Angular核心.


小智 8

让我从头开始.

在我的应用程序中我直接运行应用程序Webpack.

要构建和运行应用程序,我们使用webpack --progresswebpack-dev-server --inline命令编写package.json如下

"scripts": {
    "serve": "webpack-dev-server --inline ",
    "build": "webpack --progress"

  }
Run Code Online (Sandbox Code Playgroud)

当我们运行webpack --progress命令时,它开始读取webpack.config.js文件,在那里找到入口点,如下所示.

module.exports = {
    devtool: 'source-map',
    entry: './src/main.ts',
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'bundle.js'
    },
    module: {
        loaders: [
            {
                test: /\.ts$/,
                loaders: ['awesome-typescript-loader', 'angular2-template-loader'],
                exclude: [/\.(spec|e2e)\.ts$/]
            },
            /* Embed files. */
            {
                test: /\.(html|css)$/,
                loader: 'raw-loader',
                exclude: /\.async\.(html|css)$/
            },
            /* Async loading. */
            {
                test: /\.async\.(html|css)$/,
                loaders: ['file?name=[name].[hash].[ext]', 'extract']
            },
        ]
    },
    resolve: {
        extensions: ['.ts', '.js']
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: './src/index.html'
        })
    ]
}   
Run Code Online (Sandbox Code Playgroud)

然后它读取所有Typescript文件并根据tsconfig.json文件中声明的规则进行编译,然后将其转换为相应的.js文件和它的映射文件.

如果它在没有任何编译错误的情况下运行,它将创建bundle.js具有我们在Webpack输出部分中声明的名称的文件.

现在让我解释一下为什么我们使用加载器.

awesome-typescript-loader,angular2-template-loader 我们使用这些加载器在Typescript文件中声明的基础上编译tsconfig.json文件,angular2-template-loader 在Angular 2 Component元数据中搜索templateUrlstyleUrls声明,并用相应的路径替换路径要求声明.

resolve: {
        extensions: ['.ts', '.js']
    }
Run Code Online (Sandbox Code Playgroud)

我们使用上面的解析部分告诉Webpack转换TypescriptJavaScript文件

plugins: [
        new HtmlWebpackPlugin({
            template: './src/index.html'
        })
    ]
Run Code Online (Sandbox Code Playgroud)

插件部分用于注入第三方框架或文件.在我的代码中,我使用它来注入index.html目标文件夹.

 devtool: 'source-map',
Run Code Online (Sandbox Code Playgroud)

上面的行用于Typescript在浏览器中查看文件并调试它主要用于开发人员代码.

 loader: 'raw-loader'
Run Code Online (Sandbox Code Playgroud)

上面raw-loader用于加载.html.css文件,并将它们与Typescript文件捆绑在一起.

最后,当我们运行webpack-dev-server --inline时,它将创建自己的服务器并启动应用程序作为web-pack.config.js我们提到目标文件夹和入口点的文件中提到的路径.

Angular大多数应用程序的2个入口点main.ts我们提到了初始引导模块,例如(app.module),该模块包含完整的应用程序信息,如所有指令,服务,模块,组件和整个应用程序的路由实现.

注意: 许多人怀疑为什么index.html只启动应用程序,即使他们没有提到任何地方.答案是当Webpackserve命令运行时它创建自己的服务器,默认情况下,index.html如果你没有提到任何默认页面,它会加载.

我希望给定的信息可以帮助一些人.

  • 感谢您尝试解释,如果您能以更清晰的顺序方式解释会更好。那么您不使用“Angular CLI”来构建“Angular”应用程序并直接使用“Webpack”怎么办? (2认同)

sto*_*tom 5

Angular 是如何构建的?

Angular CLI呼叫Webpack,当Webpack击中.ts它通过其关闭,以文件的TypeScript编译器,其具有编译一个输出变压器Angular模板

所以构建顺序是:

Angular CLI=> Webpack=> TypeScriptCompiler => TypeScriptCompilerAngular在编译时调用编译器。

Angular 如何运行?

Angular引导程序并使用Javascript文件运行。

实际上引导过程是运行时并且在打开浏览器之前发生。这将我们带到下一个问题。

因此,如果引导过程发生在Javascript文件中,那么为什么AngularDocs 使用main.tsTypeScript 文件来解释引导过程?

Angular文档只是谈论.ts文件,因为那是来源。

这是简短的回答。不胜感激,如果有人能深入回答。

感谢@ Toxicable在聊天中回答我的问题。