为什么我不能使用SystemJS直接从node_modules导入?

时间:2016-12-18 16:22:11

标签: javascript angular typescript systemjs

虽然SystemJS上有很多questionsdocumentation,但我仍然不了解导入语法。 具体来说,为什么打字稿不能使用此代码找到ng-boostrap.js

import { createPlatform } from '../../node_modules/@ng-bootstrap/ng-bootstrap/bundles/ng-bootstrap',

直接导入文件,但此代码有效:

import {createPlatform } from './node_modules/@angular/core/bundles/core.umd.js';

map中的systemjs.config.js包含以下行:

'@angular/core': 'npm:@angular/core/bundles/core.umd.js'.

为什么我无法使用systemJS直接从node_modules导入?

1 个答案:

答案 0 :(得分:2)

注意:虽然下面的解决方案有效,但有些信息不正确。请在评论中查看以下讨论。

首先,TypeScript对JS文件一无所知。它知道如何生成它们,但不知道如何编译它们。所以我不确定你是怎么做到的

import {createPlatform } from './node_modules/@angular/core/bundles/core.umd.js';

在您的TypeScript代码中编译。

我们能够做到

import {createPlatform } from '@angular/core';
在TypeScript中

,因为TypeScript已经在node_modules中查找。 @angular/core,如果您查看node_module内部,则其目录为@angular/core,文件为index.d.ts。这是我们的TypeScript代码编译的文件,而不是JS文件。 JS文件(上面第一个代码片段中的文件)仅在运行时使用。 TypeScript应该对该文件一无所知。

使用上面的第二个片段,当TypeScript编译为JS时,它看起来像

var createPlatform = require('@angular/core').createPlatform;

作为运行时,SystemJS会看到这个,然后查看map配置,并将@angular/core映射到绝对文件位置,并能够加载该文件

'@angular/core': 'npm:@angular/core/bundles/core.umd.js'

这是你应该遵循ng-bootstrap的模式。使用指向TypeScript定义文件的导入,以便它可以编译

import { ... } from '@ng-bootstrap/ng-bootstrap';

如果您查看node_modules/@ng-bootstrap/ng-bootstrap目录,则应该看到index.d.ts文件。这是TypeScript将用于编译的内容。当它被编译为JS时,它编译如下

var something = require('@ng-bootstrap/ng-bootstrap').something;

在SystemJS配置中,我们需要将@ng-bootstrap/ng-bootstrap映射到模块文件的绝对路径,否则SystemJS将不知道如何解决它。

'@ng-bootstrap/ng-bootstrap': 'npm:@ng-bootstrap/ng-bootstrap/bundles/ng-bootstrap.js'

关键的一点是,要了解编译时和运行时之间的区别。编译类型是TypeScript,它对JS文件一无所知,因为它们是运行时文件。 SystemJS是需要了解运行时(JS)文件的人。