Qual é o melhor método para agrupar o Angular (versão 2, 4, 6, ...) para produção em um servidor da web ao vivo.
Inclua a versão Angular nas respostas para que possamos acompanhar melhor quando ela for lançada posteriormente.
Qual é o melhor método para agrupar o Angular (versão 2, 4, 6, ...) para produção em um servidor da web ao vivo.
Inclua a versão Angular nas respostas para que possamos acompanhar melhor quando ela for lançada posteriormente.
Respostas:
2.x, 4.x, 5.x, 6.x, 7.x, 8.x, 9.x
(TypeScript) com CLI angularnpm install -g @angular/cli
ng new projectFolder
cria um novo aplicativong build --prod
(executado na linha de comandos quando o diretório estiver projectFolder
)
prod
Pacote de sinalizadores para produção (consulte a documentação Angular para obter a lista de opções incluídas no sinalizador de produção).
Compactar usando Brotli compacta os recursos usando o seguinte comando
for i in dist/*; do brotli $i; done
os pacotes configuráveis são gerados por padrão para projectFolder / dist (/ $ projectFolder for 6)
Tamanhos com Angular 9.0.0
com CLI 9.0.1
e opção CSS sem roteamento Angular
dist/main-[es-version].[hash].js
Seu aplicativo empacotou [tamanho do ES5: 158 KB para o novo aplicativo CLI Angular vazio, 40 KB compactado].dist/polyfill-[es-version].[hash].bundle.js
as dependências do polyfill (@angular, RxJS ...) empacotadas [tamanho ES5: 127 KB para o novo aplicativo CLI Angular vazio, 37 KB compactado].dist/index.html
ponto de entrada da sua aplicação.dist/runtime-[es-version].[hash].bundle.js
carregador webpackdist/style.[hash].bundle.css
as definições de estilodist/assets
recursos copiados da configuração de ativos da CLI AngularVocê pode obter uma visualização do seu aplicativo usando o ng serve --prod
comando que inicia um servidor HTTP local, para que o aplicativo com arquivos de produção seja acessível usando http: // localhost: 4200 .
Para um uso de produção, você deve implantar todos os arquivos da dist
pasta no servidor HTTP de sua escolha.
2.0.1 Final
usando Gulp (TypeScript - Destino: ES5)npm install
(executado no cmd quando direcory é projectFolder)npm run bundle
(executado no cmd quando direcory é projectFolder)
pacotes são gerados para projectFolder / bundles /
bundles/dependencies.bundle.js
[ tamanho: ~ 1 MB (o menor possível)]
bundles/app.bundle.js
[ tamanho: depende do seu projeto , o meu é ~ 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
tag após as tags do pacote configurável ainda permitiria a execução do programa, mas o pacote configurável de dependência seria ignorado e as dependências seriam carregadas da node_modules
pasta.<!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>
O melhor que pude fazer ainda :)
inline-templates
é executado, ele inline os modelos e cria uma cópia de todas as pastas e arquivos do aplicativo em dist/app
. Em seguida, dist-systemjs.config.js
você mapeia app
para a dist/app
qual existe uma pasta que não existirá se você a usar dist
como raiz. Você não gostaria de executar seu aplicativo a partir da dist
pasta? E se for esse o caso, você não teria uma dist
pasta aninhada na dist
pasta raiz . Eu devo estar perdendo algo mais aqui. Você não precisa dizer ao systemjs para usar seus arquivos agrupados e não os arquivos habituais encontrados na dist/app
pasta?
A equipe do Angular2 publicou um tutorial para usar o Webpack
Criei e coloquei os arquivos do tutorial em um pequeno projeto de semente do GitHub . Para que você possa experimentar rapidamente o fluxo de trabalho.
Instruções :
instalação npm
npm start . Para desenvolvimento. Isso criará uma pasta virtual "dist" que será carregada no seu endereço do host local.
npm executar compilação . Para produção. "Isso criará uma versão física da pasta" dist "que pode ser enviada para um servidor da Web. A pasta dist é de 7,8 MB, mas apenas 234 KB são realmente necessários para carregar a página em um navegador da Web.
Este Webpack Starter Kit oferece mais recursos de teste que o tutorial acima e parece bastante popular.
Angular.io tem tutorial de início rápido. Copiei este tutorial e estendi algumas tarefas simples para agrupar tudo na pasta dist, que pode ser copiada para o servidor e funcionar assim. Tentei otimizar tudo para funcionar bem no Jenkis CI, para que o node_modules possa ser armazenado em cache e não precise ser copiado.
Código-fonte com aplicativo de exemplo no Github: https://github.com/Anjmao/angular2-production-workflow
Etapas para a produçãoNó : Embora você sempre possa criar seu próprio processo de criação, mas eu recomendo usar o angular-cli, porque ele possui todos os fluxos de trabalho necessários e funciona perfeitamente agora. Já o estamos usando na produção e não temos nenhum problema com o angular-cli.
Isso suporta:
ng new project-name --routing
Você pode adicionar --style=scss
ao suporte ao SASS .scss.
Você pode adicionar o --ng4
Angular 4 em vez do Angular 2.
Após criar o projeto, a CLI será executada automaticamente npm install
para você. Se você deseja usar o Yarn, ou apenas deseja ver o esqueleto do projeto sem instalar, verifique como fazê-lo aqui .
Dentro da pasta do projeto:
ng build -prod
Na versão atual, você precisa especificar --aot
manualmente, porque pode ser usado no modo de desenvolvimento (embora isso não seja prático devido à lentidão).
Isso também executa a compilação AoT para pacotes ainda menores (nenhum compilador Angular, em vez disso, gerou saída do compilador). Os pacotes configuráveis são muito menores com o AoT se você usar o Angular 4, pois o código gerado é menor.
Você pode testar seu aplicativo com o AoT no modo de desenvolvimento (mapas de origem, sem minificação) e o AoT executandong build --aot
.
O diretório de saída padrão é ./dist
, embora possa ser alterado ./angular-cli.json
.
O resultado da etapa de construção é o seguinte:
(Nota: <content-hash>
refere-se ao hash / impressão digital do conteúdo do arquivo que deve ser uma maneira de impedir o cache, isso é possível, pois o Webpack grava as script
tags sozinho)
./dist/assets
./src/assets/**
./dist/index.html
./src/index.html
, depois de adicionar scripts de Webpack a ele ./angular-cli.json
./dist/inline.js
./dist/main.<content-hash>.bundle.js
./dist/styles.<content-hash>.bundle.js
Nas versões mais antigas, também criava versões compactadas com gzip para verificar o tamanho e os .map
arquivos dos mapas de origem, mas isso não acontece mais porque as pessoas pediam para removê-los.
Em outras ocasiões, você pode encontrar outros arquivos / pastas indesejados:
./out-tsc/
./src/tsconfig.json
'soutDir
./out-tsc-e2e/
./e2e/tsconfig.json
'soutDir
./dist/ngfactory/
<content-hash>
os pacotes no prod. pode causar problemas na obtenção do pacote mais recente?
Até hoje, ainda encontro o livro de receitas de Compilação antecipada como a melhor receita para agrupar a produção. Você pode encontrá-lo aqui: https://angular.io/docs/ts/latest/cookbook/aot-compiler.html
Minha experiência com o Angular 2 até agora é que o AoT cria as versões menores, quase sem tempo de carregamento. E o mais importante, como é a pergunta aqui - você só precisa enviar alguns arquivos para produção.
Isso ocorre porque o compilador Angular não será enviado com as compilações de produção, pois os modelos são compilados "Antecipadamente". Também é muito bacana ver sua marcação de modelo HTML transformada em instruções javascript que seriam muito difíceis de fazer a engenharia reversa no HTML original.
Fiz um vídeo simples em que demonstro o tamanho do download, o número de arquivos, etc., para um aplicativo Angular 2 em compilação dev vs AoT - que você pode ver aqui:
Você encontrará o código-fonte usado no vídeo aqui:
**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.
Você pode implantar seu aplicativo angular github
usando
angular angular-cli-ghpages
confira o link para descobrir como implantar usando este CLI.
o site implantado será armazenado em alguma filial da github
normalmente
páginas gh
O uso pode clonar o ramo git e usá-lo como um site estático no seu servidor
"Melhor" depende do cenário. Há momentos em que você se preocupa apenas com o menor pacote único possível, mas em aplicativos grandes, pode ser necessário considerar um carregamento lento. Em algum momento, torna-se impraticável veicular o aplicativo inteiro como um único pacote.
Neste último caso, o Webpack é geralmente a melhor maneira, pois suporta a divisão de código.
Para um único pacote, consideraria o Rollup ou o compilador Closure se você estiver se sentindo corajoso :-)
Criei amostras de todos os empacotadores angulares que já usei aqui: http://www.syntaxsuccess.com/viewarticle/angular-production-builds
O código pode ser encontrado aqui: https://github.com/thelgevold/angular-2-samples
Versão angular: 4.1.x
Basta configurar o angular 4 com o webpack 3 em um minuto, seu pacote ENV de desenvolvimento e produção ficará pronto sem nenhum problema, basta seguir o documento abaixo do github
Por favor, tente abaixo do comando da CLI no diretório do projeto atual. Isso criará um pacote de pastas dist. para que você possa carregar todos os arquivos na pasta dist para implantações.
ng build --prod --aot --base-href.
ng serve obras para atender nosso aplicativo para fins de desenvolvimento. E quanto à produção? Se olharmos para o nosso arquivo package.json, podemos ver que existem scripts que podemos usar:
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build --prod",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
},
O script de construção usa a construção ng da CLI Angular com o sinalizador --prod. Vamos tentar isso agora. Podemos fazer isso de duas maneiras:
# usando os scripts npm
npm run build
# usando o cli diretamente
ng build --prod
Desta vez, recebemos quatro arquivos em vez dos cinco. O sinalizador --prod informa ao Angular para tornar nosso aplicativo muito menor em tamanho.