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 - это ключ для высокопроизводительных веб-страниц, но эти сценарии по-прежнему блокируют загрузку. Потратьте время, чтобы проанализировать свои данные о производительности сети и понять, влияют ли и на то, как эти не очень важные материалы/виджеты/объявления/коды отслеживания влияют на время загрузки страницы.