• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com专业计算机教程网站
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • html/xhtml
  • html5
  • CSS
  • XML/XSLT
  • Dreamweaver教程
  • Frontpage教程
  • 心得技巧
  • bootstrap
  • vue
  • AngularJS
  • HBuilder教程
  • css3
  • 浏览器兼容
  • div/css
  • 网页编辑器
  • axure
您的位置:首页 > 网页设计 >AngularJS > Webpack 实现 AngularJS 的延迟加载

Webpack 实现 AngularJS 的延迟加载

作者:PasteBin of GC 字体:[增加 减小] 来源:互联网 时间:2017-05-30

本文主要包含Webpack 实现 AngularJS 的延迟加载等相关知识,PasteBin of GC 希望在学习及工作中可以帮助到您

随着你的单页应用扩大,其下载时间也越来越长。这对提高用户体验不会有好处(提示:但用户体验正是我们开发单页应用的原因)。更多的代码意味着更大的文件,直到代码压缩已经不能满足你的需求,你唯一能为你的用户做的就是不要再让他一次性下载整个应用。这时,延迟加载就派上用场了。不同于一次性下载所有文件,而是让用户只下载他现在需要的文件。

所以。如何让你的应用程序实现延迟加载?它基本上是分成两件事情。把你的模块拆分成小块,并实施一些机制,允许按需加载这些块。听起来似乎有很多工作量,不是吗?如果你使用 Webpack 的话,就不会这样。它支持开箱即用的代码分割特性。在这篇文章中我假定你熟悉 Webpack,但如果你不会的话,这里有一篇介绍 。为了长话短说,我们也将使用 AngularUI Router 和 ocLazyLoad 。

代码可以在 GitHub 上。你可以随时 fork 它。

Webpack 的配置

没什么特别的,真的。实际上从你可以直接从文档中复制然后粘贴,唯一的区别是采用了 ng-annotate ,以让我们的代码保持简洁,以及采用 babel 来使用一些 ECMAScript 2015 的魔法特性。如果你对 ES6 感兴趣,可以看看 这篇以前的帖子 。虽然这些东西都是非常棒的,但是它们都不是实现延迟加载所必需的东西。

// webpack.config.js
var config = {
entry: {
app: ['./src/core/bootstrap.js'],
},
output: {
path: __dirname + '/build/',
filename: 'bundle.js',
},
resolve: {
root: __dirname + '/src/',
},
module: {
noParse: [],
loaders: [
{ test: /\.js$/, exclude: /node_modules/,
loader: 'ng-annotate!babel' },
{ test: /\.html$/, loader: 'raw' },
]
}
};
module.exports = config;
</div>

应用

应用模块是主文件,它必须被包括在 bundle.js 内,这是在每一个页面上都需要强制下载的。正如你所看到的,我们不会加载任何复杂的东西,除了全局的依赖。不同于加载控制器,我们只加载路由配置。

// app.js
'use strict';
export default require('angular')
.module('lazyApp', [
require('angular-ui-router'),
require('oclazyload'),
require('./pages/home/home.routing').name,
require('./pages/messages/messages.routing').name,
]);
</div>

路由配置

所有的延迟加载都在路由配置中实现。正如我所说,我们正在使用 AngularUI Router ,因为我们需要实现嵌套视图。我们有几个使用案例。我们可以加载整个模块(包括子状态控制器)或每个 state 加载一个控制器(不去考虑对父级 state 的依赖)。

加载整个模块

当用户输入 /home 路径,浏览器就会下载 home 模块。它包括两个控制器,针对 home 和 home.about 这两个state。我们通过 state 的配置对象中的 resolve 属性就可以实现延迟加载。得益于 Webpack 的 require.ensure 方法,我们可以把 home 模块创建成第一个代码块。它就叫做 1.bundle.js 。如果没有 $ocLazyLoad.load ,我们会发现得到一个错误 Argument 'HomeController' is not a function, got undefined ,因为在 Angular 的设计中,启动应用之后再加载文件的方式是不可行的。 但是 $ocLazyLoad.load 使得我们可以在启动阶段注册一个模块,然后在它加载完之后再去使用它。

// home.routing.js
'use strict';
function homeRouting($urlRouterProvider, $stateProvider) {
$urlRouterProvider.otherwise('/home');
$stateProvider
.state('home', {
url: '/home',
template: require('./views/home.html'),
controller: 'HomeController as vm',
resolve: {
loadHomeController: ($q, $ocLazyLoad) => {
return $q((resolve) => {
require.ensure([], () => {
// load whole module
let module = require('./home');
$ocLazyLoad.load({name: 'home'});
resolve(module.controller);
});
});
}
}
}).state('home.about', {
url: '/about',
template: require('./views/home.about.html'),
controller: 'HomeAboutController as vm',
});
}
export default angular
.module('home.routing', [])
.config(homeRouting);
</div>

控制器被当作是模块的依赖。

// home.js
'use strict';
export default angular
.module('home', [
require('./controllers/home.controller').name,
require('./controllers/home.about.controller').name
]);
</div>

仅加载控制器

我们所做的是向前迈出的第一步,那么我们接着进行下一步。这一次,将没有大的模块,只有精简的控制器。

// messages.routing.js
'use strict';
function messagesRouting($stateProvider) {
$stateProvider
.state('messages', {
url: '/messages',
template: require('./views/messages.html'),
controller: 'MessagesController as vm',
resolve: {
loadMessagesController: ($q, $ocLazyLoad) => {
return $q((resolve) => {
require.ensure([], () => {
// load only controller module
let module = require('./controllers/messages.controller');
$ocLazyLoad.load({name: module.name});
resolve(module.controller);
})
});
}
}
}).state('messages.all', {
url: '/all',
template: require('./views/messages.all.html'),
controller: 'MessagesAllController as vm',
resolve: {
loadMessagesAllController: ($q, $ocLazyLoad) => {
return $q((resolve) => {
require.ensure([], () => {
// load only controller module
let module = require('./controllers/messages.all.controller');
$ocLazyLoad.load({name: module.name});
resolve(module.controller);
})
});
}
}
})
</div>

我相信在这里没有什么特别的,规则可以保持不变。

加载视图(Views)

现在,让我们暂时放开控制器而去关注一下视图。正如你可能已经注意到的,我们把视图嵌入到了路由配置里面。如果我们没有把里面所有的路由配置放进 bundle.js ,这就不会是一个问题,但现在我们需要这么做。这个案例不是要延迟加载路由配置而是视图,那么当我们使用 Webpack 来实现的时候,这会非常简单。

// messages.routing.js
...
.state('messages.new', {
url: '/new',
templateProvider: ($q) => {
return $q((resolve) => {
// lazy load the view
require.ensure([], () => resolve(require('./views/messages.new.html')));
});
},
controller: 'MessagesNewController as vm',
resolve: {
loadMessagesNewController: ($q, $ocLazyLoad) => {
return $q((resolve) => {
require.ensure([], () => {
// load only controller module
let module = require('./controllers/messages.new.controller');
$ocLazyLoad.load({name: module.name});
resolve(module.controller);
})
});
}
}
});
}
export default angular
.module('messages.routing', [])
.config(messagesRouting);
</div>

当心重复的依赖

让我们来看看 messages.all.controller 和 messages.new.controller 的内容。

// messages.all.controller.js
'use strict';
class MessagesAllController {
constructor(msgStore) {
this.msgs = msgStore.all();
}
}
export default angular
.module('messages.all.controller', [
require('commons/msg-store').name,
])
.controller('MessagesAllController', MessagesAllController);
// messages.all.controller.js
'use strict';
class MessagesNewController {
constructor(msgStore) {
this.text = '';
this._msgStore = msgStore;
}
create() {
this._msgStore.add(this.text);
this.text = '';
}
}
export default angular
.module('messages.new.controller', [
require('commons/msg-store').name,
])
.controller('MessagesNewController', MessagesNewController);
</div>

我们的问题的根源是 require('commons/msg-store').name 。它需要 msgStore 这一个服务,来实现控制器之间的消息共享。此服务在两个包中都存在。在 messages.all.controller 中有一个,在 messages.new.controller 中又有一个。现在,它已经没有任何优化的空间。如何解决呢?只需要把 msgStore 添加为应用模块的依赖。虽然这还不够完美,在大多数情况下,这已经足够了。

// app.js
'use strict';
export default require('angular')
.module('lazyApp', [
require('angu
  


 

您可能想查找下面的文章:

相关文章

  • 2017-05-30AngularJS使用ng-class动态增减class样式的方法示例
  • 2017-05-30AngularJS 模块详解及简单实例
  • 2017-05-30AngularJS变量及过滤器Filter用法分析
  • 2017-05-30AngularJS基础 ng-keydown 指令简单示例
  • 2017-05-30AngularJS动态菜单操作指令
  • 2017-05-30AngularJS基础 ng-mouseover 指令简单示例
  • 2017-05-30Angular2安装angular-cli
  • 2017-05-30详解Angular.js的$q.defer()服务异步处理
  • 2017-05-30AngularJS入门教程之AngularJS表达式
  • 2017-05-30angularjs中的$eval方法详解

文章分类

  • html/xhtml
  • html5
  • CSS
  • XML/XSLT
  • Dreamweaver教程
  • Frontpage教程
  • 心得技巧
  • bootstrap
  • vue
  • AngularJS
  • HBuilder教程
  • css3
  • 浏览器兼容
  • div/css
  • 网页编辑器
  • axure

最近更新的内容

    • AngularJS入门教程之表单校验用法示例
    • AngularJS基础 ng-mouseover 指令简单示例
    • 详解AngularJS中的表达式使用
    • 详解使用angular-cli发布i18n多国语言Angular应用
    • AngularJS学习笔记之基本指令(init、repeat)
    • AngularJs入门教程之环境搭建+创建应用示例
    • Angular2平滑升级到Angular4的步骤详解
    • AngularJS基于ngInfiniteScroll实现下拉滚动加载的方法
    • AngularJS ng-blur 指令详解及简单实例
    • 使用AngularJS制作一个简单的RSS阅读器的教程

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有