我们正在使用增量方法将 AngularJS 应用程序升级到 Angular:我们希望能够在 Angular 中创建新组件并逐个升级现有的 AngularJS 组件,在此过程中所有这些仍然具有功能性应用程序。
我们使用官方文档以及关于现实世界应用程序中混合 Angular/AngularJS 应用程序的几篇文章。
这是我们的尝试和我们得到的错误。
语境
- AngularJS 1.7.3
- 角 6.1.7
- 打字稿 2.7.2
- 角-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 全局角度(如果我们删除require("angular")) -脚本模式
在 .ts 文件中:我们不能使用import from angular,否则我们会得到错误
angular.module is undefined
-模块模式
考虑到这一点,我们使应用程序在浏览器中编译和加载没有错误,但最后:
this.upgrade.bootstrap(document.body, [App])
在 AngularJS 引导时生成错误:
Angular 1.x not loaded !
如何解决这个问题?可能是因为我们没有以 TypeScript 模块的方式导入 AngularJS 来避免之前的错误?
官方文档提到了 angular.IAngularStatic(还是报错)?
我们也可以试试setAngularJSGlobal()吗?Used when AngularJS is loaded lazily, and not available on window
顺便说一句,调用 bootstrap() 时使用 [App] 或 ["App"] 有什么区别?
...由于我们是这个升级过程的新手,我们可能会做完全错误的事情。感谢您分享您的经验!
配置文件
角.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"
]
}