【问题标题】:Conditional dependency ignored in mobile在移动设备中忽略条件依赖
【发布时间】:2015-02-26 16:41:10
【问题描述】:

在构建网站的过程中,我们遇到了 VideoJS 和 Angular 之间的冲突,因此当 VideoJS 库存在时,Angular 模块不会在 iOS7 中加载。这是一种极端情况,页面内容比外围视频重要得多,所以我们选择只为我们的移动用户 nix VideoJS 并使用图像后备。

现在,考虑一下来自 requirejs 模块的相关代码摘录:

log("checkpoint 1");

var videojs, $ = require('jquery');

if($(".home").length && $(window).outerWidth() > 768){
    log("checkpoint 2a");
    videojs = require('videojs');
    log("checkpoint 2b");

    // video init code here
}

log("checkpoint 3");

在任何移动设备中,日志都会返回:

> checkpoint 1
> checkpoint 3

这表明循环没有像预期的那样在移动设备中被渗透。然而,与此相反,videojs 库仍在加载中——这违背了有条件地包含它的整个目的。

我们已经确认这是唯一包含 videojs 库的地方,因为当 videojs = require('videojs'); 被注释掉时问题就消失了 - 该库没有出现在资源列表中,并且页面正常呈现。

我们只是在设置条件依赖时很差吗?是否有其他方法可以执行此操作,或者我们是否牢牢卡在 Require 的已知限制中?

【问题讨论】:

    标签: javascript ios mobile requirejs


    【解决方案1】:
    videojs = require('videojs')
    

    我敢打赌,这是源代码(非编译文件)中的一行,然后您使用 browserify(或发布应用程序之前的类似内容)进行编译。

    当然,问题是您编译的文件总是需要 videojs(除非该行被注释掉),因为您的条件基于仅在运行时可用的行列式,而不是编译时。

    所以,回答你的问题:

    我们只是设置条件依赖关系不好?

    是的。

    可能有很多方法可以做到这一点,但我想到的一种是将 videojs 库作为单独的资产提供服务。您将使用(呃)用户代理解析来确定设备是否正在运行 iOS7 类似于以下内容(PHP 示例):

    <?php if(!is_ios7()) { //pseudo code - UA parsing in here. ?>
     <script src="/path/to/videojs"></script>
    <?php } ?>
    

    然后在您的主 js 文件中,您可以检测是否存在 videojs 全局变量,然后在需要时使用它。

    【讨论】:

      【解决方案2】:

      对于生产和测试 ENV 以及移动/桌面版本使用可以使用这个加载器:(来自这个 git hub 项目https://github.com/BoilerplateMVC/Marionette-Require-Boilerplate/blob/master/public/index.html

          // Mobile/Desktop Detection script
                  (function(ua, w, d, undefined) {
                      // App Environment
                      // ---------------
                      //  Tip: Set to true to turn on "production" mode
                      var production = true,
                              filesToLoad,
                      //BoilerplateMVC Helper Methods
                              boilerplateMVC = {
                                  loadCSS: function(url, callback) {
                                      var link = d.createElement("link");
                                      link.type = "text/css";
                                      link.rel = "stylesheet";
                                      link.href = url;
                                      d.getElementsByTagName("head")[0].appendChild(link);
                                      if(callback) {
                                          callback();
                                      }
                                  },
                                  loadJS: function(file, callback) {
                                      var script = d.createElement("script");
                                      script.type = "text/javascript";
                                      if (script.readyState) {  // IE
                                          script.onreadystatechange = function() {
                                              if (script.readyState == "loaded"
       || script.readyState == "complete") {
                                                  script.onreadystatechange = null;
                                                  callback();
                                              }
                                          };
                                      } else {  // Other Browsers
                                          script.onload = function() {
                                              callback();
                                          };
                                      }
                                      if(((typeof file).toLowerCase()) === "object"
       && file["data-main"] !== undefined) {
                                          script.setAttribute("data-main", 
      file["data-main"]);
                                          script.async = true;
                                          script.src = file.src;
                                      } else {
                                          script.src = file;
                                      }
                                      d.getElementsByTagName("head")[0].appendChild(script);
                                  },
                                  loadFiles: function(production, obj, callback) {
                                      var self = this;
                                      if(production) {
                                          // Loads the production CSS file(s)
                                          self.loadCSS(obj["prod-css"], function() {
                                              // If there are production JavaScript files to load
                                              if(obj["prod-js"]) {
                                                  // Loads the correct initialization file (which includes Almond.js)
                                                  self.loadJS(obj["prod-js"], callback);
                                              }
                                          });
                                      } else {
                                          // Loads the development CSS file(s)
                                          self.loadCSS(obj["dev-css"], function() {
                                              // If there are development Javascript files to load
                                              if(obj["dev-js"]) {
                                                  // Loads Require.js and tells Require.js to find the correct intialization file
                                                  self.loadJS(obj["dev-js"], callback);
                                              }
                                          });
                                      }
                                  }
                              };
                      // Mobile/Tablet Logic
                      if((/iPhone|iPod|iPad|Android|BlackBerry|Opera Mini|IEMobile/).test(ua)) {
                          // Mobile/Tablet CSS and JavaScript files to load
                          filesToLoad = {
                              // CSS file that is loaded when in development mode
                              "dev-css": "css/mobile.css",
                              // CSS file that is loaded when in production mode
                              "prod-css": "css/mobile.min.css",
                              // Require.js configuration file that is loaded when in development mode
                              "dev-js": { "data-main": "js/app/config/config.js", "src": "js/libs/require.js" },
                              // JavaScript initialization file that is also loaded when in development mode
                              "dev-init": "js/app/init/MobileInit.js",
                              // JavaScript file that is loaded when in production mode
                              "prod-init": "js/app/init/MobileInit.min.js",
                              "prod-js": { "data-main": "js/app/config/config.js", "src": "js/libs/require.js" }
                          };
                      }
                      // Desktop Logic
                      else {
                          // Desktop CSS and JavaScript files to load
                          filesToLoad = {
                              // CSS file that is loaded when in development mode
                              "dev-css": "css/desktop.css",
                              // CSS file that is loaded when in production mode
                              "prod-css": "css/desktop.min.css",
                              // Require.js configuration file that is also loaded when in development mode
                              "dev-js": { "data-main": "js/app/config/config.js", "src": "js/libs/require.js" },
                              // JavaScript initialization file that is loaded when in development mode
                              "dev-init": "js/app/init/DesktopInit.js",
                              // JavaScript file that is loaded when in production mode
                              "prod-init": "js/app/init/DesktopInit.min.js",
                              "prod-js": { "data-main": "js/app/config/config.js", "src": "js/libs/require.js" }
                          };
                      }
                      boilerplateMVC.loadFiles(production, filesToLoad, function() {
                          if(!production && window.require) {
                              require([filesToLoad["dev-init"]]);
                          } else if ( production ) {
                              require([filesToLoad["prod-init"]])
                          }
                      });
                  })(navigator.userAgent || navigator.vendor || window.opera, window, document);
      

      以及该项目中的其他逻辑:

          var App = new Backbone.Marionette.Application();
      
          function isMobile() {
              var userAgent = navigator.userAgent || navigator.vendor || window.opera;
              return ((/iPhone|iPod|iPad|Android|BlackBerry|Opera Mini|IEMobile/).test(userAgent));
          }
      
          App.mobile = isMobile();
      
      
      require(["App", "jquery", "routers/AppRouter", "controllers/MobileController", "backbone", "marionette", "jquerymobile", "backbone.validateAll"],
          function (App, $, AppRouter, AppController) {
              // Prevents all anchor click handling
              $.mobile.linkBindingEnabled = false;
              // Disabling this will prevent jQuery Mobile from handling hash changes
              $.mobile.hashListeningEnabled = false;
      
              App.appRouter = new AppRouter({
                  controller:new AppController()
              });
      
              App.start();
          });
      

      【讨论】:

        猜你喜欢
        • 2020-06-27
        • 1970-01-01
        • 2017-05-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多