Обновление до гибридного приложения Angular / AngularJS: получение ошибок машинописного текста / ошибок импорта AngularJS

Мы находимся в процессе обновления приложения AngularJS до Angular с инкрементным подходом: мы хотели бы иметь возможность создавать новые компоненты в Angular и обновлять существующие компоненты AngularJS один за другим, все это по-прежнему с функциональным приложением в процессе.

Мы используем официальную документацию, а также несколько статей о гибридных приложениях Angular / AngularJS в реальных приложениях.

Вот наши попытки и ошибки, которые мы получаем.

Контекст

  • AngularJS 1.7.3
  • Угловой 6.1.7
  • Машинопись 2.7.2
  • angular-cli

Первые шаги

  • перейти на AngularJS 1.7
  • удалите Grunt и используйте angular-cli
  • используйте ngUpgrade (app.module.ts и app.module.ajs.ts)

Переход на Typscript: устранение ошибок

Это официальный процесс: переименовать файлы .js в .ts.

Затем мы перешли от Node require () к загрузке модуля TypeScript (var ... = require -> import ... = require)

В идеале мы должны исправить все опечатки из-за использования компилятора TypeScript.

Но в документе TypeScript говорится, что можно сделать добавочный миграция: быть толерантным к ошибкам TypeScript вначале, чтобы скомпилировать js-код без изменений (и более строгим позже, после исправления кода).

Для этого мы использовали awesome-typescript-loader вместо tsc, чтобы получить следующие параметры: transpileOnly, errorsAsWarnings (для этого требуется использование angular-builders / custom-webpack).

Параметры позволяют пройти компиляцию, но оказывается, что компиляция выполняется дважды: сначала без ошибок (с предупреждениями или без), а затем с ошибками ... поэтому сборка завершается неудачей. Как мы можем запустить только первую компиляцию?


Альтернативная попытка: сохранение файлов .js, ошибки при импорте и загрузке

Мы также попробовали неофициальный и необычный способ постепенной миграции кода js, то есть сохранение исходных файлов .js вместе с новыми файлами .ts.

У нас возникли ошибки при компиляции или загрузке приложения, связанные с импортом AngularJS и управлением модулями. Действительно, в документации модуля TypsScript говорится, что:

Some libraries are designed to be used in many module loaders, or with no module loading (global variables). These are known as UMD modules. These libraries can be accessed through either an import or a global variable. ... can be used as a global variable, but only inside of a script. (A script is a file with no imports or exports.)

Что мы заметили:

  • в файлах .js: доступ к AngularJS global angular (если мы удалим require ("angular")) - режим скрипта < / сильный>

  • в файлах .ts: мы не можем использовать импорт из angular, иначе мы получим ошибку angular.module is undefined - режим модуля

Имея это в виду, мы заставили приложение компилироваться и загружаться в браузере без ошибок, но в итоге:

this.upgrade.bootstrap (document.body, [Приложение])

генерирует ошибку при загрузке AngularJS:

Angular 1.x not loaded !

Как это исправить? Это может быть потому, что мы не импортировали AngularJS в модуле TypeScript, чтобы избежать предыдущей ошибки?

В официальной документации упоминается angular.IAngularStatic (по-прежнему возникает ошибка)?

Мы также можем попробовать setAngularJSGlobal ()? Used when AngularJS is loaded lazily, and not available on window

Кстати, в чем разница между использованием [App] или ["App"] при вызове bootstrap ()?

... Поскольку мы новички в этом процессе обновления, мы можем делать совершенно неправильные вещи. Спасибо, что поделились своим опытом!


Файлы конфигурации

angular.json

{
    "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
    "version": 1,
    "newProjectRoot": "acd-banner-multicanal",
    "projects": {
        "acd-banner-multicanal": {
            "root": "",
            "sourceRoot": "src",
            "projectType": "application",
            "architect": {
                "build": {
                    "builder": "@angular-devkit/build-angular:browser",
                    "options": {
                        "outputPath": "target",
                        "index": "src/index.html",
                        "main": "src/main.ts",
                        "tsConfig": "./tsconfig.json",
                        "assets": [
                            "src/i18n",
                            "src/conf/conf.txt",
                            "src/conf/conf_DEFAULT.txt",
                            "src/systemjs.config.js",
                            { "glob": "font-banner*", "input": "./node_modules/elq-font-icon/build/", "output": "/assets/fonts" },
                            "src/assets/images",
                            { "glob": "system.js*", "input": "./node_modules/systemjs/dist/", "output": "/assets" },
                            "src/assets/images",
                            { "glob": "**/*", "input": "./node_modules/tinymce/plugins", "output": "/assets/tinymce/plugins" },
                            { "glob": "**/*", "input": "./node_modules/tinymce/skins", "output": "/assets/tinymce/skins" }

                        ],
                        "styles": [
                            "src/assets/styles/style.less"
                        ],
                        "scripts": [
                            "./node_modules/jquery/dist/jquery.js",
                            "./node_modules/jquery-ui-dist/jquery-ui.js"
                        ]
                    },
                    "configurations": {
                        "production": {
                            "fileReplacements": [
                                {
                                    "replace": "src/environments/environment.ts",
                                    "with": "src/environments/environment.prod.ts"
                                }
                            ],
                            "optimization": true,
                            "aot": true,
                            "buildOptimizer": true
                        }
                    }
                },
                "test": {
                    "builder": "@angular-devkit/build-angular:karma",
                    "options": {
                        "main": "src/test.ts",
                        "polyfills": "src/polyfills.ts",
                        "tsConfig": "src/tsconfig.spec.json",
                        "karmaConfig": "./karma.conf.js",
                        "scripts": [],
                        "styles": [
                            "src/assets/main.less"
                        ],
                        "assets": [
                            "src/i18n",
                            "src/favicon.ico"
                        ]
                    }
                },
                "lint": {
                    "builder": "@angular-devkit/build-angular:tslint",
                    "options": {
                        "tsConfig": [
                            "tsconfig.json",
                            "src/tsconfig.spec.json"
                        ],
                        "exclude": [
                            "**/node_modules/**"
                        ]
                    }
                }
            }
        },
        "acd-ihm-angular-e2e": {
            "root": "e2e/",
            "sourceRoot": "e2e",
            "projectType": "application",
        }
    },
    "defaultProject": "acd-banner-multicanal",
    "schematics": {
        "@schematics/angular:component": {
            "styleext": "less",
            "lintFix": true
        }
    }
}

tsconfig.json

{
    "compilerOptions": {
        "target": "es5",
        "module": "commonjs",
        "moduleResolution": "node",
        "outDir": "./target",
        "sourceMap": true,
        "experimentalDecorators": true,
        "allowJs": true,
        "baseUrl": "./",
        "lib": [
            "es2017",
            "dom"
        ],
        "noImplicitAny": true,
        "suppressImplicitAnyIndexErrors": true,
        "paths": {
            "angular": ["node_modules/angular/angular"]
        }
    },
    "include": [
        "src/**/*"
    ],
    "exclude": [
                "src/**/*.spec.ts"
    ]
}

person Emmanuel    schedule 21.02.2019    source источник


Ответы (2)


Что касается ошибки angular 1.x not loaded; Вы установили angularJS в новом приложении?

$ npm install --save [email protected] \
      @types/angular

В angular.json файл нужно включить скрипт:

"scripts": [
    "../node_modules/angular/angular.js",
    //etc...
],

Здесь - это пример обновления приложения, которое кажется похожим на то, что у вас есть.

В качестве альтернативы вы можете добавить angular в цепочку импорта, импортировав его в main.ts;

import * as angular from 'angular';

Это может быть лучшим вариантом, поскольку он заставляет angular cli / webpack знать об angularJS и может предотвратить такие ошибки, как "WARNING: Tried to Load Angular More Than Once", которые могут возникнуть, если какой-либо другой компонент (например, гибридный маршрутизатор импортирует angular).

person DaggeJ    schedule 28.02.2019
comment
Действительно, добавление angular.js к angular.json исправляет ошибки angular undefined и Angular 1.x not loaded. Я собираюсь продолжить процесс, спасибо. - person Emmanuel; 01.03.2019

Подтверждаю, что ответ работает, мы смогли запустить наше приложение в гибридном режиме. Фактически, в AngularJs мы использовали grunt и browserify, и мы упаковали некоторые библиотеки с использованием поля package.json browser. Чтобы сделать то же самое, нам пришлось объявить библиотеки для загрузки в браузере в angular.js / build.options.scripts:

"scripts": [
    "./node_modules/jquery/dist/jquery.js",
    "./node_modules/jquery-ui-dist/jquery-ui.js",
    "./node_modules/moment/moment.js",
    "./node_modules/bootstrap/dist/js/bootstrap.js",
    "./node_modules/eonasdan-bootstrap-datetimepicker/src/js/bootstrap- datetimepicker.js",
    "./node_modules/bootstrap-tour/build/js/bootstrap-tour.js",
    "./node_modules/angular/angular.js",
    "./node_modules/ng-table/bundles/ng-table.js"`
]

Большое спасибо.

Что может быть полезно добавить в документацию по Angular? Действительно, примеры, приведенные в https://angular.io/guide/upgrade#bootstrapping-hybrid-applications основаны на SystemJS, тогда как мы просто используем Webpack (уже используемый Angular).

Действительно, есть проблема с угловым документом, документ миграции еще не обновлен. для angular-cli (поэтому речь идет о SystemJS).

person Emmanuel    schedule 03.05.2019