AngularJS- 使用 LazyLoad- Webpack 动态加载脚本文件
Posted
技术标签:
【中文标题】AngularJS- 使用 LazyLoad- Webpack 动态加载脚本文件【英文标题】:AngularJS- Dynamic Loading of script files using LazyLoad- Webpack 【发布时间】:2017-03-31 07:55:16 【问题描述】:现在在我的index.html
页面中,我有两个 CDN 文件的链接,一个是 JS,另一个是 CSS 文件。
即 在我的身体底部
https://somedomain.com/files/js/js.min.js
在头脑中
https://somedomain.com/files/css/css.min.css
但是现在我的主页上不需要它们,而只是在一个特定的路线上。因此,我正在研究如何在路由被击中时延迟加载这些 CDN 资源,即/profile
,然后才可以?
这些不是通过 bower 或 npm 安装的,而是通过 CDN url 加载的,例如 jquery。如何在 Angular 1 和 Webpack 中基于路由延迟加载?
【问题讨论】:
通过一条特定路线它指的是什么? Angular 有路由,即 /profile。配置文件有一个单独的模块、控制器、视图等我只想在用户导航到该特定路线时加载上述库。 $ocLazyLoad 效果很好 $ocLazyLoad 示例应用freakyjolly.com/how-to-lazy-load-modules-controllers-angularjs 【参考方案1】:我有这个JStaticLoader repo,方便我在需要时加载静态文件。虽然它没有角化,但您仍然可以在您的应用程序中将其用作directive
,直接从您的controller
甚至在$rootScope
中调用它以加载您想要的js
。
JStaticLoader
使用纯js,不需要依赖。它使用XMLHttpRequest
加载静态文件。
例如在您的app.js
中使用(在$routeChangeStart
或$stateChangeStart
)
myApp
.run(['$rootScope', '$http', function ($rootScope, $http)
var scriptExists = function (scriptId)
if (document.getElementById(scriptId))
return true;
return false;
;
var addLazyScript = function (scriptId, url)
if (scriptExists(scriptId)) return;
var js = document.createElement('script'),
els = document.getElementsByTagName('script')[0];
js.id = scriptId;
js.src = url;
js.type = "text/javascript";
els.parentNode.insertBefore(js, els);
;
$rootScope.$on('$routeChangeStart', function (e, current)
if (current.controller === 'MainCtrl')
var pathUrls = ["https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.8/js/materialize.js"],
scriptId = 'lazyScript1';
if (scriptExists(scriptId)) return;
JStaticLoader(pathUrls, files: ['js'] , function (vals, totalTime)
/* Success */
for (var i = 0; i < vals.length; i++)
var path = vals[i];
addLazyScript(scriptId, path);
, function (error, totalTime)
/* Error */
console.warn(error, totalTime);
);
);
]);
在上面的示例中,我使用 xhr 获得了一个 js
文件,并在完成后将其作为 script
附加到我的 document
中。然后将从浏览器的缓存中加载脚本。
【讨论】:
XMLHttpRequest 不是外部库。它实际上是内置的,可以得到developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest。通过您自己实现它,您的意思是......在不使用 XMLHttpRequest 的情况下实现 ajax?很抱歉直言不讳,但是……真是个糟糕的主意! @FélixGagnon-Grenier 我不是说 XHR 是外部库.. 但是,JStaticLoader
是..
... 我一定被这句话误导了:“它使用 XMLHttpRequest 来加载它们。所以,如果你不想为此使用外部库,你可以实现它你” 起初(实际上,很多人后来也读过)并且没有周围的上下文,这完全意味着 XMLHttpRequest 是一个外部库,如果你不想使用它们,你应该实现你自己的.也许只是删除关于 XHR 的那部分,只说 JStaticLoader 是,如果你想避免使用外部库,你应该自己实现它。
考虑一下,这意味着您也可以完全删除它,因为重点是提供答案,而不是告诉操作他们可以自己实现它... :)【参考方案2】:
给你.. 使用 oclazyload 使之成为可能。看看下面的代码。下面链接的一个plunker
我有一个名为 myApp 的模块,如下所示
angular.module('myApp', ['ui.router','oc.lazyLoad'])
.config(function ($stateProvider, $locationProvider, $ocLazyLoadProvider)
$stateProvider
.state("home",
url: "/home",
templateUrl: "Home.html",
controller: 'homeCtrl',
resolve:
loadMyCtrl: ['$ocLazyLoad', function ($ocLazyLoad)
return $ocLazyLoad.load('homeCtrl.js');
]
)
.state("profile",
url:"/profile",
templateUrl: "profile.html",
resolve:
loadMyCtrl: ['$ocLazyLoad', function ($ocLazyLoad)
return $ocLazyLoad.load('someModule.js');
]
)
);
我有另一个名为 someApp 的模块,如下所示
(function ()
var mynewapp=angular.module('someApp',['myApp']);
mynewapp.config(function()
//your code to route from here!
);
mynewapp.controller("profileCtrl", function ($scope)
console.log("reached profile controller");
);
)();
我有一个 Live Plunker 用于您的演示 here
【讨论】:
【参考方案3】:严格来说是 Webpack -
Webpack 只是一个模块捆绑器,而不是一个 javascript 加载器。因为它仅从本地存储打包文件,而不从 web 加载文件(除了它自己的块)。尽管可能包含其他模块进入可能执行相同过程的 webpack。
我将只演示一些您可以尝试的模块,因为网上已经定义了很多这样的模块。
因此,从另一个域延迟加载 cdn 的更好方法是使用 javascript 加载器 - script.js
可以通过以下方式加载——
var $script = require("script.js");
$script = ("https://somedomain.com/files/js/js.min.js or https://somedomain.com/files/css/css.min.css",function()
//.... is ready now
);
这是可能的,因为 script-loader 只是在全局上下文中评估 javascript。
参考here
关于延迟加载cdn到angular app的问题
以下库Lab JS 是专门为此目的而制作的。 使用这个库加载和阻止 javascript 变得非常简单。
这里有一个例子来演示
<script src="LAB.js"></script>
<script>
$LAB
.script("/local/init.js").wait(function()
waitfunction();
);
<script>
或
您可以使用require.js
这里是一个加载 jquery 的例子
require.config(
paths:
"jquery": "https://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min"
,
waitSeconds: 40
);
您还应该考虑this 文章中的以下段落。
异步加载第三方脚本是获得高性能网页的关键,但这些脚本仍然会阻止 onload。花时间分析您的网络性能数据,并了解这些不那么重要的内容/小部件/广告/跟踪代码是否以及如何影响页面加载时间。
【讨论】:
以上是关于AngularJS- 使用 LazyLoad- Webpack 动态加载脚本文件的主要内容,如果未能解决你的问题,请参考以下文章