Мы находимся в процессе обновления приложения 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"
]
}