/app.js:
require('./messages'); angular.module('sling',['sling.messages']);
/messages/index.js:
exports = angular.module('sling.messages',[]) .controller('MessagesListCtrl',require('./MessagesListCtrl'));
/messages/MessagesListCtrl.js:
module.exports = function() { // ... });
当然这样做,但为什么要这样做?我已经执行了这样的工作,这个工作绝对不错,对于AngularJS项目感觉更加正常:
/app.js:
require('./messages'); angular.module('sling',['sling.messages']);
/messages/index.js:
angular.module('sling.messages',[]); require('./MessagesListCtrl');
/messages/MessagesListCtrl.js:
angular.module('sling.messages').controller('MessagesListCtrl',function() { // ... });
换句话说,我完全跳过exports / module.exports,只使用require来基本上包含带有控制器,服务,过滤器等的文件.
我这样做是对吗?我的意思是一切正常,但我以后会遇到麻烦吗?
所以一个’真正的’CommonJS模块看起来像这样.
文件A:
// a.js function doSomething() { console.log("I am doing something"); } module.exports = doSomething
文件B:
// b.js doSomething(); // Exception - attempt to call a non-existent function
文件C:
// c.js var doSomething = require('a'); doSomething(); // logs "I am doing something"
在没有模块范围的浏览器中,a.js将使用doSomething函数来扩充全局范围,因为它被声明为全局. Browserify通过将每个捆绑的模块包装到函数包装器中,并将“exports”对象提供给包含的模块作为此包装器的参数.
输入AngularJS.你有两种方法可以在这里使用,其中我假设你不使用require(‘angular’)是第一个:
>在您的Browserify-transpiled bundle脚本之前,将AngularJS作为index.html中的硬编码脚本.
> Shim AngularJS,以便它连接到导出对象而不是窗口(使用类似于browserify-shim),然后使用任何其他模块进行导入.
我倾向于喜欢第二种方法,因为使用Browserify给您模块范围是一件奇怪的事情,然后让您的项目的主要依赖关系是一个全局窗口.
然而,AngularJS已经有了自己的依赖注入驱动模块系统.当您声明angularJS组件时,您将它们附加到自身已连接到角度对象的模块对象.这意味着在角度的情况下,您的angularJS模块文件的导出对象基本上是多余的,因为只要执行文件,则角度对象将随模块和组件进行扩充.
您仍然需要“需要”文件,否则Browserify将不会捆绑它们,它们将永远不会执行,并且它们将永远不会增加您的模块的角度对象.但是您不需要为Angular的任何内容添加任何内容,因为角度对象是您的导出.
那么为什么我花这么多时间来解释CommonJS模块和出口的工作原理?因为希望您使用Browserify的其他原因是允许您使用浏览器应用程序中NPM上托管的模块.这些模块中的大多数都是非角度commonJS模块,意味着它们的功能通过导出来暴露.在这种情况下,重要的是要在需要时在变量中捕获他们的出口,例如我在上面的c.js中.同样,如果你写一些模块并将它们发布到NPM,那么你的用户将期望你将模块的入口点添加到你的package.json中被声明为main的文件的export对象.