原文 http://www.startersquad.com/blog/angularjs-requirejs/

AngularJS + RequireJS

  • Dmitry Evseev
  • September 19, 2013
  • 13 Comments

While delivering software projects for startups, we’ve come to love AngularJS. We’ve also come to struggle with clean modularity, both the parts that Angular does really well, and the parts that are somewhat missing. RequireJS does a great job where Angular leaves some things to be desired, but using them together is not entirely trivial. What follows is our take at the problem.

Why?

Working with Angular you could worry about a good way to organize code. There are already great how-tos on that, check out this mainly theoretical post by Brian Ford and this practical guide by Cliff Meyers if you haven’t already. I’ll share the way I’m managing code in Angular applications with RequireJS.

Continue reading if you want to:

  • stop worrying about including script tags in the right order when building Angular apps;
  • to load your javascript asynchronously;
  • to compile code into single minified js file;

Who?

I assume that you already know what AngularJS is and that you’ve at least heard of AMD and RequireJS. To illustrate the approach I’ll first enable RequireJS for Angular Seed and explain process. Angular Seed structures code by splitting files by type and so will I. It’s also possible to apply this approach if you write modules by entities (you’ll see it from app.controllersmodule implementation).

How?

Angular Seed Project

Let’s check how Angular Seed structures code. Check out the example in your browser or on github (copied from Seed):

  • app.js file to bootstrap and set app config;
  • actual implementation files – controllers, services, directives and filters;
  • index.html with all script tags included in right order;
  • or index-async.html that makes use of angular-loader.js and 3-rd party$script loader library to load dependencies asyncronously.

Let’s start the party.

Add RequireJS

Checkout the example in your browser or on github.

Installing dependencies

I used bower to do this for me. See bower.json file:

{"name": "AngularJS + RequireJS Example","version": "0.1","main": "index.html","ignore": ["**/.*","libs"],"dependencies": {"angular": "latest","requirejs": "latest","requirejs-domready": "latest"}
}

Put the .bowerrc file next to bower.json, run bower install and – poof, we have all we need under libs folder.

index.html

Destruction is a good start. Open Angular Seed’s index.html and remove all the <script> tags. Looks cleaner, doesn’t it? Now switch to creation mode and add single script before closing </body> that will load RequireJS and instruct it to look for config in js/main.js with the data-main attribute:

<!doctype html>
<html lang="en">
<head><meta charset="utf-8"><title>My AngularJS AngularJS + RequireJS App</title><link rel="stylesheet" href="css/app.css">
</head>
<body><ul class="menu"><li><a href="#/view1">view1</a></li><li><a href="#/view2">view2</a></li></ul><div data-ng-view></div><div>Angular Require seed app: v<span app-version></span></div><script src="lib/requirejs/require.js" data-main="js/main.js"></script>
</body>
</html>

That’s all there’s to it. You can close index.html now, as there is nothing more we need to add to it.

main.js

Time to setup RequireJS config.

require.config({// alias libraries pathspaths: {'domReady': '../lib/requirejs-domready/domReady','angular': '../lib/angular/angular'},// angular does not support AMD out of the box, put it in a shimshim: {'angular': {exports: 'angular'}},// kick start applicationdeps: ['./bootstrap']
});

What just happened? In paths we set aliases for the libraries and plugins used, then we defined that angular should be shimmed and that bootstrap.jsshould be loaded to start the application.

bootstrap.js

We’re bootstrapping angular manually now, that’s what bootstrap.js is for. Note that you don’t need ng-app in your html anymore. Also routes.js, which contains angular routes configuration is included into dependencies list.

Note that in this require module we almost have no use of asynchronous loading and we’ll always have chain of angular -> app -> routes, as they depend on each other: angular needs to be present on a page before setting up application module, which is required to exist when defining routes config.

/*** bootstraps angular onto the window.document node*/
define(['require','angular','app','routes'
], function (require, ng) {'use strict';require(['domReady!'], function (document) {ng.bootstrap(document, ['app']);});
});

We use domReady RequireJS plugin to make sure that DOM is ready when we start the app. Note that before doing so we’re loading the app.js dependency, in there the main application is defined.

app.js

app.js wraps the definition of the top-level app module and loads the dependencies of its submodules.

define(['angular','./controllers/index','./directives/index','./filters/index','./services/index'
], function (ng) {'use strict';return ng.module('app', ['app.services','app.controllers','app.filters','app.directives']);
});

We agreed to have 4 modules by files types: controllers, directives, filters, services – we require these modules to be loaded before defining the main module.

routes.js

Top level routes definition lives here. It is also possible to have modules to set up their own routes (this case is omitted for now in favour of simplicity).

define(['./app'], function (app) {'use strict';return app.config(['$routeProvider', function ($routeProvider) {$routeProvider.when('/view1', {templateUrl: 'partials/partial1.html',controller: 'MyCtrl1'});$routeProvider.when('/view2', {templateUrl: 'partials/partial2.html',controller: 'MyCtrl2'});$routeProvider.otherwise({redirectTo: '/view1'});}]);
});

Module structure

A module consists of 3 parts:

  • definition;
  • component;
  • loader.

Let’s use the app.controllers module as example.

module definition (controllers/module.js)

It’s just like top level app.js: it defines a module.

define(['angular'], function (ng) {'use strict';return ng.module('app.controllers', []);
});

This file will be used by the module components to attach themselves to (see next section).

module loader (controllers/index.js)

That’s just an empty define block with all module components included. You don’t need to mention module.js here as it’s already required by components. Loader is included as dependency of top level app module. And that’s actually how RequireJS knows about files to load.

define(['./my-ctrl-1','./my-ctrl-2'
], function () {});

module components (controllers/my-ctrl-1.js)

In the case with the app.controllers module it’ll be controllers. Example of controller wrapped in define is:

define(['./module'], function (controllers) {'use strict';controllers.controller('MyCtrl1', [function ($scope) {}]);
});

Note that we used reference to ./module.js to attach component to its module.

Conclusion

That’s it. Now you have working Angular application powered by RequireJS. You can enjoy the power of not tracking the order of your scripts anymore and you get some powerful minification tooling to boot.

In next articles I’ll show you how to test this application properly, how to compile it into single file and automate workflows with grunt. All this is already enabled in StarterSquad Angular + Require Seed check it out if you can’t wait (I’m a slow typist).

About StarterSquad

StarterSquad is a community of distributed development teams consisting of freelance developers. We specialize in startups and lean innovation. If you want to know more, read more about how we work and checkout our team.

AngularJS + RequireJS相关推荐

  1. AngularJS+RequireJs实现动态加载JS和页面的方案研究

    摘要:本文是笔者研究了几天的动态加载方案的成果,前台使用的是AngularJS+RequireJs+angular-ui-router+angularAMD.后台使用了SpringMVC+Spring ...

  2. 【开源】分享一个前后端分离方案-前端angularjs+requirejs+dhtmlx 后端asp.net webapi

    一.前言 半年前左右折腾了一个前后端分离的架子,这几天才想起来翻出来分享给大家.关于前后端分离这个话题大家也谈了很久了,希望我这个实践能对大家有点点帮助,演示和源码都贴在后面. 二.技术架构 这两年a ...

  3. AngularJS+RequireJS集成环境

    整个项目搭建流程   index开始页面  引入requireJS文件 和main.Js主要文件 <--index.html--> <div ui-view ></div ...

  4. AngularJS+RequireJs实现动态加载JS和页面的方案研究【上】

    1.入口页面 存放地址:src/main/webapp/WEB-INF/view/workflow/workflow.jsp [html] view plain copy 在CODE上查看代码片派生到 ...

  5. angularJS+requireJS实现controller及directive的按需加载

    最近因为项目的比较大,需要加载的js文件较多,为了提高首屏页面的加载速度,需要对js文件进行按需加载,然后网上参考了一些资料,自己也深入研究一番之后,实现了按需加载控制器js文件及指令js文件的效果: ...

  6. Angular项目构建指南 - 不再为angular构建而犹豫不决(转)

    如果你不知道什么是Angular或者根本没听说过,那么我接下来所说的对你来说毫无益处,不过如果你打算以后会接触Angular或者干脆要涨涨姿势~读下去还是有点用的. Angular和它之前所出现的其余 ...

  7. Angular项目构建指南 - 不再为angular构建而犹豫不决

    摘要: 洋洋洒洒写了一大堆都是最近构建项目的一些经验,对于angular项目的构建确实不大同于以往的前端框架,所以特此记录分享给大家,希望有所帮助. 前言 接触Angular也有小半个月了,虽然没有使 ...

  8. php 判断联通移动电信,JavaScript_JavaScript判断手机号运营商是移动、联通、电信还是其他(代码简单),正则表达式判断所填入号码的 - phpStudy...

    JavaScript判断手机号运营商是移动.联通.电信还是其他(代码简单) 正则表达式判断所填入号码的运营商js代码修改版:/article/31563.htm 在做WEB项目时,有时候需要根据用户的 ...

  9. 基于angularJS和requireJS的前端架构

    1.概要描述 1.1.angularJS描述:angularJS是可以用来构建WEB应用的,WEB应用中的一种端对端的完整解决方案.通过开发者呈现一个更高层次的抽象来简化应用的开发.最适合的就是用它来 ...

最新文章

  1. MDK编译后生成bin文件占用FLASH大小说明
  2. 【采用】【风控体系】携程基于大数据分析的实时风控体系
  3. 微信红包要哭了...给抢红包设计一个新交互
  4. qt5.9.0调试如何查看变量的值_深入了解 Java 调试
  5. H264 帧边界识别简介
  6. mac 安装memcached服务
  7. mescroll报错
  8. matlab识别水雷岩石,基于MATLAB的微弱信号检测方法仿真分析
  9. 设计模式 - 代理模式、委托模式
  10. 苹果新款耳机问题多 线上短暂销售仍被抢空
  11. python精灵和精灵组_Pygame精灵和精灵组
  12. 计算机根号的3次方怎么,excle 开几次方|excel中咋开3次根号啊
  13. 男士必须收藏:男士健身方案
  14. 光伏并网发电系统MATLAB Simulink仿真设计 该仿真包括电池,BOOST升压电路,单相全桥逆变电路
  15. 数控加工零件工艺性分析
  16. Simulink仿真示波器波形出现小圆圈
  17. 【DBC专题】-5-DBC文件格式解析
  18. ati linux驱动下载,安装 ATI 驱动 for linux
  19. 【转帖】2018年Windows漏洞年度盘点
  20. 巴黎综合理工大学计算机专业,巴黎综合理工大学

热门文章

  1. 使用开源实时监控系统 HertzBeat 5分钟搞定 Mysql 数据库监控告警
  2. DIV布局之道一:DIV块的水平并排、垂直并排
  3. 【OAuth2】三、OAuth2配置解读
  4. 使用最小二乘法和最大似然法估计非线性模型
  5. 知识图谱学习|报告总结|肖仰华: 知识图谱下半场-机遇与挑战
  6. 2014暑假集训总结
  7. 仙剑奇侠传四服务器维护,《仙剑奇侠传四》无法登录怎么办_无法登录解决办法_3DM手游...
  8. 猿创征文|从mysql 到kingbase(人大金仓)
  9. 红蓝对抗-红蓝对抗经验总结
  10. Java爬取王者荣耀全英雄全皮肤图片