Как собрать приложение Angular для производства

353

Как лучше всего связать Angular (версии 2, 4, 6, ...) для производства на живом веб-сервере.

Пожалуйста, включите версию Angular в ответы, чтобы мы могли лучше отслеживать ее при переходе к более поздним версиям.

Пэт М
источник
На данный момент (RC1). Вот несколько решений stackoverflow.com/questions/37324511/how-to-bundle-angular2-rc1-with-systemjs
Пэт М
И этот один stackoverflow.com/questions/37098942/…
Пэт М
rc3 теперь предлагает связанные версии файлов, которые уменьшают количество запросов с 300+ до 40.
Pat M
2
Привет. Я также ненавижу шаги WebPack и сборки в целом. В некотором роде излишняя попытка просто собрать простой сайт. Таким образом я сделал это: github.com/schungx/angular2-bundle
Стивен Чунг
Спасибо, Стивен. Это было бы простым решением для поставщиков. Надеюсь, что это может быть официально предложено и обновлено. Я полагаю, вы используете что-то вроде Gulp для файлов проекта?
Пэт М

Ответы:

362

2.x, 4.x, 5.x, 6.x, 7.x, 8.x, 9.x (TypeScript) с угловым CLI

Настройка OneTime

  • npm install -g @angular/cli
  • ng new projectFolder создает новое приложение

Шаг связывания

  • ng build --prod(запускается в командной строке, когда каталог есть projectFolder)

    Пометить prodкомплект для производства (см. документацию Angular для списка опций, включенных в производственный флаг).

  • Сжатие с использованием Brotli, сжатие ресурсов с помощью следующей команды

    for i in dist/*; do brotli $i; done

пакеты по умолчанию генерируются в projectFolder / dist (/ $ projectFolder для 6)

Вывод

Размеры с Angular 9.0.0с CLI 9.0.1и опцией CSS без угловой маршрутизации

  • dist/main-[es-version].[hash].jsВаше приложение в комплекте [размер ES5: 158 КБ для нового приложения Angular CLI пусто, сжато 40 КБ ].
  • dist/polyfill-[es-version].[hash].bundle.jsсвязанные с полифиллом зависимости (@angular, RxJS ...) [размер ES5: 127 КБ для нового приложения Angular CLI пусто, 37 КБ сжато].
  • dist/index.html точка входа вашего приложения.
  • dist/runtime-[es-version].[hash].bundle.js веб-загрузчик
  • dist/style.[hash].bundle.css определения стиля
  • dist/assets ресурсы, скопированные из конфигурации ресурсов Angular CLI

развертывание

Вы можете получить предварительный просмотр вашего приложения с помощью ng serve --prodкоманды, которая запускает локальный HTTP-сервер, чтобы приложение с рабочими файлами было доступно по адресу http: // localhost: 4200 .

Для производственного использования вы должны развернуть все файлы из distпапки на HTTP-сервере по вашему выбору.

Николя Хено
источник
Я получил ошибку при запуске npm install -g angular-cli @ webpack: npm ERR! Пожалуйста, включите следующий файл с любым запросом поддержки: .... \ npm-debug.log. Вы знаете, что происходит?
Чонг Ван
2
@chrismarx производит только один пакет, включающий все компоненты с их HTML и стилями.
Николя Хено
4
У меня было приложение, и я хотел использовать этот метод, поэтому я запускаю ng init из папки проекта. Я выполнил оставшиеся шаги, но когда я развернул свои приложения, он кажется пустым. Единственное, что появляется, это "приложение работает!" сообщение, есть ли какое-то место, где я должен установить, где взять файлы моего приложения?
Маутрок
2
ng-init был удален из углового списка. github.com/angular/angular-cli/issues/5176
Пэт М
2
Я наконец отметил это как принятый ответ. Хотя другие решения могут также работать и даже обеспечивать некоторую дополнительную гибкость (я написал одно об использовании Webpack без CLI). Использование Angular CLI определенно дает меньше головной боли. В итоге я использовал Angular CLI и адаптировал свой проект, чтобы мне было проще использовать AoT.
Пэт М
57

2.0.1 Final используя Gulp (TypeScript - Target: ES5)


Настройка OneTime

  • npm install (запускается в cmd, когда direcory является projectFolder)

Шаги объединения

  • npm run bundle (запускается в cmd, когда direcory является projectFolder)

    пакеты генерируются в projectFolder / bundles /

Вывод

  • bundles/dependencies.bundle.js[ размер: ~ 1 МБ (как можно меньше)]
    • содержит rxjs и угловые зависимости, а не целые рамки
  • bundles/app.bundle.js[ размер: зависит от вашего проекта , мой ~ 0,5 МБ ]
    • содержит ваш проект

Файловая структура

  • projectFolder / app / (все компоненты, директивы, шаблоны и т. д.)
  • projectFolder / gulpfile.js

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);
    });
});
  • projectFolder / package.json (аналогично руководству по быстрому запуску, только что показаны devDependencies и npm-скрипты, необходимые для комплектации)

{
  "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"
  }
}
  • projectFolder / systemjs.config.js (так же, как руководство по быстрому запуску , там больше нет)

(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);
  • projetcFolder / dist-systemjs.config.js (только что показано отличие от systemjs.config.json)

var map = {
    'app':                        'dist/app',
  };
  • projectFolder / index.html (production) - Порядок тегов скрипта имеет решающее значение. Размещение dist-systemjs.config.jsтега после тегов комплекта по-прежнему позволяет программе запускаться, но комплект зависимостей будет игнорироваться и зависимости будут загружаться из node_modulesпапки.

<!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>
  • projectFolder / app / boot.ts - это место, где находится начальная загрузка .

Лучшее, что я мог сделать еще :)

Анкит Сингх
источник
2
Привет, скрипт gulp создает пакеты, но я не уверен, что должно быть в файле boot.ts? Разве не все файлы сейчас в комплекте? Выполняем ли мы комплект?
Крисмаркс
2
Я думаю, мне нужно попробовать еще раз. Я попытался переключиться на builder.buildStatic и получил ошибки от rxjs о том, что я не загружен как модуль commonjs или amd. Я дам вашему предложению еще одну попытку
chrismarx
1
Мне также непонятно, как на самом деле используются связки в этой настройке? Кажется, я сталкиваюсь с теми же проблемами, что и @chrismarx. Я могу создать пакеты, но затем кажется, что все еще загружается из моей перенесенной и скопированной папки приложения (расположенной в dist / app). Если я загляну в свою сетевую панель, то увижу, что файлы, связанные с моим приложением, на самом деле загружаются оттуда (компоненты и т. Д.), А не все, что связано с приложением, из app.bundle.js. A_Singh, вы можете поделиться своими boot.ts? Кажется, я что-то здесь упускаю и хотел бы получить разъяснения
Jbgarr
1
A_Singh, я не понимаю, как это помогает. При inline-templatesзапуске он вставляет шаблоны, а затем создает копию всех папок и файлов приложения в dist/app. Тогда в dist-systemjs.config.jsсопоставлении appс dist/appкоторой находится папка , в которой не будет существовать , если вы используете distпапку в корневом каталоге. Разве вы не хотите запускать свое приложение из distпапки? И если это так, у вас не будет distпапки, вложенной в корневую distпапку. Должно быть, я что-то здесь упускаю. Вам не нужно указывать systemjs использовать ваши связанные файлы, а не обычные файлы, найденные в dist/appпапке?
Jbgarr
1
Я столкнулся с проблемой с вашим решением, загрузка - это то, чего здесь не существует, и когда я заменяю его "app", я ошибаюсь, "модуль не определен".
LoïcR
22

Angular 2 с Webpack (без настройки CLI)

1- Учебник от команды Angular2

Команда Angular2 опубликовала руководство по использованию Webpack

Я создал и поместил файлы из учебника в небольшой начальный проект GitHub . Таким образом, вы можете быстро попробовать рабочий процесс.

Инструкции :

  • установка npm

  • нпм начало . Для разработки. Это создаст виртуальную папку «dist», которая будет загружена в реальном времени по адресу вашего локального хоста.

  • npm запустить сборку . Для производства. «Это создаст физическую версию папки« dist », которую можно отправить на веб-сервер. Папка dist имеет размер 7,8 МБ, но для загрузки страницы в веб-браузер требуется всего 234 КБ».

2 - Стартовый комплект Webkit

Этот стартовый комплект Webpack предлагает больше возможностей для тестирования, чем приведенный выше учебник, и кажется довольно популярным.

Пэт М
источник
Привет, можно ли обновить проект seed с угловой версии 2.1.0? Учебник использует угловой 2.1.0 сейчас. Я следовал за этим и не мог заставить это работать. Ошибка http 404 - не удается найти app.component.html.
heq99
Я обновил до угловой 2.1.0 без проблем. app.component.html вызывается из app.component.ts (templateUrl: './app.component.html'). у вас есть оба файла в одной папке приложения?
Пэт М
1
Тряска деревьев, минификация и сжатие могут значительно уменьшить размер, когда вы идете на производство. Вот отличное прочтение с примером, blog.mgechev.com/2016/06/26/…
Хамзин Хамим
16

Рабочий процесс Angular 2 с помощью SystemJs builder и gulp

У Angular.io есть краткое руководство. Я скопировал этот учебник и расширил его несколькими простыми задачами для объединения всего в папку dist, которую можно скопировать на сервер и работать точно так же. Я попытался оптимизировать все, чтобы хорошо работать на Jenkis CI, поэтому node_modules можно кэшировать и не нужно копировать.

Исходный код с примером приложения на Github: https://github.com/Anjmao/angular2-production-workflow

Шаги к производству
  1. Чистые машинописные скрипты скомпилированные js файлы и папка dist
  2. Скомпилируйте машинописные файлы в папке приложения
  3. Используйте SystemJs bundler, чтобы связать все в папку dist с сгенерированными хешами для обновления кэша браузера.
  4. Используйте gulp-html-replace для замены сценариев index.html на связанные версии и копирование в папку dist
  5. Скопируйте все в папке активов в папку dist

Узел : Хотя вы всегда можете создать свой собственный процесс сборки, но я настоятельно рекомендую использовать angular-cli, потому что у него есть все необходимые рабочие процессы, и он отлично работает сейчас. Мы уже используем его в производстве и не имеем никаких проблем с angular-cli.

Анджей Мациусович
источник
Это то, что я ищу. Пример приложения на github очень полезен. Спасибо
Шахриар Хасан Сайид
14

Angular CLI 1.xx (работает с Angular 4.xx, 5.xx)

Это поддерживает:

  • Угловые 2.х и 4.х
  • Последний Webpack 2.x
  • Угловой компилятор AoT
  • Маршрутизация (нормальная и ленивая)
  • SCSS
  • Пользовательский пакет файлов (активы)
  • Дополнительные инструменты разработки (линтер, юнит и сквозные тестовые настройки)

Начальная настройка

ng новое имя проекта - маршрутизация

Вы можете добавить --style=scssподдержку SASS .scss.

Вы можете добавить --ng4для использования Angular 4 вместо Angular 2.

После создания проекта CLI автоматически запустится npm installдля вас. Если вы хотите использовать вместо этого Yarn или просто хотите посмотреть на скелет проекта без установки, проверьте, как это сделать, здесь .

Bundle Steps

Внутри папки проекта:

ng build -prod

В текущей версии вам нужно указать --aotвручную, потому что это может быть использовано в режиме разработки (хотя это не практично из-за медлительности).

Это также выполняет компиляцию AoT для еще меньших пакетов (без углового компилятора, вместо этого генерируется вывод компилятора). Пакеты намного меньше с AoT, если вы используете Angular 4, так как сгенерированный код меньше.
Вы можете протестировать свое приложение с AoT в режиме разработки (исходные карты, без минификации) и AoT, запустивng build --aot .

Вывод

Выходной каталог по умолчанию - это ./dist, хотя его можно изменить в ./angular-cli.json.

Развертываемые файлы

Результатом шага сборки является следующее:

(Примечание: <content-hash>относится к хешу / отпечатку пальца содержимого файла, предназначенного для очистки кеша, это возможно, поскольку Webpack сам пишет scriptтеги)

  • ./dist/assets
    Файлы скопированы как есть ./src/assets/**
  • ./dist/index.html
    От ./src/index.html, после добавления сценариев webpack к нему,
    файл исходного кода настраивается в./angular-cli.json
  • ./dist/inline.js
    Небольшой погрузчик для веб-пакетов / с полифилом
  • ./dist/main.<content-hash>.bundle.js
    Основной файл .js, содержащий все созданные и импортированные скрипты .js.
  • ./dist/styles.<content-hash>.bundle.js
    Когда вы используете загрузчики Webpack для CSS, что является способом CLI, они загружаются через JS здесь

В более старых версиях он также создавал gzip-версии для проверки их размера и .mapфайлы исходных карт, но этого больше не происходит, так как люди постоянно просили их удалить.

Другие файлы

В некоторых других случаях вы можете найти другие нежелательные файлы / папки:

  • ./out-tsc/
    Из ./src/tsconfig.jsonoutDir
  • ./out-tsc-e2e/
    Из ./e2e/tsconfig.jsonoutDir
  • ./dist/ngfactory/
    Из компилятора AoT (не настраивается без разветвления CLI начиная с бета-версии 16)
Meligy
источник
Можно ли отделить угловую библиотеку и их зависимости от моего приложения?
Доминик Пиганелл
Не используется интерфейс командной строки, который специально предназначен для работы в виде тряски деревьев. Это удаляет все модули Angular EcmaScript, которые не используются в вашем приложении. Есть план отключить это в режиме разработки для скорости (они вызывают библиотеки, загруженные как «DLL»), но не планируют разделять в конечном результате. Это должно быть достижимо, если вы катите свой собственный материал Webpack, хотя и без CLI.
Meligy
Как проверить мое приложение, используя папку dist. Как я могу разместить на своем веб-сервере?
Радж м
Вы просто копируете это на сервер. Это простой статический сайт, который можно обслуживать в любом случае. Если вы используете маршрутизацию, вы, возможно, захотите перенаправить все вызовы в HTML-файл, хотя для этой проверки Angular docss развертывания в разделе конфигурации сервера angular.io/docs/ts/latest/guide/…
Meligy
@Meligy, что если я удалю <content-hash>из комплекта в prod. это может вызвать проблемы при получении последней комплектации?
k11k2
5

На сегодняшний день я все еще нахожу кулинарную книгу с опережением времени как лучший рецепт для комплектации. Вы можете найти его здесь: https://angular.io/docs/ts/latest/cookbook/aot-compiler.html

До сих пор мой опыт работы с Angular 2 заключался в том, что AoT создает самые маленькие сборки практически без времени загрузки. И самое главное, поскольку вопрос здесь о - вам нужно только отправить несколько файлов в производство.

Похоже, это связано с тем, что компилятор Angular не будет поставляться с производственными сборками, поскольку шаблоны компилируются «впереди времени». Также очень здорово видеть, как разметка вашего HTML-шаблона преобразована в инструкции javascript, которые было бы очень трудно преобразовать в исходный HTML-код.

Я сделал простое видео, где демонстрирую размер загрузки, количество файлов и т. Д. Для приложения Angular 2 в сборке dev против AoT - вы можете увидеть здесь:

https://youtu.be/ZoZDCgQwnmQ

Вы найдете исходный код, используемый в видео здесь:

https://github.com/fintechneo/angular2-templates

Питер Саломонсен
источник
3
        **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.
Тушар Тибуде
источник
2

Вы можете развернуть ваше угловое приложение, githubиспользуя angular-cli-ghpages

Проверьте ссылку, чтобы найти, как развернуть с помощью этого Cli.

развернутый сайт будет храниться в какой - либо ветви в githubтипично

GH-страница

use может клонировать ветку git и использовать ее как статический сайт на вашем сервере

Сунил Кумар
источник
1

«Лучший» зависит от сценария. Есть моменты, когда вы заботитесь только о наименьшем возможном единственном пакете, но в больших приложениях вам может потребоваться отложенная загрузка. В какой-то момент становится нецелесообразным обслуживать все приложение как единый пакет.

В последнем случае Webpack, как правило, лучший способ, так как он поддерживает разбиение кода.

Для одного пакета я бы рассмотрел Rollup или компилятор Closure, если вы чувствуете себя смелым :-)

Я создал образцы всех угловых пакетов, которые я когда-либо использовал здесь: http://www.syntaxsuccess.com/viewarticle/angular-production-builds

Код можно найти здесь: https://github.com/thelgevold/angular-2-samples

Угловая версия: 4.1.x

TGH
источник
0

Просто установите angular 4 с помощью webpack 3 в течение одной минуты, и ваш комплект ENV для разработки и производства будет готов без каких-либо проблем, просто следуйте приведенному ниже документу github.

https://github.com/roshan3133/angular2-webpack-starter

AniketGole
источник
0

Пожалуйста, попробуйте команду CLI ниже в текущем каталоге проекта. Это создаст пакет папок dist. так что вы можете загрузить все файлы в папке dist для развертывания.

ng build --prod --aot --base-href.

Нагнат Мунгаде
источник
0

ng serve работает для обслуживания нашего приложения в целях разработки. Как насчет производства? Если мы посмотрим на наш файл package.json, то увидим, что есть сценарии, которые мы можем использовать:

"scripts": {
  "ng": "ng",
  "start": "ng serve",
  "build": "ng build --prod",
  "test": "ng test",
  "lint": "ng lint",
  "e2e": "ng e2e"
},

Сценарий сборки использует сборку Angular CLI ng с флагом --prod. Давайте попробуем это сейчас. Мы можем сделать это одним из двух способов:

# используя сценарии npm

npm run build

# используя cli напрямую

ng build --prod

На этот раз нам дается четыре файла вместо пяти. Флаг --prod указывает Angular, чтобы сделать наше приложение намного меньше по размеру.

Йогеш Вагмаре
источник