AngularJS - Динамическая загрузка файлов script с использованием LazyLoad-Webpack
Сейчас на моей странице 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 можно ленить нагрузку, основанную на маршруте?
Ответы
Ответ 1
Здесь вы идете.. Это стало возможным с помощью oclazyload. Посмотрите ниже код. Плункер, связанный ниже
У меня есть модуль, называемый 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 для вашей демонстрации здесь
Ответ 2
У меня есть 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);
});
}
});
}]);
В приведенном выше примере я получаю файл js
с помощью xhr и добавляю его как script
в мой document
после его завершения. script затем будет загружен из кеша браузера.
Ответ 3
Строго говоря о Webpack -
Webpack - это просто связка модулей, а не загрузчик javascript. Поскольку он упаковывает файлы только из локального хранилища и не загружает файлы из Интернета (кроме его собственных фрагментов). Хотя другие модули могут быть включены в веб-пакет, который может выполнять тот же процесс.
Я продемонстрирую только некоторые из модулей, которые вы можете попробовать, так как таких существует в Интернете.
Поэтому лучший способ ленивой загрузки 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 в глобальном контексте.
Ссылки здесь
Что касается вопроса о ленивой загрузке cdn в приложение angular
Для этой цели специально создана следующая библиотека 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
});
Вы также должны рассмотреть следующий абзац из этой статьи.
Загрузка сторонних скриптов async - это ключ для высокопроизводительных веб-страниц, но эти сценарии по-прежнему блокируют загрузку. Потратьте время, чтобы проанализировать свои данные о производительности сети и понять, влияют ли и на то, как эти не очень важные материалы/виджеты/объявления/коды отслеживания влияют на время загрузки страницы.