在构建网站的过程中,我们遇到了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');
被注释掉时问题消失 - 库没有出现在资源列表中,并且页面呈现正常。
我们只是设置条件依赖性很差吗?还有另一种方法可以执行此操作,还是我们坚持已知的需求限制?
答案 0 :(得分:0)
videojs = require('videojs')
我打赌这是源代码(非编译文件)中的一行,然后您可以使用browserify进行编译(或者在发布应用程序之前使用类似的东西)。
问题是,当然,您编译的文件总是需要videojs(除非该行被注释掉),因为您的条件基于仅在运行时可用的决定因素,而不是编译时。
所以,回答你的问题:
我们只是设置条件依赖性很差吗?
是
可能有很多方法可以做到这一点,但我想到的一个方法是将videojs库作为单独的资产提供。您使用(ugh)用户代理解析来确定设备是否正在运行iOS7
,如下所示(PHP示例):
<?php if(!is_ios7()) { //pseudo code - UA parsing in here. ?>
<script src="/path/to/videojs"></script>
<?php } ?>
然后在您的主js文件中,您可以检测videojs全局变量是否存在,然后在需要时使用它。
答案 1 :(得分:-1)
用于生产和测试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();
});