简体   繁体   中英

How is the Angular framework loaded into an application with Angular CLI?

I'm converting an existing AngularJS application to a hybrid application, to begin incrementally upgrading it to Angular 4. I want to understand how Angular 4 needs to be referenced in the existing AngularJS. In the existing AngularJS application, it's clear how the AngularJS framework is being loaded - it's simply an included script file:

<script src="/angular/angular.js"></script>

To familiarise myself with an up to date Angular version, I've created a separate 'quickstart' Angular 5 application using the Angular quickstart guide at https://angular.io/guide/quickstart , and I can run it using:

ng serve --open

When I look at the project files though, I'm not seeing where the angular framework is actually being loaded. There is no script being included anywhere in the src/index.html file for that application, it simply declares an directive for a component (app.component.ts) that looks like this:

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'Test Angular 5 app';
}

Where does the import actually import from? The Angular documentation says about the index.html file that it is:

The main HTML page that is served when someone visits your site. Most of the time you'll never need to edit it. The CLI automatically adds all js and css files when building your app so you never need to add any or tags here manually.

So what is happening here? How is @angular/core actually being referenced?

When using Angular CLI, we have a lot of moving parts. To really understand what's happening, we should review some of the core technologies used in Angular CLI as they relate to output files and module resolution:

  • TypeScript -- will transpile your TypeScript code to ES5 or ES6 (most commonly ES5). The transpiled code will use CommonJS modules by default if the target is ES5. If the target is ES6, then ES6 modules will be used.
  • Webpack -- will take your transpiled TypeScript code and build a dependency graph of your import / exports based on the entry points defined in webpack.config.js . This dependency graph will include all of your modules and it will package these modules into 1+ bundles , depending on the configuration. This is the step where the @angular/core dependency (which lives in node_modules/@angular/core ) is processed by Webpack and added to a bundle that can be accessed at runtime.

You can load the generated bundles into the page by including the generated files in your HTML. In the case of JS files, you load them using the script tag like you did with AngularJS.

Because we are using Angular CLI, there are a lot of configurations within Webpack that are set up by default, so we will have multiple generated bundles.

I just created an empty Angular CLI project and inspected the HTML to see the 5 generated bundles:

在此输入图像描述

At the core of the complexity when comparing Angular project files with AngularJS files is that Angular code is transformed through multiple build steps, while AngularJS code is normally used out-of-the-box with ES5. If you were to add Webpack and TypeScript to your AngularJS build, you would see something very similar to the Angular output.


Where is Webpack Configured in Angular CLI?

Under the hood, Angular CLI uses Webpack to build your project and bundle your files.

The Angular team chose not to expose a configurable Webpack configuration file for Angular CLI, but they did add ng eject , which generates a webpack.config.js that matches the Webpack build of your project. The downside of ejecting is that you will no longer use ng serve to serve your project. Instead, you'll use npm run build && npm run start (you'll see these scripts added to your package.json after you eject), which will build and serve your project based on the generated webpack.config.js file.

This feature is essential if you need to make custom modifications to the default Webpack build.

Read more about ng eject here .

Where are the generated bundles?

If you are using ng serve , you won't see any of your generated files because these are being served from memory and not from disk (to speed up development when files are constantly changing), so your generated files are not located in any folder.

If you want to see your generated files, you can run ng build , which will create a dist folder with the index.html and associated assets/bundles.

Note that by default, all commands that build or serve your project will delete your dist folder unless you pass the --no-delete-output-path when building/serving.

You need to understand how imports and exports work in TypeScript

From TypeScript Docs

Exporting a declaration

Any declaration (such as a variable, function, class, type alias, or interface) can be exported by adding the export keyword.

Validation.ts

export interface StringValidator {
    isAcceptable(s: string): boolean;
}

ZipCodeValidator.ts

export const numberRegexp = /^[0-9]+$/;
export class ZipCodeValidator implements StringValidator {
    isAcceptable(s: string) {
        return s.length === 5 && numberRegexp.test(s);
    }
}

Export statements

Export statements are handy when exports need to be renamed for consumers, so the above example can be written as:

ZipCodeValidator.ts

class ZipCodeValidator implements StringValidator {
    isAcceptable(s: string) {
        return s.length === 5 && numberRegexp.test(s);
    }
}
export { ZipCodeValidator };
export { ZipCodeValidator as mainValidator };

Import

Importing is just about as easy as exporting from a module. Importing an exported declaration is done through using one of the import forms below:

Import a single export from a module

import { ZipCodeValidator } from "./ZipCodeValidator";

let myValidator = new ZipCodeValidator();

imports can also be renamed

import { ZipCodeValidator as ZCV } from "./ZipCodeValidator";
let myValidator = new ZCV();

Import the entire module into a single variable, and use it to access the module exports

import * as validator from "./ZipCodeValidator";
let myValidator = new validator.ZipCodeValidator();

Since you followed the Angular quickstart guide you must have used npm which is used to install your modules and dependencies.

If you read angular.io/npm

@angular/core: Critical runtime parts of the framework needed by every application. Includes all metadata decorators, Component, Directive, dependency injection, and the component lifecycle hooks.

And by default npm stores all your dependencies in node_modules directory.

So you are importing Component from @angular/core which lives inside node_modules directory.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM