首页 > 解决方案 > Webpack - 导出 window.function 失败

问题描述

我是 Webpack 的新手,3 天前我开始使用它来改变我们加载 JavaScript 的方式。

正在运行的 webpack 之前的代码用于实现“著名”的褪色效果(来源 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);
            }
          })();          
        }        
      }
    });
  });  
}

在基本 js 文件上使用时,它可以完美运行。

当我们尝试迁移到 Webpack 并使用“导出”时,我们碰壁了。我们所做的大多数 Webapckexport一直在工作,所以我认为这个不起作用,因为它不是标准:

function doSth() {
}

但它始于window.doSth()...

这是我们今天做的失败的事情:

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);
                }
              })();          
            }        
          }
        });
      });  
    }

然后我们在 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);
            }
          })();          
        }        
      }
    });
  });  
}

我们也试过:

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

但没有任何效果,我们知道这一点,因为应该使用 requestAnimationFramePolyfill.js 逐渐淡入 1.0 不透明度的图标,保持 0.1 不透明度。

我不确定这是否是原因。过去一天我无法理解。

标签: javascriptwebpack

解决方案


您正在尝试将功能添加到window对象中,然后在其他地方使用它。这是使其他文件可以访问函数的一种方法,但是使用 ES6 和 webpack,您可以通过其他方式进行操作。

我建议不要使用变量window,因为它可能会导致一些window语法问题。此外,您不再需要向窗口对象添加函数。

这应该适合你。

js/helpers/requestAnimationFramePolyfill.js

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

main.js

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

推荐阅读