Постройте Angular2 HTML и TypeScript в один файл

Я собираю приложение (крупномасштабное) с помощью Angular2 и TypeScript. Его нужно будет разделить на многочисленные проекты, и каждый проект будет иметь множество компонентов, каждый из которых имеет вид .html, .css таблица стилей и .ts логика/класс.

Я хотел бы, чтобы каждый проект компилировался в один файл *.js и копировался на веб-узел хоста, который будет работать в IIS. Это будет похоже на то, как приложение WPF или Silverlight построено с файлами .xaml, все из которых скомпилированы в .dll.

Я просмотрел веб-сайт и могу получить файлы .ts для сборки в один файл .js с помощью параметра --outFile. Но это не помогает мне с файлами .html или css.

Любая помощь будет принята с благодарностью, даже если она скажет, что то, что я прошу, невозможно: -)

Стивен

Ответ 1

Если вы используете по умолчанию Angular2 tsconfig.json с загрузчиком SystemJS:

"module": "system",
"moduleResolution": "node",
...

Вы можете оставить всю тяжелую работу в SystemJS Build Tool. Это, например, то, как я делаю это в своих проектах, используя gulp:

  • Компилировать *.ts и inline *.html шаблоны

    Я использую gulp-angular-embed-templates, чтобы вставить все templateUrl в строки template (этот плагин работает как с Angular 1. *, так и с Angular 2).

    var tsc = require('gulp-typescript');
    var tsProject = tsc.createProject('tsconfig.json');
    var embedTemplates = require('gulp-angular-embed-templates');
    
    gulp.task('app.build', function () {
        var tsResult = gulp.src('app/src/**/*.ts', {base: './app/src'})
            .pipe(embedTemplates()) // inline templates
            .pipe(tsc(tsProject));
    
        return tsResult.js
            .pipe(gulp.dest('build/js'));
    });
    

    Это создаст много анонимных модулей System.register в каталоге build/js. У всех из них уже будет свой templateUrl.

  • Объединить все в один файл .js

    Я использую SystemJS Build Tool для этого, потому что я думаю, что это проще, чем использование, например, webpack. Итак, у меня есть еще одна задача gulp для автоматизации процесса:

    var SystemBuilder = require('systemjs-builder');
    
    gulp.task('app.systemjs.bundle', function () {
        var builder = new SystemBuilder('build/js, {
            paths: {
                '*': '*.js'
            },
            meta: {
                'angular2/*': {
                    build: false
                },
                'rxjs/*': {
                    build: false
                }
            }
        });
    
        return builder.bundle('main', 'build/js/app.bundle.js');
    });
    

    Конструктор принимает те же параметры, что и SystemJS, поэтому проверьте их API конфигурации.

    Вызов builder.bundle('main', ...) выполняет поиск main.js (это мой первоначальный вызов script с вызовом Angular bootstrap). В тот же файл вы видите за 5 минут quickstart), потому что я добавляю .js ко всем путям, найденным конструктором. Это связано с тем, что при импорте модуля в TS вы обычно вызываете:

    import {ModalResultComponent} from './modal-result.component';
    

    который скомпилирован как зависимость ./modal-result.component, и он не заботится о расширении файла. Вот почему мне пришлось добавить *.js ко всем путям, чтобы помочь строителю найти все скомпилированные файлы JavaScript.

    Параметры meta просто говорят строителю игнорировать зависимости, которые я не хочу связывать. Это Angular2 сама и rxjs библиотека, потому что я включаю import 'rxjs/add/operator/map' в main.ts.

    Это создает один файл app.bundle.js со всеми модулями, зарегистрированными как именованные модули, используя System.register.

  • Используя наш app.bundle.js

    Последняя часть - кусок пирога. Мы просто импортируем материал по умолчанию Angular2, а затем используем bundle вариант, чтобы сообщить SystemJS, где все наши зависимости.

    <script>
    System.config({
        packages: {
            '/web': {
                format: 'register',
                defaultExtension: 'js'
            }
        },
        bundles: {
            '/web/app.bundle': ['main']
        }
    });
    System.import('main').then(null, console.error.bind(console));
    </script>
    

    Когда мы вызываем System.import('main'), он фактически загружает файлы /web/app.bundle.js и регистрирует все модули в пакете, а затем импортирует модули main с нашей начальной загрузкой Angular2.

    И что это!

Вам вообще не нужно использовать gulp вообще и делать все с чистым node script.

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

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

Я уверен, что вы могли бы использовать также, например, формат commonjs, но для этого потребовалось бы также использовать некоторый загрузчик polyfill для require(), но я еще не пробовал его. Я считаю, что UMD также стоит попробовать.