Mathieu
Mathieu

Reputation: 4797

Webpack - export window.function failing

I am a total newbie in Webpack which I have started to use 3 days ago to change how we load our javascript.

The code before webpack, which is working, is used to implement a "famous" fading effect (source gist.github.com/paulirish/1579671)

window.requestNextAnimationFrame =
   (function () {
      var originalWebkitRequestAnimationFrame = undefined,
          wrapper = undefined,
          callback = undefined,
          geckoVersion = 0,
          userAgent = navigator.userAgent,
          index = 0,
          self = this;

      // Workaround for Chrome 10 bug where Chrome
      // does not pass the time to the animation function

      if (window.webkitRequestAnimationFrame) {
         // Define the wrapper

         wrapper = function (time) {
           if (time === undefined) {
              time = +new Date();
           }
           self.callback(time);
         };

         // Make the switch

         originalWebkitRequestAnimationFrame = window.webkitRequestAnimationFrame;    

         window.webkitRequestAnimationFrame = function (callback, element) {
            self.callback = callback;

            // Browser calls the wrapper and wrapper calls the callback

            originalWebkitRequestAnimationFrame(wrapper, element);
         }
      }

      // Workaround for Gecko 2.0, which has a bug in
      // mozRequestAnimationFrame() that restricts animations
      // to 30-40 fps.

      if (window.mozRequestAnimationFrame) {
         // Check the Gecko version. Gecko is used by browsers
         // other than Firefox. Gecko 2.0 corresponds to
         // Firefox 4.0.

         index = userAgent.indexOf('rv:');

         if (userAgent.indexOf('Gecko') != -1) {
            geckoVersion = userAgent.substr(index + 3, 3);

            if (geckoVersion === '2.0') {
               // Forces the return statement to fall through
               // to the setTimeout() function.

               window.mozRequestAnimationFrame = undefined;
            }
         }
      }

      return window.requestAnimationFrame   ||
         window.webkitRequestAnimationFrame ||
         window.mozRequestAnimationFrame    ||
         window.oRequestAnimationFrame      ||
         window.msRequestAnimationFrame     ||

         function (callback, element) {
            var start,
                finish;


            window.setTimeout( function () {
               start = +new Date();
               callback(start);
               finish = +new Date();

               self.timeout = 1000 / 60 - (finish - start);

            }, self.timeout);
         };
      }
   )
();

// It's then used here in our code here:
loadIcons();
function loadCompanyIcons() {
  var elements = document.querySelectorAll('img');
  if (!elements) return;
  Array.prototype.forEach.call(elements, function(el, i){    
    var watcher = scrollMonitor.create(el, 2000);
    watcher.enterViewport(function() {      
      var srcToInject = el.getAttribute('data-src');
      var src         = el.getAttribute('src');
      if (src === null && srcToInject!=null) { // do not re-execute for images already with injected src
        el.style.opacity = 0;
        el.style.display = "block";
        el.setAttribute('src',srcToInject);
        el.onload   = imageFound;
        el.onerror  = imageNotFound;        
        function imageFound() {           
          // progressively show image via opacity variation
          (function fade() {
            var val = parseFloat(el.style.opacity);
            if (!((val += .1) > 1)) {
              el.style.opacity = val;
              requestNextAnimationFrame(fade);
            }
          })();          
        }        
      }
    });
  });  
}

It perfectly works when used on a basic js file.

When we tried to move to Webpack and use "exports" we hit a wall. Most Webapck export we do have been working so I think this one does not work because it's not a standard:

function doSth() {
}

But it starts with window.doSth()...

Here's what we do today which is failing:

js/helpers/requestAnimationFramePolyfill.js

export window.requestNextAnimationFrame =
       (function () {
          var originalWebkitRequestAnimationFrame = undefined,
              wrapper = undefined,
              callback = undefined,
              geckoVersion = 0,
              userAgent = navigator.userAgent,
              index = 0,
              self = this;

          // Workaround for Chrome 10 bug where Chrome
          // does not pass the time to the animation function

          if (window.webkitRequestAnimationFrame) {
             // Define the wrapper

             wrapper = function (time) {
               if (time === undefined) {
                  time = +new Date();
               }
               self.callback(time);
             };

             // Make the switch

             originalWebkitRequestAnimationFrame = window.webkitRequestAnimationFrame;    

             window.webkitRequestAnimationFrame = function (callback, element) {
                self.callback = callback;

                // Browser calls the wrapper and wrapper calls the callback

                originalWebkitRequestAnimationFrame(wrapper, element);
             }
          }

          // Workaround for Gecko 2.0, which has a bug in
          // mozRequestAnimationFrame() that restricts animations
          // to 30-40 fps.

          if (window.mozRequestAnimationFrame) {
             // Check the Gecko version. Gecko is used by browsers
             // other than Firefox. Gecko 2.0 corresponds to
             // Firefox 4.0.

             index = userAgent.indexOf('rv:');

             if (userAgent.indexOf('Gecko') != -1) {
                geckoVersion = userAgent.substr(index + 3, 3);

                if (geckoVersion === '2.0') {
                   // Forces the return statement to fall through
                   // to the setTimeout() function.

                   window.mozRequestAnimationFrame = undefined;
                }
             }
          }

          return window.requestAnimationFrame   ||
             window.webkitRequestAnimationFrame ||
             window.mozRequestAnimationFrame    ||
             window.oRequestAnimationFrame      ||
             window.msRequestAnimationFrame     ||

             function (callback, element) {
                var start,
                    finish;


                window.setTimeout( function () {
                   start = +new Date();
                   callback(start);
                   finish = +new Date();

                   self.timeout = 1000 / 60 - (finish - start);

                }, self.timeout);
             };
          }
       )
    ();

    // It's then used here in our code here:
    loadIcons();
    function loadIcons() {
      var elements = document.querySelectorAll('img');
      if (!elements) return;
      Array.prototype.forEach.call(elements, function(el, i){    
        var watcher = scrollMonitor.create(el, 2000);
        watcher.enterViewport(function() {      
          var srcToInject = el.getAttribute('data-src');
          var src         = el.getAttribute('src');
          if (src === null && srcToInject!=null) { // do not re-execute for images already with injected src
            el.style.opacity = 0;
            el.style.display = "block";
            el.setAttribute('src',srcToInject);
            el.onload   = imageFound;
            el.onerror  = imageNotFound;        
            function imageFound() {           
              // progressively show image via opacity variation
              (function fade() {
                var val = parseFloat(el.style.opacity);
                if (!((val += .1) > 1)) {
                  el.style.opacity = val;
                  requestNextAnimationFrame(fade);
                }
              })();          
            }        
          }
        });
      });  
    }

then we do in main.js

import {requestNextAnimationFrame} from './helpers/requestAnimationFramePolyfill.js'

loadIcons();
function loadCompanyIcons() {
  var elements = document.querySelectorAll('img');
  if (!elements) return;
  Array.prototype.forEach.call(elements, function(el, i){    
    var watcher = scrollMonitor.create(el, 2000);
    watcher.enterViewport(function() {      
      var srcToInject = el.getAttribute('data-src');
      var src         = el.getAttribute('src');
      if (src === null && srcToInject!=null) { // do not re-execute for images already with injected src
        el.style.opacity = 0;
        el.style.display = "block";
        el.setAttribute('src',srcToInject);
        el.onload   = imageFound;
        el.onerror  = imageNotFound;        
        function imageFound() {           
          // progressively show image via opacity variation
          (function fade() {
            var val = parseFloat(el.style.opacity);
            if (!((val += .1) > 1)) {
              el.style.opacity = val;
              requestNextAnimationFrame(fade);
            }
          })();          
        }        
      }
    });
  });  
}

We also tried:

import {window.requestNextAnimationFrame} from './helpers/requestAnimationFramePolyfill.js'

but none work and we know this because the icons supposed to use requestAnimationFramePolyfill.js to progressively fade iunto a 1.0 opacity, remain with 0.1 opacity.

I'm not sure though this is the reason. I could not understand it for the past day.

Upvotes: 1

Views: 301

Answers (1)

Natsathorn
Natsathorn

Reputation: 1528

You are trying to add a function in to window object then use it in other place. It's one way to make a function access able by other files, but with ES6 and webpack you can do it other way.

I suggest to not use variable window because its may cause some issue with window syntax. Also you do not need to add a function to window object anymore.

This should work for you.

js/helpers/requestAnimationFramePolyfill.js

const requestNextAnimationFrame = (function { your function });
export { requestNextAnimationFrame };

main.js

import { requestNextAnimationFrame } from './helpers/requestAnimationFramePolyfill.js'

Upvotes: 2

Related Questions