Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does Angular2 resolve imports?

So, I am learning Angular2, and I am using TypeScript. So, I do know that SystemJS is used to get the import functionality like this:

import { bootstrap } from "angular2/platform/browser";

This makes sense, but, I don't understand where exactly angular2/platform/browser is. I am pretty sure it is not a path, but some other thing that is used to simulate paths/namespaces. Also, looking at bootstrap here, is it a class? Or is it just a function. And is it possible for other stuff to be imported?

Any exceptional answers will receive a bounty from me.

like image 711
Hassan Althaf Avatar asked Feb 08 '23 19:02

Hassan Althaf


1 Answers

In fact, there are several things to understand here:

  • TypeScript files are transpiled into JavaScript files. When configuring your TypeScript compiler, you will configure how the import will be translate in your tsconfig.json file. This configuration tells to use SystemJS:

    {
      "compilerOptions": {
        "target": "ES5",
        "module": "system",
        "moduleResolution": "node",
        "sourceMap": true,
        "emitDecoratorMetadata": true,
        "experimentalDecorators": true,
        "removeComments": false,
        "noImplicitAny": false
      },
      "exclude": [
        "node_modules"
      ]
    }
    
  • This way the transpiled TypeScript file will look like the following:

    System.register(['angular2/platform/browser', 'angular2/router', 'angular2/http', 'angular2/core', './app.component', './services/companies.service'], function(exports_1) {
      var browser_1, router_1, http_1, core_1, router_2, app_component_1, companies_service_1;
      return {
        (...)
      }
    });
    

    You can see that the imports are part of the parameters of the System.register function. It's the way SystemJS will provide you the elements you need from other modules. Corresponding list is based on the import you use in the TypeScript code... To have the list above, I used this code:

    import {bootstrap} from 'angular2/platform/browser';
    import {ROUTER_PROVIDERS} from 'angular2/router';
    import {HTTP_PROVIDERS} from 'angular2/http';
    import {provide} from 'angular2/core';
    import {LocationStrategy, Location, HashLocationStrategy } from 'angular2/router'; 
    import {AppComponent} from './app.component';
    import {CompanyService} from './services/companies.service';
    
  • The System.register function accepts several parameters. In the previous case, the name of the module isn't defined only the import. It's because we use the following configuration of SystemJS in the HTML file. This tells that the name of the module corresponds to the file itself:

    <script>
      System.config({
        packages: {        
          app: {
            format: 'register',
            defaultExtension: 'js'
          }
        }
      });
      System.import('app/boot')
           .then(null, console.error.bind(console));
    </script>
    
  • Regarding Angular2, the JS files contained in the node_modules/angular2/bundles (for example http.dev.js) contain several modules in files. In this case, there modules are registered into SystemJS using the System.register function but with an additional parameter:

    System.register("angular2/http", ["angular2/core", "angular2/src/http/http", "angular2/src/http/backends/xhr_backend", "angular2/src/http/backends/jsonp_backend", "angular2/src/http/backends/browser_xhr", "angular2/src/http/backends/browser_jsonp", "angular2/src/http/base_request_options", "angular2/src/http/base_response_options", "angular2/src/http/static_request", "angular2/src/http/static_response", "angular2/src/http/interfaces", "angular2/src/http/backends/browser_xhr", "angular2/src/http/base_request_options", "angular2/src/http/base_response_options", "angular2/src/http/backends/xhr_backend", "angular2/src/http/backends/jsonp_backend", "angular2/src/http/http", "angular2/src/http/headers", "angular2/src/http/enums", "angular2/src/http/url_search_params"], true, function(require, exports, module) {
      var global = System.global,
      __define = global.define;
      global.define = undefined;
      (...)
    });
    

To summarize, this is based on a module system like SystemJS that is responsible of module resolution.

SnareChops posted a great answer regarding this in this question:

  • Angular2 & TypeScript importing of node_modules
like image 163
Thierry Templier Avatar answered Feb 11 '23 16:02

Thierry Templier