javascript typescript angular systemjs

javascript - Angular2 demasiadas solicitudes de archivos en carga



typescript systemjs (9)

Estoy haciendo un sitio web usando Angular2 y tengo lo que supongo que es un problema. En la primera carga de mi página angular, SystemJS está haciendo más de 500 solicitudes para recuperar cada archivo angular2/src en el directorio angular2/src . En total, la primera carga descarga más de 4 MB y tarda más de 14 segundos en iniciarse.

Mi index.html incluye los siguientes scripts:

<script src="libs/angular2/bundles/angular2-polyfills.js"></script> <script src="libs/systemjs/dist/system.src.js"></script> <script src="libs/rxjs/bundles/Rx.js"></script> <script src="libs/angular2/bundles/angular2.min.js"></script> <script src="libs/angular2/bundles/http.dev.js"></script> <script src="libs/jquery/jquery.js"></script> <script src="libs/lodash/lodash.js"></script> <script src="libs/bootstrap/js/bootstrap.js"></script>

Y el código de inicialización de mi sistema se ve así:

<script> System.config({ defaultJSExtensions: true, paths: { ''*'': ''libs/*'', ''app/*'': ''app/*'' }, packageConfigPaths: [''libs/*/package.json''], packages: { app: { format: ''register'', defaultExtension: ''js'' } } }); System.import(''app/main'') .then(null, console.error.bind(console)); </script>

Mi carpeta pública tiene la siguiente estructura:

. ├── img ├── styles ├── app ├── libs | └── angular2 | └── systemjs | └── rxjs | └── jquery | └── lodash | └── bootstrap └── index.html

Un par de capturas de pantalla de algunos de los archivos js que se solicitan:

¿Hay alguna manera de evitar todas esas solicitudes?


En la primera carga de mi página angular, systemjs está haciendo más de 500 solicitudes para recuperar cada archivo angular2 en el directorio angular2 / src. En total, la primera carga descarga más de 4 MB y tarda más de 14 segundos en iniciarse.

Los flujos de trabajo de SystemJs son bastante nuevos y no tienen suficiente investigación para el mejor despliegue.

Sugiera volver a commonjs + webpack . Más: https://basarat.gitbooks.io/typescript/content/docs/quick/browser.html

Aquí hay un ejemplo: github.com/AngularClass/angular2-webpack-starter


@ FreeBird72 Tu respuesta es asombrosa.

Si desea utilizar SystemJS para el desarrollo y acelerar el servidor de producción como lo hago yo. Mira esto.

NOTA: solo importe los componentes que utiliza, NO los importe de todo el paquete.

Por ejemplo: si quieres usar Modal de ng2-bootstrap.

import {MODAL_DIRECTIVES} from "ng2-bootstrap/components/modal";

En vez de:

import {MODAL_DIRECTIVES} from "ng2-bootstrap/ng2-bootstrap";

Esto importará el componente modal en lugar de todo el ng2-bootstrap

Luego sigue la respuesta de @ FreeBird72

Agregue este paquete.json

{ ... "scripts": { ... "prod": "npm run tsc && npm run browserify", "browserify": "browserify -s main dist/main.js > dist/bundle.js && npm run minify", "minify": "uglifyjs dist/bundle.js --screw-ie8 --compress --mangle --output dist/bundle.min.js", ... }, "devDependencies": { ... "browserify": "^13.0.1", "uglifyjs": "^2.4.10", ... } ... }

Entonces puede npm run tsc en el desarrollo y npm run prod en el servidor de producción. También elimine System.import(.... de su index.html y cámbielo a <script src="/dist/bundle.min.js"></script>


Creo que tu pregunta está relacionada con esta:

Para tener algo listo para la producción (y acelerarlo), debe empaquetarlo.

Me refiero a transpilar todos los archivos en JavaScript y concatenarlos de la misma manera que Angular2 lo hace, por ejemplo. De esta manera, tendrá varios módulos contenidos en un solo archivo JS. De esta manera, reducirá la cantidad de llamadas HTTP para cargar el código de su aplicación en el navegador.


Encontré una solución simple, usando browserify & uglifyjs en el repositorio angular2-seed de mgechev

Aquí está mi versión:

pacakge.json:

{ ... "scripts": { "build_prod": "npm run clean && npm run browserify", "clean": "del /S/Q public//dist", "browserify": "browserify -s main public/YourMainModule.js > public/dist/bundle.js && npm run minify", "minify": "uglifyjs public/dist/bundle.js --screw-ie8 --compress --mangle --output public/dist/bundle.min.js" }, ... "devDependencies": { "browserify": "^13.0.1", "typescript": "^1.9.0-dev.20160625-1.0", "typings": "1.0.4", "uglifyjs": "^2.4.10" } }

  1. Construye tu proyecto.
  2. Ejecute: npm run build_prod Creará bundle.js & bundle.min.js en el directorio public / dist.
  3. Edite su archivo index.html : en lugar de ejecutar System.import(''YourMainModule'')... , agregue <script src="/dist/bundle.min.js"></script>

Estoy usando la versión AG2 RC Al usar la solución de MrCroft con systemjs-builder, me encontré con muchos problemas como: error TS2304: No puedo encontrar el nombre ''Mapa'' error TS2304: No puedo encontrar el nombre ''Promesa'' ...

Después de muchos intentos, agregué: ///<reference path="../../typings/index.d.ts" /> en mi boot.ts y ahora tengo mi archivo de paquete compilado.


La interfaz de línea de comandos angular ahora admite la agrupación (con sacudidas de árboles para eliminar el código no utilizado de las importaciones), la minificación y la compilación de plantillas anticipadas, lo que no solo minimiza enormemente la cantidad de solicitudes realizadas, sino que también hace que el paquete sea muy pequeña. Utiliza WebPack debajo.

Es increíblemente fácil hacer compilaciones de producción con él:

ng build --prod --aot

https://github.com/angular/angular-cli


Si desea seguir con SystemJS, puede agrupar su aplicación con JSPM . He tenido un buen éxito con esto hasta ahora, utilizando el comando bundle-sfx JSPM para crear archivos JS únicos para aplicaciones Angular 2.

Hay información útil en este Gist , y hay un proyecto semilla.


Tuve exactamente el mismo problema, en realidad estaba buscando en esta publicación una respuesta. Esto es lo que hice para resolver el problema.

  1. Modifique su proyecto para usar webpack. Siga este breve tutorial: Angular2 QuickStart SystemJS To Webpack
  2. Este método le dará un solo archivo javascript, sin embargo, es bastante grande (mi archivo de proyecto tenía más de 5 MB) y debe minimizarse. Para hacer esto, instalé webpack globalmente: npm install webpack -g . Una vez instalado, ejecute webpack -p desde el directorio raíz de su aplicación. Esto redujo el tamaño de mi archivo a aproximadamente 700 KB

Desde 20 segundos y 350 solicitudes hasta 3 segundos y 7 solicitudes.


Veo que ya tienes una respuesta, lo cual es bueno, por supuesto. PERO para aquellos que quieran usar systemjs (como yo también lo hago), y no ir a webpack, aún pueden agrupar los archivos. Sin embargo, también implica el uso de otra herramienta (yo uso gulp). Entonces ... tendrías la siguiente configuración de systemjs (no en el html, sino en un archivo separado, llamémosle "system.config.js"):

(function(global) { // map tells the System loader where to look for things var map = { ''app'': ''dist/app'', // this is where your transpiled files live ''rxjs'': ''node_modules/rxjs'', ''angular2-in-memory-web-api'': ''node_modules/angular2-in-memory-web-api'', // this is something new since angular2 rc.0, don''t know what it does ''@angular'': ''node_modules/@angular'' }; // 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'' } }; var packageNames = [ ''@angular/common'', ''@angular/compiler'', ''@angular/core'', ''@angular/http'', ''@angular/platform-browser'', ''@angular/platform-browser-dynamic'', //''@angular/router'', // I still use "router-deprecated", haven''t yet modified my code to use the new router that came with rc.0 ''@angular/router-deprecated'', ''@angular/http'', ''@angular/testing'', ''@angular/upgrade'' ]; // 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);

Luego, en su gulpfile.js, crearía un paquete como este (usando la información de los archivos system.config.js y tsconfig.json ):

var gulp = require(''gulp''), path = require(''path''), Builder = require(''systemjs-builder''), ts = require(''gulp-typescript''), sourcemaps = require(''gulp-sourcemaps''); var tsProject = ts.createProject(''tsconfig.json''); var appDev = ''dev/app''; // where your ts files are, whatever the folder structure in this folder, it will be recreated in the below ''dist/app'' folder var appProd = ''dist/app''; /** first transpile your ts files */ gulp.task(''ts'', () => { return gulp.src(appDev + ''/**/*.ts'') .pipe(sourcemaps.init({ loadMaps: true })) .pipe(ts(tsProject)) .pipe(sourcemaps.write(''.'')) .pipe(gulp.dest(appProd)); }); /** then bundle */ gulp.task(''bundle'', function() { // optional constructor options // sets the baseURL and loads the configuration file var builder = new Builder('''', ''dist/system.config.js''); /* the parameters of the below buildStatic() method are: - your transcompiled application boot file (the one wich would contain the bootstrap(MyApp, [PROVIDERS]) function - in my case ''dist/app/boot.js'' - the output (file into which it would output the bundled code) - options {} */ return builder .buildStatic(appProd + ''/boot.js'', appProd + ''/bundle.js'', { minify: true, sourceMaps: true}) .then(function() { console.log(''Build complete''); }) .catch(function(err) { console.log(''Build error''); console.log(err); }); }); /** this runs the above in order. uses gulp4 */ gulp.task(''build'', gulp.series([''ts'', ''bundle'']));

Entonces, cuando ejecutas "gulp build", obtendrás el archivo "bundle.js" con todo lo que necesitas. Claro, también necesita algunos paquetes más para que funcione esta tarea de paquete Gulp:

npm install --save-dev github:gulpjs/gulp#4.0 gulp-typescript gulp-sourcemaps path systemjs-builder

Además, asegúrese de que en su tsconfig.json tenga "module":"commonjs" . Aquí está mi tsconfig.json que se usa en mi tarea ''ts'' gulp:

{ "compilerOptions": { "target": "es5", "module": "commonjs", "moduleResolution": "node", "sourceMap": true, "emitDecoratorMetadata": true, "experimentalDecorators": true, "removeComments": false, "noImplicitAny": false }, "exclude": [ "node_modules", "typings/main", "typings/main.d.ts" ] }

Luego, en su archivo html solo necesita incluir esto:

<!-- Polyfill(s) for older browsers --> <script src="node_modules/es6-shim/es6-shim.min.js"></script> <script src="node_modules/zone.js/dist/zone.js"></script> <script src="node_modules/reflect-metadata/Reflect.js"></script> <script src="dist/app/bundle.js"></script>

Y eso es todo ... obtuve 600 solicitudes, 4mb en unos 5 segundos ... a 20 solicitudes, 1.4mb en 1.6 segundos (máquina de desarrollo local). Pero estas 20 solicitudes ~ 1.4mb en 1.6 segundos también incluyen algunos otros js y css con los que vino el tema admin además de algunas plantillas html que se requieren en la primera carga, prefiero usar plantillas externas - templateUrl: '''', en lugar de los en línea, escritos en mi archivo component.ts. Claro, para una aplicación que tendría millones de usuarios, esto aún no sería suficiente. También se debe implementar el renderizado del lado del servidor para la carga inicial y el sistema de caché, en realidad logré hacerlo con angular universal, pero en Angular2 beta (tardó entre 200 y 240 milisegundos para cargar el renderizado inicial de la misma aplicación de administración que arriba lleva 1.6 segundos - Lo sé: ¡GUAU! ). Ahora es incompatible desde que salió Angular2 RC, pero estoy seguro de que los chicos de Universal lo pondrán al día pronto, especialmente desde que se acerca ng-conf. Además, también están planeando hacer Angular Universal para PHP, ASP y algunos otros, en este momento es solo para Nodejs.

Editar: En realidad, acabo de descubrir que en NG-CONF dijeron que Angular Universal ya es compatible con ASP (pero no es compatible con Angular2> beta.15 :)) ... pero démosles algo de tiempo, RC acaba de llegar fuera hace unos días