Tenía una aplicación Angular2 'hola mundo' muy simple. También tomé la decisión aparentemente irrazonable de trabajar con diferentes estructuras de directorios entre mi proyecto de desarrollo y la carpeta de implementación final en mi backend de primavera.
Debido a esta diferencia, tuve un problema con las importaciones de TypeScript, y esta línea terminó generando errores 404 (no se pudo encontrar la biblioteca /angular2/core) cuando intenté abrir la aplicación real en mi navegador:
import {Component, View} from 'angular2/core';En pocas palabras, terminé agregando nuevamente la carpeta /app para que todo funcionara, pero terminé modificando mis declaraciones de importación de la siguiente manera:
import {Component, View} from '../node_modules/angular2/core'; Esto, sin embargo, resultó causar un comportamiento extraño. Por alguna razón, especificar ../node_modules en las rutas de la biblioteca hace que JS realmente cargue TODOS los archivos Angular2 desde cero usando llamadas ajax para recuperar todos y cada uno de los archivos individuales de la npm_modules/angular2/ aunque esto era parte de mi encabezado HTML :
<script src="/node_modules/angular2/bundles/angular2.dev.js"></script>Cuando finalmente me di cuenta de lo que estaba pasando, revertí la declaración de importación a
import {Component, View} from 'angular2/core';y todo funcionó. Angular2 ahora estaba completamente cargado desde la etiqueta de secuencia de comandos anterior y no se cargaban archivos mediante llamadas ajax adicionales.
¿Puede alguien explicar qué está causando esto? Supongo que es un comportamiento normal, pero no entiendo cómo funciona la importación y por qué especificar una ruta más detallada hace tanta diferencia.
Las reglas de import de TypeScript siguen la misma convención que node.js. Si una importación comienza con un punto:
import {Something} from './some/path';Luego se trata como una ruta relativa desde el archivo que declara la importación. Sin embargo, si es una ruta absoluta:
import {Component} from 'angular2/core'; Entonces se supone que es un módulo externo, por lo que Typescript subirá por el árbol en busca de un archivo package.json , luego irá a la carpeta node_modules y encontrará una carpeta con el mismo nombre que la importación, luego buscará en el package.json del módulo para el archivo principal .d.ts o .ts y luego lo carga, o buscará un archivo que tenga el mismo nombre que el especificado, o un archivo index.d.ts o index.ts .
Wow, eso parece complejo cuando se escribe, y todavía hay algunas excepciones allí... Pero en general, si ha trabajado con node.js antes, esto debería comportarse exactamente de la misma manera.
Una cosa a tener en cuenta es que hay una opción de compilador de TypeScript que debe configurarse para que las resoluciones de escritura funcionen de esta manera.
en tsconfig.json
"moduleResolution": "node" Ahora, la segunda parte de su pregunta fue cómo se carga esto sin usar llamadas ajax. Esta es una característica de System.js . La etiqueta de secuencia de comandos que se carga en el archivo index.html importa un paquete que registra el paquete angular2 con System. Una vez que esto ha sucedido, el sistema conoce estos archivos y los asigna correctamente a sus referencias. Es un tema bastante profundo, pero se puede encontrar mucha información en el LÉAME de systemjs o systemjs-builder .