【发布时间】:2019-07-15 09:30:45
【问题描述】:
我们正在使用增量方法将 AngularJS 应用程序升级到 Angular:我们希望能够在 Angular 中创建新组件并逐个升级现有的 AngularJS 组件,所有这些在过程。
我们使用official documentation 以及几篇关于现实世界应用程序中混合 Angular/AngularJS 应用程序的文章。
这是我们的尝试和我们得到的错误。
上下文
- AngularJS 1.7.3
- Angular 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 doc 声明可以进行增量迁移:在开始时容忍 TypeScript 错误,以便在不修改的情况下编译 js 代码(在修复代码)。
为了实现这一点,我们使用 awesome-typescript-loader 而不是 tsc 来获取这些选项:transpileOnly、errorsAsWarnings(这需要angular-builders/custom-webpack)的使用。
选项允许通过编译,但似乎编译完成了两次:第一次没有错误(警告与否),但第二次有错误......所以构建失败。我们怎样才能只运行第一次编译?
替代尝试:保留 .js 文件,导入和引导时出错
我们还尝试了一种非官方且不寻常的方式来增量迁移 js 代码,即将原始 .js 文件与新的 .ts 文件一起保留。
我们在编译或应用程序加载时遇到了一些错误,这些错误与导入 AngularJS 和模块管理有关。事实上,TypsScript module documentation 声明:
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 全局 angular(如果我们删除 require("angular")) - 脚本模式
-
在 .ts 文件中:我们不能使用 import from angular,否则我们会收到错误
angular.module is undefined- module mode
考虑到这一点,我们使应用程序在浏览器中编译和加载没有错误,但最后:
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"] 有什么区别?
...由于我们是这个升级过程的新手,我们可能会做完全错误的事情。感谢您分享您的经验!
配置文件
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"
]
}
【问题讨论】:
标签: angularjs angular typescript upgrade angular-hybrid