Webpack/Browserify and UI-Router - angularjs

I can't seem to get Webpack or Browserify to work with UI-Router. Can anybody help?
Here is my module file:
"use strict";
require("angular");
angular
.module("app", [require("angular-ui-router")])
.config(require("./app.routes"));
And my file for the routes:
"use strict";
module.exports = function($urlRouteProvider, $stateProvider) {
$urlRouteProvider.otherwise("/state1");
$stateProvider
.state("state1", {
url: "/state1",
templateUrl: "partials/state1.html"
})
.state("state2", {
url: "/state2",
templateUrl: "partials/state2.html"
});
}

So sadly when you combine bower and the angularjs dependency injection system, quite frequently a component won't use the same bower package name as it's angular module name. This is completely annoying and frustrating, but it is sadly quite common. In this case, the bower component named "angular-ui-router" declares itself with angular module name "ui.router", which is also what it exports in commonjs. So:
In your package.json "browser" section, configure it like this:
"ui.router": "./bower_components/angular-ui-router/release/angular-ui-router.js",
Then in your browser code, you can both require it (so browserify includes it in your bundle) and inject it into your angular app at the same time (this is a bit advanced/confusing, but it happens to be supported by this particular module, whereas most angular js add-ons in bower don't have any support for commonjs baked in).
angular.module("app", [require("ui.router")]);

If you want to use bower with webpack, you need a line like this: https://github.com/jeffling/angular-webpack-example/blob/master/template/webpack.config.coffee#L83
This will teach webpack to read the main property in bower.json files. This works for angular-ui-router - I use it on our projects.

Related

Webpack plugins and/or strategies for AngularJS

I have an AngularJS 1.7 project currently being built with Gulp, and I'm looking into switching it over to Webpack. After some initial poking around, I'm finding it difficult to find and load all the source files, due to the fact that it's written in a style from before CommonJS and ES6 modules. My hunch is that it's a common (but old) style of Angular, but I'm new to it so I'm not sure.
The Question: Is there a Webpack plugin or tool or strategy for building Angular 1 projects? I'm hoping there's a plugin that is smart enough to pull in all the template files, controllers, directives, services, and so forth without needing to do a lot of configuration.
Specifically, I'm looking for "Use this 1 tool that's exactly what you need", as opposed to "Follow these 20 steps". It's not that I'm lazy, just that I'm confident I can figure out all the required steps, but before I go that route I want to make sure I'm not missing some plugin that does it all for me. And, I don't want to waste anyone else's time writing up the steps.
Reference Info
File Structure
- src
- components
- hometile
-- hometile.css
-- hometile.drct.js
-- hometile.tpl.html
- services
- capabilities.fct.js
Note the way the templates are put in the same directory as the component controller.
Here's a snippet from the routes file showing how a template is referenced:
app.routes.js
$routeProvider.
when('/home', {
templateUrl: 'sections/home/home.tpl.html',
controller: 'HomeController as home',
resolve: {
commonData: function(MyService) {
return MyService.getCommonData();
}
}
})
Note the use of templateUrl and it's a string path. The actual file is a template, and as far as I can tell, the existing Gulp builder uses a glob to find all the .tpl templates and then sends them to nghtml2js to combine into a single .js
I'm hoping there's something similar that's been written for Webpack that takes a standard Angular 1 project structure and builds all the required outputs.
I'm not sure it's really the full answer, but the import-glob npm package made a big difference. I was able to create a single import.js that then imports everything I need.
import.js
import './services/**/*.js';
import './directives/**/*.js';
import './controllers/**/*.js';
I'm also updating it a little with regards to importing the templates:
import template from './sections/home/home.tpl.html';
$routeProvider.
when('/home', {
templateUrl: template,
controller: 'HomeController as home',
resolve: {
commonData: function(MyService) {
return MyService.getCommonData();
}
}
})
By importing everything this way, Webpack is able to find all the source files.

AngularJS: Using $routeProvider with multiple modules?

I am building an angular app with multiple modules. Each module is a view component (rather than having one giant module with all the view components) as recommended by John Papa's Angular style guide. However, whereas previously I could just do...
angular.module('app').config( <config for all client routes and their controllers> )
I've realized that I can't do this since controllers are on separate modules now. So, I've split off the $routeProvider login into their respective files:
angular.module('app.<modulename>').config( <config for app.modulename routes and its controllers> );
However, when I navigate to any route not defined on my app module, I see an empty page, so it seems the $routeProvider for other modules doesn't seem to be working. How do I make multiple modules share the ng-view?
In order for your modules to be configured, you need to include them in the main application module via the dependency array. For example, say you have the following modules...
angular.module('app.module1', ['ngRoute'])
.config(function($routeProvider) { ... })
angular.module('app.module2', ['ngRoute'])
.config(function($routeProvider) { ... })
You configure and include them via
angular.module('app', ['app.module1', 'app.module2'])

AngularJS app.module vs app.route

I read this article about best practices for AngularJS project structure:
https://scotch.io/tutorials/angularjs-best-practices-directory-structure
Under the title "App Folder" he explains shortly the difference between the files app.module.js and app.route.js but I didn't understand.
Can anyone give me an example with a short pseudo code for both of the files?
Any help will be profoundly appreciated!
Under this structure, app.module.js would be used to create the main module for your application (eg. App), configure services that you are using throughout your application, or for running arbitrary code once the module has loaded all of its dependencies and configured any services it may wish to configure.
app.route.js would be for specifically configuring one service: the router that you are using to handle state in your application. It could create its own module or re-use the one from app.module.js, but if it were to use a custom module, it would have to depend on your choice of router directly. In addition, you would have to add it as a dependency for the main app.module.js eg.
angular.module('App', ['App.Routes']);
angular.module('App.Routes', ['RouterModule']);
Example using just one module named App, which also depends on some other arbitrary module SomeModule and the routing module RouterModule:
app.module.js
angular.module('App', ['SomeModule', 'RouterModule'])
.config(function (SomeServiceProvider, SomeOtherServiceProvider) {
// Configure SomeServiceProvider/SomeOtherServiceProvider.
})
.run(function () {
console.log('Done loading dependencies and configuring module!');
});
app.route.js
angular.module('App')
.config(function (YourRouterProvider) {
// Configure YourRouterProvider to define the states for the application.
});
Angular Modules:
https://docs.angularjs.org/api/ng/function/angular.module
Routing in Angular using ngRouter:
https://docs.angularjs.org/api/ngRoute

angular-route dependency not requiring

With the new angular-route version, you need to require('angular-route') in your dependencies but I can't seem to get this working. In the angular-route npm page, it says to do angular.module('myApp', [require('angular-route')]);
This is my code:
angular.module('app.routes', [require('angular-route')])
.config(function($routeProvider, $locationProvider){
$routeProvider
.when('/', {
templateUrl: 'app/views/pages/home.html'
});
$locationProvider.html5Mode(true);
});
When I run my server, I get the error: require is not defined.
Can anyone help me here.
You need to use browserify if you want to use require in frontend.
Browserify is a node module that takes your main JavaScript file, read all its required dependencies (and dependencies of dependencies), and spits out a single JavaScript file, ready to be included in your HTML. This file contains JavaScript code that is actually compatible with browsers, in other words, it browserfies your Node modules.
Also you can see the following link how he structure the angular js with browserify
http://omarfouad.com/blog/2015/03/21/advanced-angularjs-structure-with-gulp-node-and-browserify/
Other wise you need to use the following code snippet.
angular.module('app.routes', ['ngRoute']);
You should use the dependency injection as normally:
angular.module('app.routes', ['angular-route']);
Remember that you need to load the angular-route module before you load your app.js.
require is from requirejs

Getting Angularjs with Requirejs working with restangular and twitter bootstrap

I am building a new angularjs app and want to use requirejs to manage my dependencies. I am struggling to get this to work and wonder if I'm just misunderstanding something. I also want to use twitter bootstrap and restangular to make restful calls. Trying to set this up leads to errors of not being able to find it. My main,js config is as follows:
require.config({
paths: {
angular: '../vendor/angular',
twitterbootstrap: '../vendor/bootstrap/ui-bootstrap-tpls-0.6.0',
restangular: '../vendor/restangular',
domReady: '../vendor/domReady'
},
shim: {
angular : {'exports' : 'angular'},
restangular: {
deps: ['underscore']
}
}
});
require([
'angular',
'app',
'domReady',
'twitterbootstrap',
//'underscore',
'restangular',
],
function (angular, app, domReady) {}...
I am getting errors with this:
angular is not defined
no module myApp
no module twitterbootstrap
I have tried several variations with this but just can't get it to play nicely together. Is there something else I'm missing - I've compared it to several examples and everything seems to be in order.
Mixing Angular and Require is tricky. I have an experimental project in GitHub (https://github.com/nikospara/angular-require-lazy) that works in some hacky way. You may take a look as an example.
Opinions comments on this project are also wellcome.
For your errors:
Open a net console (e.g. in Firebug) and check the paths called by RequireJS. Are these paths correct?
Angular modules (in contrast to Require/AMD modules) have dependencies of their own. You must make sure that .js files of Angular modules are loaded after angular. One way to do that is to shim them, e.g. for restangular it would be something like:
shim: {
...
restangular: {
deps: ["underscore", "angular"]
}
}
Otherwise you can load angular and the other scripts with standard <script> tags, in the correct order.
These are general directions. If you can't find the reason of the problems, maybe you should post some more code; a fiddle/plunkr would also be great, if possible.
Related post in SO: Inject module dynamically, only if required

Resources