【问题标题】:What does systemjs.config.js do in angular 2 packaging structure?systemjs.config.js 在 Angular 2 封装结构中做了什么?
【发布时间】:2016-05-25 14:15:56
【问题描述】:

还有什么 var map,packages, var config 在这里我有点困惑 他们做任何配置吗?我看到了每个项目,我发现他们把这个文件放在任何地方。这个功能是做什么的?

 (function(global) {

      // map tells the System loader where to look for things
      var map = {
        'app':                        'app', // 'dist',
        'rxjs':                       'node_modules/rxjs',
        'angular2-in-memory-web-api': 'node_modules/angular2-in-memory-web-api',
        '@angular':                   'node_modules/@angular',
    'primeng':                        'node_modules/primeng'
      };

      // packages tells the System loader how to load when no filename and/or no extension
      var packages = {
        'app':                        { main: 'boot.js',  defaultExtension: 'js' },
        'rxjs':                       { defaultExtension: 'js' },
        'angular2-in-memory-web-api': { defaultExtension: 'js' },
        'primeng':                    { defaultExtension: 'js' }
      };

      var packageNames = [
        '@angular/common',
        '@angular/compiler',
       //
      ];

      // add package entries for angular packages in the form '@angular/common': { main: 'index.js', defaultExtension: 'js' }
      packageNames.forEach(function(pkgName) {
        packages[pkgName] = { main: 'index.js', defaultExtension: 'js' };
      });

      var config = {
        map: map,
        packages: packages
      }

      // filterSystemConfig - index.html's chance to modify config before we register it.
      if (global.filterSystemConfig) { global.filterSystemConfig(config); }

      System.config(config);

    })(this);

【问题讨论】:

    标签: angular


    【解决方案1】:

    systemjs.config.js 定义了 SystemJS 中 Path Normalization 的配置。你可以像这样使用 SystemJS 加载一些东西:

    System.import('app/main.js')
    

    这会导致 SystemJS 从文件 app/main.js 开始尝试加载您的应用程序。 SystemJS 做的第一件事规范化路径(app/main.js),这意味着它翻译路径到 systemjs.config.js 中的规则。

    Systemjs.config.js 为 SystemJS 导入的任何东西定义了不同类型的别名:


    地图

    地图部分有两种用途:

    路径别名

    在使用 SystemJS 加载模块的应用程序中,map 部分用于为路径的一部分设置别名,告诉 SystemJS 特定命名模块的实际位置。例如,您可能会像这样使用 SystemJS 加载您的应用程序:

    System.import('app/main.js')
    

    现在,假设您实际上想要在以下位置找到您的应用文件:

    /assets/js/app.
    

    您可以在 systemjs.config.js 的“地图”部分中定义它:

    // map tells the System loader where to look for things
    map: {
      'app': '/assets/js/app'
    }
    

    SystemJS 然后会在以下位置查找您的主文件:

    /assets/js/app/main.js
    

    确定模块的位置

    SystemJS 的主要基本目的是提供一个模块系统来解决浏览器中缺乏通用 ES 模块支持的问题,其中一种方法是使用 systemjs.config.js 的 'map' 部分确定在哪里寻找模块。

    对于使用标准 ES 'import' 语句在您的应用程序中导入的任何模块,map 部分确定 SystemJS 将在何处找到它们(在您的应用程序使用 SystemJS 加载之后)。这是一个常见的例子:

        // map tells the System loader where to look for things
        map: {
            // angular bundles
            '@angular/core': 'npm:@angular/core/bundles/core.umd.js',
            '@angular/common': 'npm:@angular/common/bundles/common.umd.js',
            '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
    

    这意味着当您第一次在根模块中执行此操作时:

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

    ... SystemJS 将通过在其默认位置查找 Angular 核心库来处理导入(假设它是使用 npm 安装的):

    /node_modules/@angular/core/bundles/core.umd.js
    

    现在,您可能想知道 'npm:' 是如何转换为 '/node_modules' 的,这就是 systemjs.config.js 的 'paths' 部分所做的:


    路径

    本节为“map”下定义的部分模块路径定义别名。上面例子中'npm'可以被别名的方式是这样的:

    paths: {
      // paths serve as alias
      'npm:': '/node_modules/'
    }
    

    这将替换您添加到“map”部分的任何路径中出现的任何“npm”,并将替换为字符串“/node_modules/”。

    官方文档:https://github.com/systemjs/systemjs/blob/master/docs/config-api.md#paths(已死)


    来自文档:

    包为设置元和地图配置提供了便利 这是特定于公共路径的。

    例如,如果您想像这样加载您的应用:

    System.import('app')
    

    然后您可以为“包”添加此部分:

        // packages tells the System loader how to load when no filename and/or no extension
        packages: {
            app: {
                main: 'index.js'
                defaultExtension: 'js',
                meta: {
                    './*.js': {
                        loader: false,
                    }
                }
            }
    

    以下是细分:

    main: 'index.js'
    

    包或路径别名的主要入口点(如果尚未在“地图”部分提供)

    defaultExtension: 'js'
    

    假定的文件扩展名(如果尚未提供)。在这种情况下,如果未指定文件类型,请查找 .js 文件。

    meta: {
        './*.js': {
            loader: false,
        }
    }
    

    SystemJS 需要确定如何正确加载模块的信息。在这种情况下,不要为我们的应用程序中的任何“.js”文件调用模块加载器(如果您使用 TypeScript,您将需要这个 - 您只希望 SystemJS 在您转译 TypeScript 时加载模块,并且您需要忽略转译的 .js 文件)

    (有关“元”的更多信息,请参阅文档 - https://github.com/systemjs/systemjs/blob/master/docs/config-api.md#meta(已死))

    有关“包”部分的完整说明,另请参阅此处的官方文档:

    https://github.com/systemjs/systemjs/blob/master/docs/config-api.md#packages(已死)

    【讨论】:

    • 老兄,这是一个很好的答案:)
    • 您能否澄清一下为什么您不希望 systemjs 加载 JS 文件?你说你只想在编译打字稿时加载模块,但打字稿将文件编译成JS,所以它会加载JS文件。我有点困惑。
    【解决方案2】:

    它允许配置 SystemJS 以加载使用 TypeScript 编译器编译的模块。对于匿名模块(每个 JS 文件一个模块),它允许将模块的名称映射到实际包含模块 JavaScript 代码的 JS 文件。

    这是一个示例。如果我尝试导入名为app/test 的模块,SystemJS 会这样做:

    • 尝试找到一个预注册的模块(带有System.register('app/test', ...
    • 如果没有,它将查看其配置以构建请求以执行以加载相应的文件:
      • app 有一个 map 条目
      • app 有一个packages 条目,其中defaultExtension = js
    • 请求将是http://localhost:3000/app/test.js。如果您有map: { app: dist },则请求将是http://localhost:3000/dist/test.js

    【讨论】:

    • systemjs 引用 Index.html 文件中的 node_modules 文件夹。那么当我部署我的应用程序时,我是否也应该打包 node_modules 文件夹?
    • @user20358 在生产环境中,您可能会使用构建工具将 node_modules 文件夹中的所有依赖项“捆绑”到一个文件中。以 browserify 为例查看 browserify.org
    • 这个文件的使用和tsconfig.json文件中编译器选项中的module属性有关系吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-10
    • 2019-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多