Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
544 views
in Technique[技术] by (71.8m points)

import - Angular2 & TypeScript importing of node_modules

I had a very simple 'hello world' Angular2 app. I also made the apparently unreasonable decision to work with different directory structures between my dev project and the final deployment folder on my spring backend.

Because of this difference, I had an issue with the TypeScript imports, and this line ended up producing 404 errors (unable to find /angular2/core library) when I tried to open the actual app in my browser:

import {Component, View} from 'angular2/core';

So long story short, I ended up adding back the /app folder to make everything work, but I ended up modifying my import statements as follows:

import {Component, View} from '../node_modules/angular2/core';

This, however, turned out to cause some weird behavior. For some reason specifying ../node_modules in the library paths is causing the JS to actually load ALL Angular2 files from scratch using ajax calls to retrieve each and every individual file from the npm_modules/angular2/ folder even though this was part of my HTML header:

<script src="/node_modules/angular2/bundles/angular2.dev.js"></script>

When I finally realized what's going on I reverted the import statement back to

import {Component, View} from 'angular2/core';

and it all worked. Angular2 was now completely loaded from the script tag above and there were no files getting loaded by extra ajax calls.

Can someone please explain what is causing this? I assume it's normal behavior but I don't understand how the importing works and why specifying a more detailed path makes such a difference.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The import rules of TypeScript follow the same convention as node.js. If an import begins with a dot:

import {Something} from './some/path';

Then it is treated as a relative path from the file that declares the import. If however it is an absolute path:

import {Component} from 'angular2/core';

Then it is assumed to be an external module, so Typescript will walk up the tree looking for a package.json file, then go into the node_modules folder, and find a folder with the same name as the import, then looks in the package.json of the module for the main .d.ts or .ts file, and then loads that, or will look for a file that has the same name as the one specified, or an index.d.ts or index.ts file.

Wow that seems complex when written out, and there are still some exceptions there... But all in all, if you have worked with node.js before then this should behave exactly the same way.

One thing to note is that there is a TypeScript compiler option that should be set for typing resolutions to work in this way

in tsconfig.json

"moduleResolution": "node"

Now the second part of your question was how does this get loaded without using ajax calls. This is a feature of System.js. The script tag that is loaded in the index.html file imports a bundle which registers the angular2 bundle with System. Once this has happened System knows about these files and correctly assigns them to their references. It's a pretty deep topic but a lot of information can be found either in the README of systemjs, or systemjs-builder.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...