2016-02-02 21 views
34

Avevo una semplice app Angular2 "hello world". Ho anche preso la decisione apparentemente irragionevole di lavorare con diverse strutture di directory tra il mio progetto di sviluppo e la cartella di distribuzione finale sul mio backend di primavera.Importazione Angular2 e TypeScript di node_modules

causa di questa differenza, ho avuto un problema con le importazioni dattiloscritto, e questa linea ha finito per produrre errori 404 (non in grado di trovare la libreria/angular2/core) quando ho cercato di aprire l'applicazione effettiva nel browser:

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

Quindi per farla breve, ho finito per l'aggiunta di nuovo la cartella/app per far funzionare tutto, ma ho finito per modificare le mie istruzioni import come segue:

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

Questo, tuttavia, si è rivelata causa qualche strano comportamento Per qualche ragione specifica ../node_modules nei percorsi della biblioteca è la causa del JS per caricare effettivamente i file ALL Angular2 da zero utilizzando chiamate AJAX per recuperare ogni singolo file dalla cartella npm_modules/angular2/ anche se questo era parte del mio header HTML:

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

Quando ho finalmente capito quello che sta succedendo sono ritornato l'istruzione import di nuovo a

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

e tutto ha funzionato. Angular2 ora era completamente caricato dal tag script sopra e non c'erano file che venivano caricati da chiamate AJAX extra.

Qualcuno può spiegare per favore che cosa sta causando questo? Presumo che sia un comportamento normale, ma non capisco come funziona l'importazione e perché specificare un percorso più dettagliato fa una tale differenza.

+0

Per ulteriori dettagli sull'importazione di moduli in un mondo TS: https://www.typescriptlang.org/docs/handbook/module-resolution.html I documenti sono fatti bene per questo. Veramente. – rashadb

risposta

56

Le regole import di TypeScript seguono la stessa convenzione di node.js. Se l'importazione inizia con un punto:

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

allora è trattato come un percorso relativo dal file che dichiara l'importazione. Se invece si tratta di un percorso assoluto:

import {Component} from 'angular2/core'; 

Quindi si presume che sia un modulo esterno, in modo da tipografico camminerà l'albero alla ricerca di un file package.json, poi andare nella cartella node_modules, e trovare una cartella con lo stesso nome l'importazione, poi guarda nella package.json del modulo per i principali file di .d.ts o .ts, e quindi carica che, o sarà cercare un file che ha lo stesso nome di quello specificato, o un index.d.ts o index.ts file.

Wow che sembra complesso quando è stato scritto, e ci sono ancora alcune eccezioni lì ... Ma tutto sommato, se hai lavorato con node.js prima di allora questo dovrebbe comportarsi esattamente allo stesso modo.

Una cosa da notare è che c'è un'opzione del compilatore dattiloscritto che dovrebbe essere impostato per la digitazione riusciti a lavorare in questo modo

in TSconfig.JSON

"moduleResolution": "node" 

Ora la seconda parte della tua domanda è come funziona questo vengono caricati senza usare le chiamate Ajax. Questa è una funzionalità di System.js. Il tag script caricato nel file index.html importa un pacchetto che registra il pacchetto angular2 con System. Una volta che questo è successo, System conosce questi file e li assegna correttamente ai loro riferimenti. È un argomento piuttosto approfondito, ma è possibile trovare molte informazioni nel README di systemjs o systemjs-builder.

+0

Grazie mille per la risposta dettagliata e ben scritta. Sto usando nodejs al lavoro da alcuni anni, ma in qualche modo sono riuscito a evitare di incappare in questo problema fino ad ora. Sono contento ora so cosa succede dietro le quinte - grazie ancora! – RVP

+0

@Thierry Templier: ciao, ho il codice utilizzare i moduli node.js, ad esempio, 'var fs: any = require ('fs')'. Causa il problema Sai come posso usare l'importazione per fare questo? –

+1

@ Ng2-Fun Il 'fs' è un modulo core del nodo che non sarà disponibile nel browser in modo che Systemjs non sia in grado di localizzare il file da caricare. Questo è un problema che sto riscontrando in un caso d'uso diverso. Anche se è in esecuzione nel nodo, Systemjs tenterà di caricare un modulo per questo, anche se non è necessario. Devo ancora trovare una soluzione per questo diverso da compilare il typescript in commonjs invece (anche se non ho provato a eseguire l'applicazione in questo modo). Per dattiloscritto non angolare2 nel nodo usando commonjs puoi usare 'import * come fs da 'fs';' che dovrebbe darti quello che ti serve. – SnareChops

Problemi correlati