使用amd和requirejs在knockout spa中处理错误

时间:2015-06-29 17:35:31

标签: javascript knockout.js requirejs single-page-application

所以我有一个基于Steve Sandersons SPA template的相当大的单页面应用程序。自定义bindingHandlers,验证等一切正常。

我们需要使用XMLHttpRequests,Session和Local存储以及其他一些没有通用支持的库(jquery 2.0等)。我有一个处理身份和暴露一些服务的核心模块,这两个服务都依赖于这些功能。这是在用户首次访问页面时加载的。

我遇到了旧浏览器的问题,其中a)它们不支持某些正在加载的模块,因此它们在点击onload函数之前会抛出错误,或者b)它遇到onload函数但是它们不支持浏览器功能所以我需要自己提出异常并以某种方式处理它。

示例:IE8抛出'对象不支持属性或方法'addEventListener''(jquery错误)和IE9不支持我需要的所有内容,因此我抛出自定义错误。

define('core', ['jquery', 'browser'], function($, browser) {
     if(!browser.hasFullSupport) {
         throw new Error('Update your browser');
     }
     // aload of gubbins that requires sessionStorage etc
     return {
          identity: identity,
          serviceA: serviceA,
          serviceB: serviceB
     }
}, function(err) {
    // doesn't catch the ie8 error here
});

我尝试过设置一个window.onerror,但它在浏览器版本中的工作方式不同,有些我无法正确捕获错误消息,我只是得到了“脚本错误”。

我知道我可以为模块定义添加错误事件处理程序,但它不会捕获我遇到的错误。

我见过人们使用

requirejs.onError = function(err) {
   // something here 
}

但是我正在使用requirejs gulp bundler,我无法看到这个对象会暴露在哪里(如果有的话)

var require = {
baseUrl: ".",
paths: {
    "modernizr":            "bower_modules/modernizr/modernizr",
    "browser":              "app/browser-detect",
    "crossroads":           "bower_modules/crossroads/dist/crossroads.min",
    "hasher":               "bower_modules/hasher/dist/js/hasher.min",
    "jquery":               "bower_modules/jquery/dist/jquery.min",
    ....

// gulpfile
var requireJsRuntimeConfig = vm.runInNewContext(fs.readFileSync('src/app/require.config.js') + '; require;');
requireJsOptimizerConfig = merge(requireJsRuntimeConfig, {
    out: 'scripts.js',
    baseUrl: './src',
    name: 'app/startup',
    paths: {
        requireLib: 'bower_modules/requirejs/require'
    },
    include: [
        'requireLib',
        'components/nav-bar/nav-bar',
        .....

gulp.task('js', function () {
return rjs(requireJsOptimizerConfig)
    .pipe(uglify())
    .pipe(gulp.dest('./dist/'));
});

有大量的组件/页面,每个都可能抛出一个错误,但这是我最初想要整理的初始核心组件加载。我想区分错误(可能是因为浏览器太旧而引起的错误),也可能是我之间发现它们过于陈旧,是否有使用此模板模型实现此目的的优雅方法? / p>

我宁愿不要偏离模板太远,因为我不太熟悉requirejs / gulp等,但我愿意接受建议。

1 个答案:

答案 0 :(得分:1)

You contradict yourself:

We require the use of the XMLHttpRequests, Session and Local storage as well as some other libraries that don't have universal support (jquery 2.0 etc)

But:

IE8 throws an 'Object doesn't support property or method 'addEventListener'' (jquery error) and IE9 Doesn't support everything I need so I throw a custom error.

You can't use libraries and HTML 5 features for newer browsers and expect older browsers to still work. Libraries that do not support legacy browsers like IE 8 do not fail gracefully so you cannot handle the failure very well. And even if you found a workaround to somehow circumvent the errors, you would still need to test them all in old browsers periodically which beats the intent to support only newer browsers.

So I recommend you two approaches:

  1. Either decide not to support olders browsers at all and test the app only in newest modern browsers. You could use modern versions of libraries that dropped support of old browsers and not worry about old browsers at all. It depends on the state of your user base. Or:
  2. Downgrade libraries to versions that support your minimal required browsers and continue developing the app with them. Test the app and fix all errors that occur in old browsers. Use polyfills that enable new HTML 5 features in old browsers via emulation.