2016-01-29 28 views
2

當使用grunt-contrib-requirejs建立我的項目,我knockout components'模塊,僅在組件本身(textmapping)將不會被添加到我的壓縮輸出腳本文件引用。咕嚕-的contrib-requirejs淘汰賽成分問題

我淘汰賽模塊:

define(['knockout', 'text!./foo.html', 'mapping'], ....) 

由於該組件在運行時異步注射 - 據我所知 - 咕嚕-的contrib-requirejs不接他們,並把它們添加到我的壓縮文件,out: "<%= settings.getBuildPath() %>/js/lib/require/require.js",下面:

咕嚕配置:

requirejs: { 
    compile: { 
     options: { 
      baseUrl: 'src/js', 
      mainConfigFile: "src/js/app.js", 
      name: 'app', 
      out: "<%= settings.getBuildPath() %>/js/optimized.js", 
      preserveLicenseComments: false, 
      include: ['lib/require/require.js'] 
     } 
    }  
} 

如果我在另一個不是挖空組件模塊的腳本文件中引用它們,則該項目可以正常工作。

那麼,我該如何讓grunt-contrib-requirejs添加在我的組件中引用的腳本呢?

+0

請解釋你爲什麼用你的壓縮文件覆蓋requirejs?我猜''%= settings.getBuildPath()%>/js/lib/require/require.js'和'lib/require/require.js'是同一個文件。 –

+0

@TomaszJakubRup不,他們不是。我的index.html有一個腳本引用:''。所以當所有文件被壓縮到一個文件時,它需要具有相同的名稱。實際的require.js包含在include:['lib/require/require.js']'中,因爲優化器將其刪除。儘管目前這不是我的問題,但您是否對此方法有任何疑慮?如果我將它稱爲'out.js',我需要在grunt中相應地修改腳本標記,對吧? – Johan

+0

'out:'out.js''並加載它''。在GitHub或BitBucket上顯示完整的工作示例 –

回答

2

我對這個問題的解決方案是使用一個模塊來註冊組件,並在這裏需要模板和視圖模型,以確保r.js將它們包含在捆綁中。

我通常需要在main.js中調用此模塊。

// registerComponents.js 
define(
['knockout', 'componentViewModel', 'text!componentTemplate.html', ], 
function (ko, componentViewModel, componentTemplate) { 

    return function() { 
     ko.components.register('myComponent', { 
      viewModel: componentViewModel, 
      template: componentTemplate 
     }); 
    }; 

}); 

// main.js 
require(['registerComponents'], function (registerComponents) { 
    registerComponents(); 
}); 
+1

好主意。我目前的解決方案是使用'include'設置並在其中包含組件。我會給這個想法:) – Johan

1

根據您的應用程序的大小,也許你想給你所有的HTML放置到單個的JS文件,並使用自定義的淘汰賽組件載入。

grunt.registerTask("generate-templates", function() { 
    var componentTemplates = grunt.file.expand('components/**/*.html'); 
    var incldesContent = ''; 
    var imports = componentTemplates.map(function (item) { 

     var content = fs.readFileSync(item, { encoding: 'utf8' }).toString(); 
     content = content.trim().replace(/["'\\\n\r\u2028\u2029]/g, function (character) { 
      // Escape all characters not included in SingleStringCharacters and 
      // DoubleStringCharacters on 
      // http://www.ecma-international.org/ecma-262/5.1/#sec-7.8.4 
      switch (character) { 
       case '"': 
       case "'": 
       case '\\': 
        return '\\' + character 
        // Four possible LineTerminator characters need to be escaped: 
       case '\n': 
        return '\\n' 
       case '\r': 
        return '\\r' 
       case '\u2028': 
        return '\\u2028' 
       case '\u2029': 
        return '\\u2029' 
      } 
     }) 
     return "templatesCache['" + item + "'] = '" + content + "';"; 
    }); 
    grunt.file.write('wwwroot/templates.js', '// This file is autogenerated. DO NOT EDIT.\nvar templatesCache=[];\n' + imports.join('\n')); 
}); 

以下的模板註冊代碼。它在TypeScript中,但應該很容易翻譯成JS。

declare var templatesCache: any[]; 
enter code here 
/** 
* Dynamically register component based on component naming conventions 
*/ 
function registerComponent(componentName: string, folderName: string, componentData?: string) { 
    componentData = componentData || componentName; 
    var componentTemplate: string | KnockoutComponentTypes.AMDModule; 
    if (window["templatesCache"]) { 
     componentTemplate = templatesCache["components/" + folderName + "/" + componentData + "/" + componentData + ".html"]; 
    } else { 
     componentTemplate = { require: "text!components/" + folderName + "/" + componentData + "/" + componentData + ".html" } 
    } 
    ko.components.register(componentName, { 
     template: componentTemplate, 
     viewModel: { require: "components/" + folderName + "/" + componentData + "/" + componentData + "" } 
    }); 
} 

/* Shared components */ 
registerComponent("tabbar", "shared"); 
registerComponent("left-bar", "shared"); 
registerComponent("photo-loader", "shared"); 

從本質上講,我的咕嚕任務準備templates.js其聲明templateCache可變其中使用由組件裝載器,但它需要我手動註冊KO組件。您可以通過遵循命名約定和從文件夾結構生成註冊文件來避免這種情況。我的應用程序相對簡單,因此我最終會手動註冊,並且不要執行額外的步驟。