I am creating a POC from an Angular 1 + 2 hybrid application. I managed to run it, and now I'm trying to introduce Webpack.
I get the error Error: AngularJS v1.x is not loaded!
when loading the module. I checked - when initializing the module, Angular loads.
Any help would be appreciated.
Record File:
import { downgradeInjectable, downgradeComponent } from '@angular/upgrade/static'; import { BrowserModule } from '@angular/platform-browser'; import {NgModule} from '@angular/core'; import {HelloAngular2} from './components/hello-angular2'; import {TimeZonesService} from './services/timezones'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { UpgradeModule } from '@angular/upgrade/static'; import * as angular from 'angular'; angular.module('scotchTodo', []); angular.module('scotchTodo').directive('helloAngular2', downgradeComponent({ component: HelloAngular2})); angular.module('scotchTodo').factory('timeZones', downgradeInjectable(TimeZonesService)); @NgModule({ declarations: [HelloAngular2], entryComponents: [HelloAngular2], imports: [BrowserModule, UpgradeModule], providers: [TimeZonesService] }) class MyNg2Module { ngDoBootstrap() {}; } platformBrowserDynamic().bootstrapModule(MyNg2Module).then(platformRef => { const upgrade = platformRef.injector.get(UpgradeModule) as UpgradeModule; upgrade.bootstrap(document.documentElement, ['scotchTodo']); });
Webpack configuration:
var webpack = require('webpack'), path = require('path'), ExtractTextPlugin = require('extract-text-webpack-plugin'); var config = { entry: { app: __dirname + '/public/js/boot.js' }, output: { path: __dirname + '/public/dist', filename: 'app-loader.js' }, resolve:{ extensions: ['.js'], alias: { 'controllers/main.js': 'controllers/main.js', 'services/todos.js':'services/todos.js' } } }; module.exports = config;
tsconfig.json:
{ "compilerOptions": { "target": "es5", "module": "commonjs", "moduleResolution": "node", "sourceMap": true, "emitDecoratorMetadata": true, "experimentalDecorators": true, "removeComments": false, "noImplicitAny": false }, "exclude": [ "node_modules", "public/jslibs", "typings/main", "typings/main.d.ts" ] }
Generated part of Bootstrap with Angular:
angular.module('scotchTodo', []); angular.module('scotchTodo').directive('helloAngular2', static_1.downgradeComponent({ component: hello_angular2_1.HelloAngular2 })); angular.module('scotchTodo').factory('timeZones', static_1.downgradeInjectable(timezones_1.TimeZonesService)); var MyNg2Module = (function () { function MyNg2Module() { } MyNg2Module.prototype.ngDoBootstrap = function () { }; ; return MyNg2Module; }()); MyNg2Module = __decorate([ core_1.NgModule({ declarations: [hello_angular2_1.HelloAngular2], entryComponents: [hello_angular2_1.HelloAngular2], imports: [platform_browser_1.BrowserModule, static_2.UpgradeModule], providers: [timezones_1.TimeZonesService] }) ], MyNg2Module); platform_browser_dynamic_1.platformBrowserDynamic().bootstrapModule(MyNg2Module).then(function (platformRef) { var upgrade = platformRef.injector.get(static_2.UpgradeModule); upgrade.bootstrap(document.documentElement, ['scotchTodo']); });
- UPDATE -
After adding ProvidePlugin with this configuration:
new webpack.ProvidePlugin ({'angular': 'angular'})
Error Error: AngularJS v1.x is not loaded!
, which, I believe, emerged from the Upgrade module, disappeared. Now Angular is undefined in angular.module
because Angular is imported __webpack_require__
- UPDATE 2 -
The problem seems to be that AngularJS does not support the CommonJS style module.exports. I am trying to use exports-loader
, but now it does not work. Configuration:
loaders: [ { test: /[\/]angular\.js$/, loader: "exports-loader?angular" } ]
- UPDATE 3 -
After adding module.exports = windows.angular;
There is no error with the generated bootstrap file. But the application still does not work, because there is no resumeBootstrap
function for Angular.
- UPDATE 4 -
Here is the main HTML page:
<body ng-controller="mainController"> <div class="container"> <div class="jumbotron text-center"> <h1>I'm a Todo-aholic <span class="label label-info">{{ todos.length }}</span></h1> </div> <div id="todo-list" class="row"> <div class="col-sm-4 col-sm-offset-4"> <div class="checkbox" ng-repeat="todo in todos"> <label> <input type="checkbox" ng-click="deleteTodo(todo._id)"> {{ todo.text }} </label> </div> <p class="text-center" ng-show="loading"> <span class="fa fa-spinner fa-spin fa-3x"></span> </p> </div> </div> <div id="todo-form" class="row"> <div class="col-sm-8 col-sm-offset-2 text-center"> <form> <div class="form-group"> <input type="text" class="form-control input-lg text-center" placeholder="I want to buy a puppy that will love me forever" ng-model="formData.text"> </div> <button type="submit" class="btn btn-primary btn-lg" ng-click="createTodo()">Add</button> </form> </div> </div> <div class="text-center text-muted"> <p>A demo by <a href="http://scotch.io">Scotch</a>.</p> <p>Read the <a href="http://scotch.io/tutorials/javascript/creating-a-single-page-todo-app-with-node-and-angular">tutorial</a>.</p> </div> </div>
- UPDATE -
setting window.name = "NG_DEFER_BOOTSTRAP!";
helps Angular for init resumeBootstrap
init resumeBootstrap
, but application still not working