Jaka jest najlepsza metoda łączenia Angulara (wersja 2, 4, 6, ...) do produkcji na serwerze sieciowym na żywo.
Dołącz odpowiedź Angular do odpowiedzi, abyśmy mogli lepiej śledzić zmiany w późniejszych wersjach.
Jaka jest najlepsza metoda łączenia Angulara (wersja 2, 4, 6, ...) do produkcji na serwerze sieciowym na żywo.
Dołącz odpowiedź Angular do odpowiedzi, abyśmy mogli lepiej śledzić zmiany w późniejszych wersjach.
Odpowiedzi:
2.x, 4.x, 5.x, 6.x, 7.x, 8.x, 9.x
(TypeScript) z Angular CLInpm install -g @angular/cli
ng new projectFolder
tworzy nową aplikacjęng build --prod
(uruchom w wierszu poleceń, gdy katalog jest projectFolder
)
prod
pakiet flag dla produkcji (patrz dokumentacja kątowa, aby uzyskać listę opcji dołączonych do flagi produkcji).
Kompresuj za pomocą kompresji Brotli zasobów za pomocą następującego polecenia
for i in dist/*; do brotli $i; done
pakiety są generowane domyślnie do projectFolder / dist (/ $ projectFolder dla 6)
Rozmiary z Angular 9.0.0
z CLI 9.0.1
i opcją CSS bez Angular routingu
dist/main-[es-version].[hash].js
Twoja aplikacja w pakiecie [rozmiar ES5: 158 KB dla nowej aplikacji Angular CLI pusty, 40 KB skompresowany].dist/polyfill-[es-version].[hash].bundle.js
Zależności wielopełnienia (@ prostokątne, RxJS ...) w pakiecie [rozmiar ES5: 127 KB dla nowej aplikacji Angular CLI pusty, 37 KB skompresowany].dist/index.html
punkt wejścia Twojej aplikacji.dist/runtime-[es-version].[hash].bundle.js
moduł ładującydist/style.[hash].bundle.css
definicje styludist/assets
zasoby skopiowane z konfiguracji zasobów Angular CLIPodgląd aplikacji można uzyskać za pomocą ng serve --prod
polecenia uruchamiającego lokalny serwer HTTP, dzięki czemu aplikacja z plikami produkcyjnymi jest dostępna za pomocą http: // localhost: 4200 .
W przypadku zastosowania produkcyjnego musisz wdrożyć wszystkie pliki z dist
folderu na wybranym serwerze HTTP.
2.0.1 Final
using Gulp (TypeScript - Target: ES5)npm install
(uruchom w cmd, gdy katalog jest folderem projektu)npm run bundle
(uruchom w cmd, gdy katalog jest folderem projektu)
pakiety są generowane w folderze projektu / pakiety /
bundles/dependencies.bundle.js
[ rozmiar: ~ 1 MB (tak mały, jak to możliwe)]
bundles/app.bundle.js
[ rozmiar: zależy od twojego projektu , mój wynosi ~ 0,5 MB ]
var gulp = require('gulp'),
tsc = require('gulp-typescript'),
Builder = require('systemjs-builder'),
inlineNg2Template = require('gulp-inline-ng2-template');
gulp.task('bundle', ['bundle-app', 'bundle-dependencies'], function(){});
gulp.task('inline-templates', function () {
return gulp.src('app/**/*.ts')
.pipe(inlineNg2Template({ useRelativePaths: true, indent: 0, removeLineBreaks: true}))
.pipe(tsc({
"target": "ES5",
"module": "system",
"moduleResolution": "node",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": true,
"noImplicitAny": false
}))
.pipe(gulp.dest('dist/app'));
});
gulp.task('bundle-app', ['inline-templates'], function() {
// optional constructor options
// sets the baseURL and loads the configuration file
var builder = new Builder('', 'dist-systemjs.config.js');
return builder
.bundle('dist/app/**/* - [@angular/**/*.js] - [rxjs/**/*.js]', 'bundles/app.bundle.js', { minify: true})
.then(function() {
console.log('Build complete');
})
.catch(function(err) {
console.log('Build error');
console.log(err);
});
});
gulp.task('bundle-dependencies', ['inline-templates'], function() {
// optional constructor options
// sets the baseURL and loads the configuration file
var builder = new Builder('', 'dist-systemjs.config.js');
return builder
.bundle('dist/app/**/*.js - [dist/app/**/*.js]', 'bundles/dependencies.bundle.js', { minify: true})
.then(function() {
console.log('Build complete');
})
.catch(function(err) {
console.log('Build error');
console.log(err);
});
});
{
"name": "angular2-quickstart",
"version": "1.0.0",
"scripts": {
***
"gulp": "gulp",
"rimraf": "rimraf",
"bundle": "gulp bundle",
"postbundle": "rimraf dist"
},
"license": "ISC",
"dependencies": {
***
},
"devDependencies": {
"rimraf": "^2.5.2",
"gulp": "^3.9.1",
"gulp-typescript": "2.13.6",
"gulp-inline-ng2-template": "2.0.1",
"systemjs-builder": "^0.15.16"
}
}
(function(global) {
// map tells the System loader where to look for things
var map = {
'app': 'app',
'rxjs': 'node_modules/rxjs',
'angular2-in-memory-web-api': 'node_modules/angular2-in-memory-web-api',
'@angular': 'node_modules/@angular'
};
// packages tells the System loader how to load when no filename and/or no extension
var packages = {
'app': { main: 'app/boot.js', defaultExtension: 'js' },
'rxjs': { defaultExtension: 'js' },
'angular2-in-memory-web-api': { defaultExtension: 'js' }
};
var packageNames = [
'@angular/common',
'@angular/compiler',
'@angular/core',
'@angular/forms',
'@angular/http',
'@angular/platform-browser',
'@angular/platform-browser-dynamic',
'@angular/router',
'@angular/router-deprecated',
'@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.asp's chance to modify config before we register it.
if (global.filterSystemConfig) { global.filterSystemConfig(config); }
System.config(config);
})(this);
var map = {
'app': 'dist/app',
};
dist-systemjs.config.js
znacznika po znacznikach pakietu nadal pozwoli na uruchomienie programu, ale pakiet zależności zostanie zignorowany, a zależności zostaną załadowane z node_modules
folderu.<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<base href="/"/>
<title>Angular</title>
<link rel="stylesheet" type="text/css" href="style.css"/>
</head>
<body>
<my-app>
loading...
</my-app>
<!-- Polyfill(s) for older browsers -->
<script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/zone.js/dist/zone.min.js"></script>
<script src="node_modules/reflect-metadata/Reflect.js"></script>
<script src="node_modules/systemjs/dist/system.js"></script>
<script src="dist-systemjs.config.js"></script>
<!-- Project Bundles. Note that these have to be loaded AFTER the systemjs.config script -->
<script src="bundles/dependencies.bundle.js"></script>
<script src="bundles/app.bundle.js"></script>
<script>
System.import('app/boot').catch(function (err) {
console.error(err);
});
</script>
</body>
</html>
Najlepsze, co mogłem zrobić :)
inline-templates
uruchomieniu wstawia szablony, a następnie tworzy kopię wszystkich folderów i plików aplikacji w folderze dist/app
. Następnie wdist-systemjs.config.js
odwzorować app
na dist/app
który to folder, który nie istnieje w przypadku korzystania z dist
folderu jako root. Czy nie chcesz uruchomić aplikacji z dist
folderu? W takim przypadku dist
folder nie byłby zagnieżdżony w dist
folderze głównym . Muszę tu coś przegapić. Czy nie musisz informować systemjs, aby używał twoich plików w pakiecie, a nie zwykłych plików znalezionych w dist/app
folderze?
Zespół Angular2 opublikował samouczek dotyczący korzystania z pakietu Webpack
Pliki z samouczka utworzyłem i umieściłem w małym projekcie początkowym GitHub . Możesz więc szybko wypróbować przepływ pracy.
Instrukcje :
instalacja npm
npm start . Dla rozwoju. Spowoduje to utworzenie wirtualnego folderu „dist”, który zostanie ponownie załadowany na Twój adres localhost.
kompilacja npm run . Do produkcji „Spowoduje to utworzenie fizycznej wersji folderu„ dist ”, która może zostać wysłana do serwera WWW. Folder dist ma 7,8 MB, ale tylko 234 KB jest wymagane do załadowania strony w przeglądarce internetowej.
Ten zestaw startowy Webpack oferuje więcej funkcji testowych niż powyższy samouczek i wydaje się dość popularny.
Angular.io ma samouczek szybkiego startu. Skopiowałem ten samouczek i rozszerzyłem o kilka prostych zadań typu gulp, aby spakować wszystko do folderu dist, który można skopiować na serwer i tak po prostu pracować. Próbowałem zoptymalizować wszystko, aby działało dobrze w Jenkis CI, aby moduły node_modu mogły być buforowane i nie trzeba ich kopiować.
Kod źródłowy z przykładową aplikacją na Github: https://github.com/Anjmao/angular2-production-workflow
Kroki do produkcjiWęzeł : Chociaż zawsze możesz utworzyć własny proces kompilacji, ale bardzo polecam użycie angular-cli, ponieważ ma on wszystkie potrzebne przepływy pracy i działa teraz idealnie. Używamy go już w produkcji i nie mamy żadnych problemów z angular-cli.
Obsługuje to:
ng nazwa nowego projektu - routing
Możesz dodać --style=scss
obsługę SASS .scss.
Możesz dodać --ng4
do korzystania z Angular 4 zamiast Angular 2.
Po utworzeniu projektu interfejs CLI uruchomi się automatycznie npm install
. Jeśli zamiast tego chcesz użyć Przędzy lub po prostu chcesz zobaczyć szkielet projektu bez instalacji, sprawdź, jak to zrobić tutaj .
W folderze projektu:
ng build -prod
W bieżącej wersji musisz określić --aot
ręcznie, ponieważ można jej używać w trybie programowania (chociaż nie jest to praktyczne ze względu na powolność).
To również wykonuje kompilację AoT dla jeszcze mniejszych pakietów (bez kompilatora Angular, zamiast tego wygenerowano dane wyjściowe kompilatora). Pakiety są znacznie mniejsze z AoT, jeśli używasz Angular 4, ponieważ generowany kod jest mniejszy.
Możesz przetestować swoją aplikację za pomocą AoT w trybie programowania (sourcemaps, bez minimalizacji) i AoT, uruchamiającng build --aot
.
Domyślnym katalogiem wyjściowym jest ./dist
, choć można go zmienić./angular-cli.json
.
Wynik kroku kompilacji jest następujący:
(Uwaga: <content-hash>
odnosi się do skrótu / odcisku palca zawartości pliku, który ma być sposobem na pomijanie pamięci podręcznej, jest to możliwe, ponieważ Webpack zapisuje script
tagi samodzielnie)
./dist/assets
./src/assets/**
./dist/index.html
./src/index.html
, po dodaniu do niego skryptów webpack, ./angular-cli.json
./dist/inline.js
./dist/main.<content-hash>.bundle.js
./dist/styles.<content-hash>.bundle.js
W starszych wersjach utworzono także wersje spakowane gzip do sprawdzania ich rozmiaru oraz .map
plików sourcemaps, ale nie dzieje się tak, ponieważ ludzie wciąż proszą o ich usunięcie.
W niektórych innych przypadkach możesz znaleźć inne niechciane pliki / foldery:
./out-tsc/
./src/tsconfig.json
„soutDir
./out-tsc-e2e/
./e2e/tsconfig.json
„soutDir
./dist/ngfactory/
<content-hash>
z pakietów w prod. może to powodować problemy z uzyskaniem najnowszego pakietu?
Na dzień dzisiejszy nadal uważam książkę kucharską z kompilacją Ahead-of-Time za najlepszy przepis na pakiet produkcyjny. Można go znaleźć tutaj: https://angular.io/docs/ts/latest/cookbook/aot-compiler.html
Moje dotychczasowe doświadczenia z Angularem 2 polegają na tym, że AoT tworzy najmniejsze kompilacje bez prawie żadnego czasu ładowania. I najważniejsze, ponieważ chodzi o pytanie - wystarczy wysłać tylko kilka plików do produkcji.
Wydaje się, że dzieje się tak, ponieważ kompilator Angular nie zostanie dostarczony z kompilacjami produkcyjnymi, ponieważ szablony są kompilowane „przed czasem”. Fajnie jest też widzieć znaczniki szablonów HTML przekształcone w instrukcje javascript, których odtworzenie w oryginalnym HTML byłoby bardzo trudne.
Zrobiłem prosty film, w którym pokazuję rozmiar pobierania, liczbę plików itp. Dla aplikacji Angular 2 w wersji dev vs AoT - którą możesz zobaczyć tutaj:
Tutaj znajdziesz kod źródłowy użyty w filmie:
**Production build with
- Angular Rc5
- Gulp
- typescripts
- systemjs**
1)con-cat all js files and css files include on index.html using "gulp-concat".
- styles.css (all css concat in this files)
- shims.js(all js concat in this files)
2)copy all images and fonts as well as html files with gulp task to "/dist".
3)Bundling -minify angular libraries and app components mentioned in systemjs.config.js file.
Using gulp 'systemjs-builder'
SystemBuilder = require('systemjs-builder'),
gulp.task('system-build', ['tsc'], function () {
var builder = new SystemBuilder();
return builder.loadConfig('systemjs.config.js')
.then(function () {
builder.buildStatic('assets', 'dist/app/app_libs_bundle.js')
})
.then(function () {
del('temp')
})
});
4)Minify bundles using 'gulp-uglify'
jsMinify = require('gulp-uglify'),
gulp.task('minify', function () {
var options = {
mangle: false
};
var js = gulp.src('dist/app/shims.js')
.pipe(jsMinify())
.pipe(gulp.dest('dist/app/'));
var js1 = gulp.src('dist/app/app_libs_bundle.js')
.pipe(jsMinify(options))
.pipe(gulp.dest('dist/app/'));
var css = gulp.src('dist/css/styles.min.css');
return merge(js,js1, css);
});
5) In index.html for production
<html>
<head>
<title>Hello</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta charset="utf-8" />
<link rel="stylesheet" href="app/css/styles.min.css" />
<script type="text/javascript" src="app/shims.js"></script>
<base href="https://stackoverflow.com/">
</head>
<body>
<my-app>Loading...</my-app>
<script type="text/javascript" src="app/app_libs_bundle.js"></script>
</body>
</html>
6) Now just copy your dist folder to '/www' in wamp server node need to copy node_modules in www.
Możesz wdrożyć aplikację kątową przy github
użyciu
angular-cli-ghpages
sprawdź link, aby dowiedzieć się, jak wdrożyć przy użyciu tego CLI.
wdrożona strona internetowa będzie przechowywana w jakimś oddziale w github
zazwyczaj
strony gh
use może sklonować gałąź git i używać jej jak statycznej witryny na serwerze
„Najlepsze” zależy od scenariusza. Są chwile, kiedy zależy Ci tylko na najmniejszym możliwym pojedynczym pakiecie, ale w dużych aplikacjach możesz rozważyć leniwe ładowanie. W pewnym momencie niepraktyczne jest obsługiwanie całej aplikacji jako jednego pakietu.
W tym drugim przypadku Webpack jest ogólnie najlepszym sposobem, ponieważ obsługuje dzielenie kodu.
W przypadku pojedynczego pakietu rozważyłbym Rollup lub kompilator Closure, jeśli czujesz się odważny :-)
Stworzyłem próbki wszystkich Anglerów, z których kiedykolwiek tu korzystałem: http://www.syntaxsuccess.com/viewarticle/angular-production-builds
Kod można znaleźć tutaj: https://github.com/thelgevold/angular-2-samples
Wersja kątowa: 4.1.x
Wystarczy skonfigurować Angular 4 z pakietem WebPack 3 w ciągu minuty Twój pakiet rozwojowy i produkcyjny ENV będzie gotowy bez żadnych problemów, postępuj zgodnie z poniższym dokumentem github
Spróbuj poniżej komendy CLI w bieżącym katalogu projektu. Stworzy pakiet folderów dist. dzięki czemu możesz przesłać wszystkie pliki w folderze dist do wdrożeń.
ng build --prod --aot --base-href.
ng serwuje prace służące do obsługi naszej aplikacji w celach programistycznych. A co z produkcją? Jeśli spojrzymy na nasz plik package.json, możemy zobaczyć, że istnieją skrypty, których możemy użyć:
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build --prod",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
},
Skrypt kompilacji używa kompilacji ng Angular CLI z flagą --prod. Spróbujmy teraz. Możemy to zrobić na dwa sposoby:
# za pomocą skryptów npm
npm run build
# przy użyciu cli bezpośrednio
ng build --prod
Tym razem otrzymujemy cztery pliki zamiast pięciu. Flaga --prod mówi firmie Angular, aby nasza aplikacja była znacznie mniejsza.