利用browserify与requirejs构建ng项目

简介:

随着业务的增长,利用ng来构建项目时候,文件数量就会显著的上升,从而上线部署的时候就要考虑压缩合并问题,随着前端工程化的发展,现在已经有很多种第三方工具来实现开发与部署的便捷性,browserifyrequirejs就是其中的两个比较好多的工具.


  • browserify以commonjs模块开发规范来约束前端模块开发,最后上线时提供命令行生成合并文件,详情请 点击这里
  • requirejs以amd模块开发规范来约束前端模块开发,最后上线的时候提供r.js命令行工具来生成合并压缩文件,详情请 点击这里

一个普通的ng例子

下面先提供一个原生的ng例子,只显示核心的代码

// 核心文件 app.js

(function () {

      var app = angular.module('myApp', ['ngRoute']);

      // 下面这个需要依赖angular-route模块
      app.config(['$routeProvider', function ($routeProvider) {
            $routeProvider.when('/home',
            {
              templateUrl: 'partials/home.html',
              controller: 'HomeController'
            })
            .otherwise(
            {
              redirectTo: '/home'
            })
      }]);

      app.controller('HomeController', ['$scope', 'usersService', function($scope, usersService){
            $scope.title = 'Home';
            $scope.users = usersService.getData();
      }]);

      app.factory('usersService', function () {
            var service = {
              getData: function(){
                return [{name: 'feenan', info: 'fe'}, {name: 'tina', info: 'financy'}];
              }
            }
            return service;
      });

}());

browserify 构建ng

下面以browserify的模块开发规范来重构上面的例子,项目结构大概这样:

  • app
    • lib 这个下面存放第三方js库,例如jquery,angularjs
    • partials
      • home.html
    • controllers
      • homeController.js
    • services
      • usersService.js
    • app.js
  • index.html

homeController.js

module.exports = function ($scope, usersService) {

    $scope.title = 'Home';
    $scope.users = usersService.getData();

};

usersService.js

module.exports = function () {
    var service = {
      getData: function(){
        return [{name: 'feenan', info: 'fe'}, {name: 'tina', info: 'financy'}];
      }
    }
    return service;
}

app.js

// 加载所有的依赖
window.jQuery = require('./lib/jquery/jquery.min');
require('./lib/angular/angular.min');
require('./lib/angular-route/angular-route.min');

// 获取控制器与服务的依赖
var homeController = require('./controllers/homeController');
var usersService = require('./services/usersService');

// module up
var app = angular.module('app', [ 'ngRoute']);

// routes and such
app.config(['$routeProvider', function($routeProvider) {
  $routeProvider
    .when('/home',
    {
      templateUrl: 'partials/home.html',
      controller: 'HomeController'
    })
    .otherwise(
    {
      redirectTo: '/home'
    });
}]);

// create factories
app.factory('usersService', usersService);

// create controllers
app.controller('HomeController', ['$scope', 'usersService', homeController]);

然后我们用browserify来生成最终index.html引用的文件名,先cdapp目录

browserify app.js -o main.js

最后我们来看看index.html代码

<!doctype html>
<html lang="en" ng-app="myApp" >
<head>
    <meta charset="utf-8">
</head>
<body>
    <div ng-view></div>

    <script src="app/main.js"></script>
</body>
</html>

可以看到最终的页面里只需要引用一个js文件就可以了,这就是神奇的地方,因为browserify编译文件时候已经加载了一套自己的模块处理方案,有兴趣的话可以自己写个简单的项目分析下编译后的js文件

requirejs 构建ng

下面我们来用requirejs来重构上面的例子,大概的目录结构如下:

  • app
    • partials
      • home.html
    • controllers
      • index.js // 包括所有的 控制器的入口
      • module.js // 创建控制器模块
      • homeController.js services
      • index.js // 同控制器
      • modules.js
      • userService.js
    • app.js // 创建ng主模块的地方
    • main.js // requirejs配置文件地方
    • routes.js // 配置路由的地方

下面我们一一来创建这些文件,静态页文件除外

先说说requirejs配置文件

main.js

require.config({
  paths: {
    'jquery': './lib/jquery/jquery.min',
    'angular': './lib/angular/angular.min',
    'angular-route': './lib/angular/angular-route.min',
    'app': 'app'
  },
  shim: {
    'angular-route': {
        deps: ['angular']
    },
    'app': {
        deps: ['jquery', 'angular', 'angular-route']
    }
  }
});

define(['./routes'], function () {

  // 启动ng
  angular.bootstrap(document, ['app']);

});

上面的define的时候依赖了routes文件

routes.js

define([
  './app'
], function (app) {
  // 通过返回app主模块来定义配置
  return app.config(['$routeProvider', function ($routeProvider) {
    $routeProvider
      .when('/home',
        {
          templateUrl: '/app/partials/home.html',
          controller: 'homeController'
        })
      .otherwise(
        {
          redirectTo: '/home'
        });

  }]);
});

上面的路由文件依赖app.js

app.js

define([
  './controllers/index',
  './services/index'
], function (controllers, index) {

  // 因为主模块依赖控制器与服务模块
  // 上面的两个index 依赖分别为控制器与服务模块的两个入口
  return angular.module('app', [
    'ngRoute',
    'app.controllers',
    'app.services'
  ]);
});

下面先看看控制器的入口文件

controllers/index.js

define([
  './homeController'
], function () {
    // 此处为空,这个文件主要是控制当控制器比较多时可以多加载完毕
});

再来看看控制器代码

controllers/homeController.js

define([
  './module'
], function (module) {

  module.controller('homeController', ['$scope', 'userService',
    function ($scope, userService) {
      $scope.title = 'Home';
      $scope.users = userService.getData();
    };
  );

});

下面来看看控制器主模块

controllers/module.js

define(function () {

  return angular.module('app.controllers', []);

});

上面定义了控制器模块,以后新增的控制器都由它来定义

然后service的代码跟控制器思路差不多,这里就不一一定义了.

最后总结下这些依赖关系

  • “main.js” requires “routes.js”
    • “routes.js” requires “app.js”
      • “app.js” requires “controllers/index.js”
        • “controllers/index.js” requires all controllers
          • all controllers require “module.js”

从上面的依赖关系可以看到,当所有的控制器与服务都加载完毕,然后创建ng主模块,加载路由配置信息,最后调用启动方法.

关于requirejs的代码优化可以用它提供的r.js来合并压缩上面定义的文件最后合成一个文件来运行.

总结

通过上面的比较可以看出,requirejs比较适合大型ng项目开发,browserify在小型项目上要更适合,因为它比较轻量,而且commonjs规范可以保证相同的功能在前后端通用.

本文参考了此篇文章: Requiring vs Browserifying Angular


目录
相关文章
|
监控 前端开发 JavaScript
从0到1搭建前端异常监控系统(Vue + Webpack + Node.js + Egg.js + Jest)(上)
从0到1搭建前端异常监控系统(Vue + Webpack + Node.js + Egg.js + Jest)
579 0
|
12天前
|
JavaScript 前端开发
构建工具:配置Webpack打包Vue项目
【4月更文挑战第24天】本文介绍了如何配置Webpack来打包Vue项目。首先,Webpack作为模块打包器处理依赖并打包成可执行文件。接着,通过安装Node.js和npm,创建Vue项目,进入项目目录并配置Webpack的入口、输出、加载器和插件。最后,运行构建命令完成打包。理解Webpack基础并按需配置,能优化前端项目构建和开发体验。
|
10月前
|
Web App开发 前端开发 JavaScript
UMD 被淘汰了吗?不考虑的 UMD 的库如何在纯 UMD 前端项目中运行?
UMD 被淘汰了吗?不考虑的 UMD 的库如何在纯 UMD 前端项目中运行?
144 0
|
前端开发
lerna.js:monorepos项目管理模式简单实践
lerna.js:monorepos项目管理模式简单实践
71 0
|
关系型数据库 MySQL 数据库连接
Koa的上层框架egg.js的学习
Koa的上层框架egg.js的学习
|
JavaScript 数据安全/隐私保护
为了深入学习JS我写了一个JS工具库 | 从零到一发布到npm上(1)
自从工作以来,写项目的时候经常需要手写一些方法和引入一些js库 JS基础又十分重要,于是就萌生出自己创建一个JS工具库并发布到npm上的想法 于是就创建了一个名为learnjts的项目,在空余时间也写了几个工具函数,后续还会再继续增加... 这篇文章就是一篇实战文章,我把自己创建项目,发布到npm,以及遇到的问题和解决方案全都记录了下来,如果你也想创建一个自己的js工具库,可以根据这篇文章一步一步的尝试一下
117 0
为了深入学习JS我写了一个JS工具库 | 从零到一发布到npm上(1)
|
JavaScript 前端开发 测试技术
为了深入学习JS我写了一个JS工具库 | 从零到一发布到npm上(2)
为了深入学习JS我写了一个JS工具库 | 从零到一发布到npm上(2)
133 0
为了深入学习JS我写了一个JS工具库 | 从零到一发布到npm上(2)
|
前端开发 测试技术 开发工具
使用rush.js管理monorepo
使用rush.js管理monorepo
579 0
使用rush.js管理monorepo
|
存储 JSON 缓存
Ember.js 项目开发之 Ember Data
Ember.js 是一个基于MVVM模型的开源框架,该框架主要用于创建复杂的多页面应用程序。它最大的特点是:持续推出最新的特性,并不会丢弃任何旧功能。
120 0
Ember.js 项目开发之 Ember Data