Angular의 빌드 및 실행 방법


84

Angular가 백그라운드에서 어떻게 빌드되고 실행되는지 배우고 싶습니까?

아래는 내가 지금까지 이해 한 것입니다. 내가 뭔가를 놓쳤는 지 알고 싶어요.

Angular가 만드는 방법

TypeScript를 사용하여 Angular 앱을 코딩 한 후 Angular CLI 명령을 사용하여 앱을 빌드합니다.

ng build명령은 애플리케이션을 출력 디렉토리로 컴파일하고 빌드 아티팩트는 dist/디렉토리에 저장됩니다 .

내부 프로세스

1. Angular CLI는 Webpack을 실행하여 모든 JavaScript 및 CSS 코드를 빌드하고 번들링합니다.

2. 차례로 Webpack .ts은 Angular 프로젝트의 모든 파일을 가져온 다음 .js브라우저가 이해할 수 있는 JavaScript 즉 파일 로 트랜스 파일 하는 TypeScript 로더를 호출합니다 .

게시물은 Angular에 두 개의 컴파일러가 있다고 말합니다.

  • 컴파일러보기

  • 모듈 컴파일러

빌드에 대한 질문

빌드 프로세스를 호출하는 순서는 무엇입니까?

Angular CLI는 먼저 TypeScript =>로 작성된 Angular 내장 컴파일러를 호출 한 다음 TypeScript Transpiler =>를 호출 한 다음 Webpack을 호출하여 dist/디렉토리 에 번들로 저장합니다 .

Angular가 실행되는 방법

빌드가 완료되면 모든 앱의 구성 요소, 서비스, 모듈 등이 JavaScript .js브라우저에서 Angular 애플리케이션을 실행하는 데 사용되는 파일 로 트랜스 파일됩니다.

Angular Docs의

  1. AppComponent클래스 (main.ts)로 부트 스트랩하면 Angular는에서 a <app-root>index.html찾고, 찾아서 AppComponent의 인스턴스를 인스턴스화하고, <app-root>태그 내부에 렌더링합니다 .

  2. Angular는 사용자가 응용 프로그램을 이동할 때 구성 요소를 생성, 업데이트 및 파괴합니다.

달리기에 대한 질문

main.ts부트 스트랩 프로세스를 설명하기 위해 위의 문에서 사용 되었지만 Angular 앱이 부트 스트랩되거나 JavaScript .js파일을 사용하여 시작되지 않습니까?

위의 모든 명령문이 JavaScript .js파일을 사용하여 런타임에 수행되지 않습니까?

모든 부품이 깊이에 어떻게 결합되는지 아는 사람이 있습니까?

답변:


89

(내가 Angular라고 말하면 Angular 2+를 의미하며 angular 1을 언급하면 ​​명시 적으로 angular-js라고 말할 것입니다).

전주곡 : 혼란스러워

Angular, 아마도 더 정확하게는 angular-cli는 빌드 프로세스에 관련된 Javascript의 여러 트렌드 도구를 병합했습니다. 그것은 약간의 혼란으로 이어집니다.

혼란을 더욱 심화시키기 위해이 용어 compile는 angular-js에서 템플릿의 의사 HTML을 가져 와서 DOM 요소로 바꾸는 과정을 지칭하기 위해 자주 사용되었습니다. 그것은 컴파일러가하는 일의 일부이지만 더 작은 부분 중 하나입니다.

우선 Angular를 실행하기 위해 TypeScript, angular-cli 또는 Webpack을 사용할 필요가 없습니다. 귀하의 질문에 답하십시오. "Angular 란 무엇입니까?"라는 간단한 질문을 살펴 보겠습니다.

Angular : 무엇을합니까?

이 섹션은 논란의 여지가있을 수 있습니다. Angular가 제공하는 서비스의 핵심은 Javascript, HTML 및 CSS에서 작동하는 종속성 주입 메커니즘입니다. 모든 작은 조각과 조각을 개별적으로 작성하고 각 작은 조각에서 다른 조각을 참조하는 Angular의 규칙을 따릅니다. 그런 다음 Angular는 어떻게 든 그것을 모두 엮습니다.

(약간) 더 구체적으로 말하면 :

  • 템플릿을 사용하면 HTML을 Javascript 구성 요소에 연결할 수 있습니다. 이를 통해 DOM 자체에 대한 사용자 입력 (예 : 버튼 클릭)이 Javascript 구성 요소에 공급 될 수 있으며 Javascript 구성 요소의 변수가 DOM의 구조와 값을 제어 할 수 있습니다.
  • Javascript 클래스 (Javascript 구성 요소 포함)는 종속 된 다른 Javascript 클래스의 인스턴스에 액세스 할 수 있어야합니다 (예 : 클래식 종속성 주입). BookListComponent에는 BookListPolicy 또는 이와 유사한 인스턴스가 필요할 수있는 BookListService의 인스턴스가 필요합니다. 이러한 각 클래스는 서로 다른 수명 (예 : 서비스는 일반적으로 단일 항목이고 구성 요소는 일반적으로 단일 항목이 아님)을 가지며 Angular는 이러한 모든 수명, 구성 요소 생성 및 종속성 연결을 관리해야합니다.
  • CSS 규칙은 DOM의 하위 집합에만 적용되는 방식으로로드되어야했습니다 (구성 요소의 스타일은 해당 구성 요소에 국한 됨).

주목해야 할 중요한 사항 중 하나는 Angular가 Javascript 파일이 다른 Javascript 파일 (예 : import키워드)을 참조하는 방식에 대해 책임을지지 않는다는 것 입니다. 이는 Webpack에서 처리합니다.

컴파일러는 무엇을합니까?

이제 Angular가 무엇을하는지 알았으니 컴파일러가 무엇을하는지 이야기 할 수 있습니다. 나는 주로 내가 무지하기 때문에 너무 기술적 인 것을 피할 것입니다. 그러나, 의존성 주입 시스템에 당신은 일반적으로 메타 데이터의 어떤 종류 (예를 들어, 어떻게 수행하는 클래스 말과 의존성을 표현해야한다 I can be injected, My lifetime is blah또는 You can think of me as a Component type of instance). Java에서 Spring은 원래 XML 파일로이 작업을 수행했습니다. Java는 나중에 주석을 채택했으며 메타 데이터를 표현하는 데 선호되는 방법이되었습니다. C #은 특성을 사용하여 메타 데이터를 표현합니다.

자바 스크립트에는이 메타 데이터를 노출하는 훌륭한 메커니즘이 없습니다. angular-js가 시도했고 나쁘지는 않았지만 쉽게 확인할 수없는 규칙이 많고 약간 혼란 스러웠습니다. Angular에는 메타 데이터를 지정하는 데 지원되는 두 가지 방법이 있습니다. 순수 자바 스크립트를 작성하고 angular-js와 다소 유사하게 수동으로 메타 데이터를 지정할 수 있으며 규칙을 계속 따르고 추가 상용구 코드를 작성할 수 있습니다. 또는 @메타 데이터를 표현하는 데 사용되는 데코레이터 ( 심볼)가있는 TypeScript로 전환 할 수 있습니다 .

그래서 여기에서 마침내 컴파일러에 도달 할 수 있습니다. 컴파일러의 임무는 해당 메타 데이터를 가져와 애플리케이션에 맞는 작업 시스템을 만드는 것입니다. 모든 부분과 모든 메타 데이터에 집중하면 컴파일러가 하나의 큰 상호 연결된 애플리케이션을 빌드합니다.

컴파일러는 어떻게합니까?

컴파일러가 작동 할 수있는 방법에는 런타임과 미리 두 가지가 있습니다. 여기서부터는 TypeScript를 사용하고 있다고 가정합니다.

  • 런타임 : 타입 스크립트 컴파일러가 실행될 때 모든 데코레이터 정보를 가져와 데코 레이팅 된 클래스, 메소드 및 필드에 첨부 된 자바 스크립트 코드로 밀어 넣습니다. 당신은 index.html당신의 참조 방법 main.js을 호출합니다 bootstrap. 이 메서드는 최상위 모듈에 전달됩니다.

부트 스트랩 메서드는 런타임 컴파일러를 실행하고 최상위 모듈에 대한 참조를 제공합니다. 그런 다음 런타임 컴파일러는 해당 모듈, 해당 모듈에서 참조하는 모든 서비스, 구성 요소 및 모든 관련 메타 데이터를 크롤링하기 시작하고 애플리케이션을 빌드합니다.

  • AOT : 런타임에 모든 작업을 수행하는 대신 Angular는 빌드 시간에 대부분의 작업을 수행하는 메커니즘을 제공했습니다. 이 작업은 거의 항상 웹팩 플러그인을 사용하여 수행됩니다 (가장 널리 사용되지만 가장 알려지지 않은 npm 패키지 중 하나 여야 함). typescript 컴파일이 실행 된 후에 실행되므로 기본적으로 런타임 컴파일러와 동일한 입력이 표시됩니다. AOT 컴파일러는 런타임 컴파일러와 마찬가지로 애플리케이션을 빌드하지만 Javascript에 다시 저장합니다.

여기서의 장점은 컴파일 자체에 필요한 CPU 시간을 절약 할 수있을뿐만 아니라 응용 프로그램의 크기도 줄일 수 있다는 것입니다.

특정 답변

Angular CLI 먼저 Typescript =>로 작성된 컴파일러에 내장 된 angular를 호출 한 다음 Typescript Transpiler =>를 호출 한 다음 Webpack을 호출하여 dist / 디렉토리에 번들로 저장합니다.

아니요. Angular CLI는 Webpack을 호출합니다 (Angular CLI의 실제 서비스는 웹팩을 구성하는 것입니다. 실행할 때 ng buildWebpack을 시작하는 프록시에 지나지 않습니다). Webpack은 먼저 Typescript 컴파일러를 호출 한 다음 각 컴파일러 (AOT 가정)를 호출하고 동시에 코드를 번들링합니다.

main.ts는 부트 스트랩 프로세스를 설명하기 위해 위의 문에서 사용되지만 각도 앱이 부트 스트랩되거나 Javascript .js 파일을 사용하여 시작되지 않습니까?

나는 당신이 여기서 무엇을 요구하고 있는지 완전히 확신하지 못합니다. main.tsJavascript로 변환됩니다. 해당 자바 스크립트에는 bootstrapAngular의 진입 점 인 호출이 포함됩니다 . bootstrap완료 되면 전체 Angular 응용 프로그램이 실행됩니다.

이 게시물은 Angular에 두 개의 컴파일러가 있다고 말합니다.

컴파일러보기

모듈 컴파일러

솔직히 말해서 여기서 무지를 주장 할 것입니다. 우리 수준에서 우리는 모든 것을 하나의 큰 컴파일러로 생각할 수 있다고 생각합니다.

누구든지 모든 부품이 깊이에 어떻게 맞춰 지는지 알고 있습니까?

위의 내용이 만족했으면합니다.

Do n't @ Me : Angular는 의존성 주입 이상의 역할을합니다.

확실한. 라우팅, 뷰 빌딩, 변경 감지 및 기타 모든 작업을 수행합니다. 컴파일러는 실제로 뷰 빌드 및 변경 감지를 위해 Javascript를 생성합니다. 그냥 의존성 주입이라고 말했을 때 거짓말을했습니다. 그러나 의존성 주입은 핵심이며 나머지 답변을 이끌어 내기에 충분합니다.

컴파일러라고 불러야할까요?

아마도 많은 파싱과 렉싱을 수행하고 결과적으로 많은 코드를 생성하므로 이러한 이유로 컴파일러라고 부를 수 있습니다.

반면에 코드를 단순히 다른 표현으로 변환하는 것은 아닙니다. 대신 여러 가지 코드를 가져 와서 더 큰 시스템의 소모품으로 짜는 것입니다. 그런 다음 부트 스트랩 프로세스 (필요한 경우 컴파일 후)는 해당 조각을 가져 와서 Angular 코어에 연결합니다.


자세한 답변 감사합니다. 당신의 대답을 받아들이 기 전에 나는 당신의 성명서 The compiler does actually generate 자바 스크립트에서보기 구축과 변화 감지에 의문을 품었다 . '그것은 거짓말이 아니다. 그것이 컴파일러가하는 일이 아닙니다. 그리고 각도는 의존성 주입을합니다.
shaijut

1
네 죄송합니다. 내가 언급 한 거짓말은 "Angular가 제공하는 서비스의 핵심은 종속성 주입 메커니즘입니다."였습니다. 왜냐하면 Angular가 수행하는 것이 전부가 아니고 컴파일러가 수행하는 모든 작업도 아니기 때문입니다.
Pace

Angular가 구성 요소, 지시문, 서비스 등과 같은 기능을 가진 새로운 "언어"로 생략 된 경우. 컴파일러라고 할 수 있습니다. Angular 언어를 원시 js 및 html로 작성하십시오.
Chris Bao

10

처음부터 시작하겠습니다.

내 응용 프로그램에서 Webpack.

애플리케이션을 빌드하고 실행하기 위해 webpack --progresswebpack-dev-server --inline 명령을 사용합니다. 다음과 package.json같이 작성되었습니다.

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

  }

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'
        })
    ]
}   

그런 다음 모든 Typescript파일을 읽고 파일에 선언 된 규칙에 따라 컴파일 tsconfig.json하고 각 .js파일과 맵 파일 로 변환 합니다.

컴파일 오류없이 실행 bundle.js되면 Webpack출력 섹션 에서 선언 한 이름으로 파일을 생성 합니다 .

이제 로더를 사용하는 이유를 설명하겠습니다.

멋진-타이프 라이터 로더, angular2 템플릿 로더는 우리는 컴파일이 로더를 사용 Typescript에 선언 된베이스 파일 tsconfig.json파일 angular2 템플릿 로더를 검색 templateUrl하고 styleUrls각이 구성 요소의 메타 데이터 선언의 내부와 해당로 경로를 대체 요구 사항.

resolve: {
        extensions: ['.ts', '.js']
    }

위의 해결 섹션을 사용 하여 파일 Webpack로 변환 Typescript하도록 알려줍니다JavaScript

plugins: [
        new HtmlWebpackPlugin({
            template: './src/index.html'
        })
    ]

플러그인 섹션은 타사 프레임 워크 또는 파일을 삽입하는 데 사용됩니다. 내 코드에서 나는 이것을 사용하여 index.html대상 폴더 를 주입 하고 있습니다.

 devtool: 'source-map',

위의 줄은 Typescript브라우저 에서 파일 을보고 주로 개발자 코드에 사용되는 디버그에 사용됩니다.

 loader: 'raw-loader'

위의 내용 raw-loader.html.css파일 을로드 하고 파일과 함께 묶는 데 사용됩니다 Typescript.

마지막에 webpack-dev-server --inline 을 실행하면 자체 서버가 생성되고 web-pack.config.js대상 폴더와 진입 점을 언급 한 파일에 언급 된 경로로 애플리케이션이 부팅 됩니다.

에서 Angular대부분의 응용 프로그램이 진입 점입니다 main.ts우리가 예 (app.module)의 초기 부트 스트랩 모듈을 언급 곳이 모듈은 모든 지시, 서비스, 모듈, 구성 요소와 전체 응용 프로그램의 라우팅 구현으로 완벽한 애플리케이션 정보가 포함되어 있습니다.

참고 : 많은 사람들은 index.html어디에도 언급하지 않았지만 응용 프로그램을 부팅 만하는 이유를 의심합니다 . 대답은 Webpackserve 명령이 실행될 때 자체 서브를 생성 index.html하고 기본 페이지를 언급하지 않은 경우 기본적으로로드 하는 것입니다.

주어진 정보가 어떤 사람들에게 도움이되기를 바랍니다.


1
설명 해주신 것에 감사드립니다. 좀 더 명확하게 순차적으로 설명 해주시면 좋겠습니다. 그래서 당신은 앱 Angular CLI을 만드는 데 사용하지 않고 어떻게 직접 Angular사용 Webpack합니까?
shaijut

5

Angular는 어떻게 구축합니까?

Angular CLI전화 Webpack, 때 Webpack명중 .ts이로를 통과하는 파일을 TypeScript컴파일 A 출력 변압기가 컴파일러 Angular템플릿

따라서 빌드 순서는 다음과 같습니다.

Angular CLI=> Webpack=> TypeScript컴파일러 => 컴파일러는 컴파일 시간에 TypeScript컴파일러를 호출합니다 Angular.

Angular는 어떻게 실행됩니까?

AngularJavascript파일을 사용하여 부트 스트랩 및 실행 됩니다.

실제로 부트 스트랩 프로세스는 런타임이며 브라우저를 열기 전에 발생합니다. 다음 질문으로 넘어갑니다.

그래서 부트 스트랩 프로세스가 Javascript파일에서 발생 한다면 왜 Angular문서는 main.ts부트 스트랩 프로세스를 설명하기 위해 TypeScript 파일을 사용 합니까?

Angular문서 .ts는 소스이기 때문에 파일 에 대해 이야기 합니다.

이것은 간단한 대답입니다. 누구든지 깊이 대답 할 수 있는지 감사하십시오.

크레딧은 채팅에서 내 질문에 답한 @ Toxicable 로 이동합니다 .


2

이 답변에 늦을 수도 있지만 최근에 초보자 관점에서 시작하여 깊이있는이 주제에 대해 정말 좋은 이야기가있었습니다. 이 스레드의 잘못된 정보를 내 말로 요약하거나 지적하는 대신 Kara Erickson : How Angular works 의 비디오를 연결하겠습니다 .

그녀는 Angular 프레임 워크의 기술 책임자이며 다음과 같은 프레젠테이션을 정말 잘합니다.

  • Angular 프레임 워크의 주요 부분은 무엇입니까
  • 컴파일러는 어떻게 작동하며 무엇을 생성합니까?
  • "구성 요소 정의"란 무엇입니까?
  • 애플리케이션 부트 스트랩이란 무엇이며 어떻게 작동합니까?

1
기여해 주셔서 감사합니다 :), 감사합니다.
shaijut

1

그래서 부트 스트랩 프로세스가 Javascript 파일에서 발생한다면 Angular Docs는 왜 부트 스트랩 프로세스를 설명하기 위해 main.ts TypeScript 파일을 사용합니까?

이것은 ng build아직 생성되지 않은 main.ts 의 변형 된 .js 버전의 일부입니다 . 초보자가이 코드를 어떻게 이해하기를 기대합니까? 훨씬 복잡해 보이지 않습니까?

Object(__WEBPACK_IMPORTED_MODULE_1__angular_platform_browser_dynamic__["a" /* platformBrowserDynamic */])().bootstrapModule(__WEBPACK_IMPORTED_MODULE_2__app_app_module__["a" /* AppModule */])
    .catch(function (err) { return console.log(err); });

와 함께 ng build --prod --build-optimizer순서 uglifies 및 축소하고 코드가 최적화되는, 생성 된 번들은 컴팩트하고 비트 읽을 수없는 형식입니다.

webpackJsonp([1],{0:function(t,e,n){t.exports=n("cDNt")},"1j/l":function(t,e,n){"use strict";n.d(e,"a",function(){return r});var r=Array.isArray||function(t){return t&&"number"==typeof t.length}},"2kLc

main.ts 파일은 사람이 읽을 수 있고 명료 한 반면, angular.io는 main.ts를 사용하여 각도 응용 프로그램의 부트 스트랩 프로세스를 설명합니다. Angular : 왜 TypeScript인가? 이 외에도 훌륭한 프레임 워크의 작성자 였다면 프레임 워크를 대중적이고 사용자 친화적으로 만들기 위해 어떤 접근 방식을 사용했을까요? 복잡한 설명보다는 명확하고 간결한 설명을 하시겠어요? angular.io 문서에 자세한 설명이 부족하고 그다지 좋지는 않지만 지금까지 그들이 더 좋게 만들기 위해 열심히 노력하고 있음에 동의합니다.


1

Angular 9+는 AOT (Ahead of Time Compilation)를 사용합니다. 즉, 컴포넌트 (.ts + .html + .css), 모듈 (.ts)과 같은 다양한 파일에 흩어져있는 모든 비트를 취하고 런타임시 다운로드되는 브라우저가 이해할 수있는 JavaScript를 구성합니다. 브라우저에 의해 실행됩니다.

Angular 9 이전에는 브라우저에서 요구하는대로 코드가 컴파일 된 JIT (Just in time Compilation)였습니다.

자세한 내용은 Angular AOT Documentaiton을 참조하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.