I've been working on an AngularJS 1.7 application that's coded entirely in TypeScript, and there's always been one thing bothering me.
Within my app.module.ts file, I have this piece of code that doesn't sit right with me:
declare var angular;
This is necessary for the
this.app = angular.module('app'...
to transpile and function correctly.
I've experimented with a few solutions:
1) Switching out declare var angular;
with
import angular from "angular";
transpiles without issues, but then the browser throws an error:
Uncaught (in promise) TypeError: angular_1.default.module is not a function
2) Substituting declare var angular;
with
import * as angular from "angular";
also transpiles smoothly, but again, leads to a similar browser error:
Uncaught (in promise) TypeError: angular.module is not a function
3) Swapping declare var angular;
with
import ng from "angular";
and using ng.angular.module
or ng.module
fails to transpile altogether.
In the end, the only method that has worked for me is sticking with declare var angular;
While everything functions properly, it just doesn't feel quite right. Why is this step necessary? Am I missing something? Is there a cleaner approach?
Details:
- Utilizing Visual Studio 2017/2019
- TypeScript version 3.3
- SystemJS (not RequireJS)
- AngularJS version 1.7.8
- @types/angular version 1.6.54
package.json
"devDependencies": {
"@types/angular": "^1.6.54",
...
},
"dependencies": {
"angular": "~1.7.8",
...
}
tsconfig.json
{
"compileOnSave": true,
"compilerOptions": {
"baseUrl": ".",
"paths": {
"*": [ "node_modules/types/*", "node_modules/*" ],
},
"module": "system",
"target": "es6",
"sourceMap": true,
"lib": [ "es6", "dom" ],
"allowSyntheticDefaultImports": true,
"outFile": "./app/everything.js",
"moduleResolution": "node",
"types": [
"angular",
"jquery"
]
},
"include": ["app/**/*"],
"exclude": ["node_modules", "lib"],
"strict": true
}
app.module.ts
declare var angular;
...
export class App {
app: ng.IModule;
constructor() {
this.app = angular.module('app', [
...
]);
}
public run() {
this.app.run([
...
]);
...
}
index.html
...
<script src="lib/systemjs/system.js"></script>
<script src="lib/angular/angular.min.js" type="text/javascript"></script>
...
<script src="app/everything.js" type="text/javascript"></script>
<script>
System.config({
map: {
"angular": "lib/angular",
...
},
packages: {
"angular": { main: "angular.min.js", defaultExtension: "js" },
...
}
});
System.import("app.module")
.then(function (app) {
let a = new app.App();
a.run();
angular.element(function () {
angular.bootstrap(document, ['app']);
});
});
</script>