【问题标题】:Dojo build requesting already inlined templates请求已内联模板的 Dojo 构建
【发布时间】:2013-09-14 21:41:34
【问题描述】:

我绝望地试图让 Dojo buildsDijit template 内联功能为我的 AMD 项目工作,但还没有运气......

具体问题不在于 HTML 模板本身的内联,而是在成功内联后仍然使用 Ajax (XHR) 请求它们这一事实。

模板按以下方式内联:

"url:app/widgets/Example/templates/example.html": '<div>\n\tHello World!</div>'

Dijit 小部件本身在构建后定义如下模板:

define("dojo/_base/declare,dijit/_Widget,dojo/text!./templates/example.html".split(","), function (f, g, d) {
    return f("MyApp.Example", [g], {
        templateString: d,
    });
});

我尝试使用:

  • shrinksafe/闭包优化器
  • 相对/绝对路径
  • 使用旧的cache() 方法
  • 使用templatePath 属性

但即使在内联模板的情况下运行成功构建(0 个错误和一些警告)后,Dojo / Dijit 仍会向这些资源发出 Ajax 请求。

这是我的构建配置文件:

var profile = {
    basePath: '../src/',
    action: 'release',
    cssOptimize: 'comments',
    mini: true,
    optimize: 'closure',
    layerOptimize: 'closure',
    stripConsole: 'all',
    selectorEngine: 'acme',
    internStrings: true,
    internStringsSkipList: false,
    packages: [
        'dojo',
        'dijit',
        'dojox',
        'app'
    ],
    layers: {
        'dojo/dojo': {
            include: [
                'app/run'
            ],
            boot: true,
            customBase: true
        },
    },
    staticHasFeatures: {
        'dojo-trace-api': 0,
        'dojo-log-api': 0,
        'dojo-publish-privates': 0,
        'dojo-sync-loader': 0,
        'dojo-xhr-factory': 0,
        'dojo-test-sniff': 0
    }
};

由于这个问题,我的应用程序完全无法使用,因为要单独下载的文件太多(浏览器对并行连接的数量有限制)。

非常感谢您!

更新:

在我的index.html 中加载dojo.js 和run.js 的两行:

<script data-dojo-config='async: 1, tlmSiblingOfDojo: 0, isDebug: 1' src='/public/dojo/dojo.js'></script>
<script src='/public/app-desktop/run.js'></script>

这是新的build-profile

var profile = {
    basePath: '../src/',
    action: 'release',
    cssOptimize: 'comments',
    mini: true,
    internStrings: true,
    optimize: 'closure',
    layerOptimize: 'closure',
    stripConsole: 'all',
    selectorEngine: 'acme',
    packages        : [
        'dojo',
        'dijit',
        'app-desktop'
    ],
    layers: {
        'dojo/dojo': {
            include: [
                'dojo/request/xhr',
                'dojo/i18n',
                'dojo/domReady',
                'app-desktop/main'
            ],
            boot: true,
            customBase: true
        }
    },
    staticHasFeatures: {
        'dojo-trace-api': 0,
        'dojo-log-api': 0,
        'dojo-publish-privates': 0,
        'dojo-sync-loader': 0,
        'dojo-xhr-factory': 0,
        'dojo-test-sniff': 0
    }
};

我的新run.js 文件:

require({
    async: 1,
    isDebug: 1,
    baseUrl: '/public',
    packages: [
        'dojo',
        'dijit',
        'dojox',
        'saga',
        'historyjs',
        'wysihtml5',
        'app-shared',
        'jquery',
        'jcrop',
        'introjs',
        'app-desktop'
    ],
    deps: [
        'app-desktop/main',
        'dojo/domReady!'
    ],
    callback: function (Main) {
        debugger;
        var main = new Main();
        debugger;
        main.init();
    }
});

我的main.js 文件看起来像这样:

define([
    'dojo/_base/declare',
    'app-desktop/widgets/Application',
    'app-desktop/config/Config',
    'saga/utils/Prototyping',
    'dojo/window',
    'dojo/domReady!'
], function (declare, Application, ConfigClass, Prototyping, win) {

    return declare([], {
        init: function() {

            // ... other stuff

            application = new Application();
            application.placeAt(document.body);

            // ... some more stuff
        }
    });

});

build-mode 中,我收到以下错误:

GET http://localhost:4000/app-desktop/run.js 404 (Not Found)

这很奇怪,因为这意味着构建过程使 dojo 具有外部依赖项,而不是构建文件中已经内联的 dojoConfig 变量。

normal-mode 中,请求文件,但从未创建应用程序。

在这两种情况下,run.js 文件中设置的两个调试器都没有运行,这意味着由于某种原因从未调用过 callback 方法。

感谢您的帮助!

【问题讨论】:

  • 如果您在小部件中使用"A,B,C".split(",") 技巧会怎样? (换句话说,只是["A","B","C"])也许有一些解析/正则表达式的魔法正在发生并且破坏了它?
  • 我尝试将 string + split hack 替换为常规数组,但遗憾的是,这不起作用。
  • 闭包编译器在编译期间将 "A,B,C".split(",") 表达式扩展为标准数组。它使代码更容易优化。
  • 是的,我以为会是这样,但即使使用 shrinksafe 代替 Closure-compiler,这意味着在标准数组中定义了依赖项,您也会遇到相同的错误。
  • 我看到 ""url:app/widgets/..." 并且在您的包中列出了 'app-desktop' - 我想知道这是否与此有关。另外,在搜索生成器代码,internStringsSkipList 似乎什么都不做,因此您可以将其省略,而 internStrings 默认为 true,因此也可以省略。

标签: templates build dojo google-closure-compiler


【解决方案1】:

我已经在 dojo/text.js 的 load() 方法中将 requireCacheUrlrequire.cache 的值打印到控制台。至少在我的情况下,缓存中模板的键与一个前导斜杠上的查找键不同。

例如,我的小部件中有"dojo/text!./templates/Address.html"。它在缓存中以键 url:/app/view/templates/Address.html 显示,但像 url:app/view/templates/Address.html 一样搜索,导致缓存未命中和 xhr 请求。

在 dojo/text.js(版本 1.9.1 的第 183 行)中添加了额外的斜线,它似乎可以工作(行看起来像 requireCacheUrl = "url:/" + url)。

不确定这个“修复”会引入什么样的错误。因此,可能值得将这个问题报告给 dojo 人。

UPD:嗯,我看到你已经报告了这个问题。这是链接:https://bugs.dojotoolkit.org/ticket/17458

UPD:不要使用上述的 hack。这只是试图缩小问题。我项目中的真正问题是包和 baseUrl 设置。最初,我基于https://github.com/csnover/dojo-boilerplate 创建了我的项目。然后将其修复为neonstalwart's sample

【讨论】:

  • 好的,我做了一些测试,模板似乎不再内联,应该是 JavaScript 文件还是 HTML 文件(1.8.3 和 1.9.1)。但是我尝试用随机字符串替换 URL,它起作用了!所以肯定跟URL建设有关!
  • 嗯,这个技巧绝对适合我。澄清一下:我在本地的 dojo/text.js 副本中替换了字符串 183。我使用完整的源代码版本 1.9.1。行是“requireCacheUrl = “url:”+ url”,我当前的版本是“requireCacheUrl = (url.charAt(0) == '/' ? 'url:' : 'url:/') + url”。我承认,在某些情况下,此修复程序会刹车。我的项目还很小,没有涵盖很多场景,但我现在没有看到任何问题。如果您尝试重现这一点,请确保构建工具使用固定的 dojo 库文件。
  • 另外,我从 github.com/csnover/dojo-boilerplate 开始,必须在 app.profile 的层中添加 'app/run',以便该文件也打包到 dojo.js 中,然后必须修复 baseUrl在 dojoConfig 中。不确定,但可能这些东西也与制作模板的网址有关。这是我设置 baseUrl 的方法: var dojoConfig = (function () { var base = location.pathname.split('/'); base.pop(); base = base.join('/'); return {baseUrl: base, isDebug: 1, async: 1}; })();
  • 通过这些修复,所有脚本都只放在一个文件中,并且只有几个对 css、png 等的额外请求。如果您使用 Chrome,请在开发控制台的设置中取消标记“启用源映射”选项,因为当使用此选项打开控制台时,它会下载源的调试版本。
  • @nikolay_turpitko 您可以尝试github.com/neonstalwart/inlined-build 并更改它以重现您所看到的问题吗?我试图故意破坏代码以找到你们都看到的问题,但我无法让它破坏。也许我非常了解“规则”,以至于我不知道如何打破它们:) fwiw,我不认为像你所做的那样添加'/'将成为最终的解决方案。
【解决方案2】:

这听起来像https://bugs.dojotoolkit.org/ticket/17141。如果是,您只需更新到 Dojo 1.9.1。

【讨论】:

  • 这不起作用。我检查了 Dojo、Dijit、Dojox 和 Util 存储库上的 1.9.1 标签,但这并没有改变任何东西。
  • 通过检查最小化的源代码,有一个区别。现在模板全部内联在文件的末尾,而不是分散在文件中的任何地方,仅此而已。
  • 您使用什么浏览器进行测试?
  • Google Chrome 29 主要是。
猜你喜欢
  • 1970-01-01
  • 2013-06-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多