Structuring large javascript code using RequireJS - django

Am very new to RequireJS here and trying to learn how to adopt to the structure. As of now, I've managed to create a structure as following
above image shows the structure of my code. Where by the folder "my" is supposed to contain all my modules, I plan to write inside each module its own models.js, views.js to be used later on by backbone.js
At this point I have couple questions as following
Can anyone by looking at the structure tell if its a good idea or if I should reconsider?
The second question is have is related to how I should manage conditionally loading my modules. Below is my config.js file
require([
"jquery",
"libs/jquery-ui/js/jquery-ui-1.9.0.custom.min",
"libs/bootstrap/js/bootstrap.min",
"my/base/module",
"my/vehicle/module"],
function($, ui, bootstrap, base, vehicle) {
//plugins have been loaded.
base.initialize();
vehicle.initialize();
});
am still not sure how to load module vehicle when am browsing or load module accounts when am browsing accounts. The backend is developed using django, I could create several config.js files for each module but am not sure if this is the correct approach or not.

This is how I setup RequireJS with JQuery within Python Django framework.
In base top level baset_site.html I have the following require.js config code between "head" tags:
<script>
requirejs.config({
baseUrl: "{% static '' %}",
paths: {
jquery: './js/jslibs/jquery-1.9.1',
jqm: './js/jslibs/jquery.mobile-1.4.0',
ajax_redirect: './js/ajax_redirect',
make_filt_sel: './app_namespace/js/make_filt_sel'
},
shim: {
"jquery": {
exports: '$',
},
"jqm": {
deps: ['jquery'],
exports: '$.mobile'
},
"make_filt_sel": {
deps: ['jquery', 'jqm'],
exports: 'make_filt_sel'
}
}
});
</script>
{% block header_scripts %}{% endblock header_scripts %}
Here's my ajax_redirect.js
/*
JQuery Ajax typically does not redirect in Django. Need middleware to
setup "class AjaxRedirect(object):" to fix redirection.
Reference:
http://hunterford.me/how-to-handle-http-redirects-with-jquery-and-django/
*/
(function ( root, doc, factory ) {
if ( typeof define === "function" && define.amd ) {
// AMD. Register as an anonymous module.
define( ['jquery'], function () {
factory();
});
} else {
// Browser globals
factory();
}
}( this, document, function ( ) {
$(document).ajaxComplete(function(e, xhr, settings){
if (xhr.status == 278){
window.location.href =
xhr.getResponseHeader("Location")
.replace(/\?.*$/, "?next="+window.location.pathname);
}
});
}));
Then I typically setup "block header_scripts" in the inherited templates as follows:
{% block header_scripts %}
{{ block.super }}
<script>
if ( typeof define === "function" && define.amd ) {
// AMD {# Configure requirejs.config in base_site.html #}
require(["./app_namespace/js/module_namespace/js_module"]);
} else {
// No AMD
$.ajax({
async:false,
type:'GET',
url: "{% static "app_namespace/js/make_filt_sel.js" %}",
data:null,
dataType:'script'
});
$.ajax({
async:false,
type:'GET',
url: "{% static "app_namespace/js/module_namespace/js_module.js" %}",
data:null,
dataType:'script'
});
}
</script>
{% endblock header_scripts %}
Here's an example of setting up a js_module.js with dependencies:
(function ( root, doc, factory ) {
if ( typeof define === "function" && define.amd ) {
// AMD. Register as an anonymous module.
define( ['jquery', 'jqm', 'ajax_redirect', 'make_filt_sel'], function () {
factory();
});
} else {
// Browser globals
factory();
}
}( this, document, function ( ) {
// A bunch of code
$.mobile.document.on( "pagebeforecreate", function(e){
// a bunch of code
// Shorthand for $( document ).ready()
$(function(){
// a bunch of code
}); // end of $( document ).ready()
}); // end of $(document).on( "pagebeforecreate",
})); // end of (function ( root, doc, factory )

The essence of requireJS is modularization . IF you are loading any scripts , you should put path configs into the rquireJS config section. However if you are want conditional use /loading of files . Then you have to wrap your code around define module . somewhat like this
require.config({
paths:
{
jquery: 'libs/jquery/jquery-1.7.2.min',
jqueryui: 'libs/jquery/jquery-ui-1.8.20.min',
bootstrap: 'libs/bootstrap/bootstrap.min',
},
shim: {
'underscore': {
exports: '_'
},
'bootstrap': {
deps: ['jquery'],
exports: 'jquery'
}
}
});
require(['app/jquery.app','jquery.bootstrap'], function (AppRouter) {
var app_view = new AppRouter;
}
Your app/jquery.app should be your starting point of your application.
You have to write this into main.js file and call it like this
<script data-main="/Scripts/main" src="/Scripts/libs/require/require.js" type="text/javascript"></script>
and your jquery.app which is your starting point should look like this
define(['jquery','my/base/module','my/vehicle/module']],
//plugins have been loaded.
base.initialize();
vehicle.initialize();
});
Note that in define module I havent defined anything to be loaded for jquery ui and bootstrap . The reason is since jquery ui loads of its own and it uses jquery syntax . And bootstrap file actually depends on jquery . So use the shim config to load bootstrap.min.js. Basically Your config and starting point should define the paths + starting point . So thats how make it .

Related

Webpack 4 - Migrating from CommonsChunkPlugin to SplitChunksPlugin

We have a traditional server rendered application (non SPA) where each page is augmented with vuejs
Our existing webpack 3 configuration is
webpack.config.js
var webpack = require('webpack')
var path = require('path')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const CleanWebpackPlugin = require('clean-webpack-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')
module.exports = {
entry: {
shared: './shared.js',
pageA: './pageA.js',
// pageB: './pageB.js',
// pageC: './pageC.js',
// etc
},
resolve: {
alias: { vue: 'vue/dist/vue.esm.js' },
},
output: {
path: path.join(__dirname, './dist'),
filename: '[name].js',
},
module: {
rules: [
{
test: /\.css$/,
exclude: /node_modules/,
use: ExtractTextPlugin.extract({
use: [
{
loader: 'css-loader',
query: {
sourceMap: true,
},
},
],
}),
},
],
},
plugins: [
new CleanWebpackPlugin('./dist'),
new webpack.optimize.CommonsChunkPlugin({
name: ['shared'],
minChunks: Infinity,
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'runtime',
}),
new ExtractTextPlugin('[name].css'),
new CopyWebpackPlugin([{ from: 'index.html', to: '.' }]),
],
}
shared.js
// import shared dependencies & pollyfills
var vue = require('vue')
// import global site css file
require('./shared.css')
// initialize global defaults
// vue.setDefaults(...)
console.log('shared', { vue })
pageA.js
var vue = require('vue')
// only this page uses axios
var axios = require('axios')
console.log('pageA', { vue, axios })
shared.css
body {
background-color: aquamarine;
}
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<!-- included on every page-->
<link rel="stylesheet" href="shared.css">
</head>
<body>
<!-- included on every page-->
<script src="runtime.js"></script>
<script src="shared.js"></script>
<script src="pageA.js"></script>
</body>
</html>
With this setup
1) runtime.js contains the webpack loader, so any changes to shared.js don't cause pageA.js to be cache busted and vice versa
2) shared.js contains any shared dependencies (in this case vue) as well as any shared global initializion for every page (setting vue defaults etc). It is also the point we import our shared global css file.
3) pageA.js does not contain any dependencies imported in shared.js (vue in this case) but does contain dependicies it imports (axios in this case).
We have been unable to reproduce this setup using the SplitChunksPlugin
1) SplitChunksPlugin doesn't seem to allow an entry point as a split point.
2) All the examples have split out ALL node module dependices into a vendor chunk. This doesn't work for us as we have 100's of pages but only a few import a graphing library or moment etc... We don't want to have this graphing library or moment included in shared.js as it will then be load for all pages.
3) It wasn't clear how to split the runtime into its own file either
SplitChunksPlugin seems to be targeted at SPA's where javascript can be loaded on demand. Is the scenario we are trageting still supported?
Are you trying to migrate to webpack 4?
I find the optimisation cacheGroups test option works well to be specific about what goes where.
optimization: {
splitChunks: {
cacheGroups: {
shared: {
test: /node_modules[\\/](?!axios)/,
name: "shared",
enforce: true,
chunks: "all"
}
}
}
}
Will load everything from the node modules (except axios) and should therefore be included as part of your page entry point.
If you want webpack to chunk some component, you will need to import it asynchronously from your main entry file.
I have been using bundle-loader to do it, then I have:
In my webpack.config.js
optimization: {
splitChunks: {
chunks: 'all'
},
mergeDuplicateChunks: true,
}
module: {
rules: [
{
test: /\.bundle\.js$/, //yes my output file contains the bundle in its name
use: {
loader: 'bundle-loader', options: {lazy: true}
}
}
]
}
In my entry file.
//this code will replace the line where you are importing this component
let Login;
// this method will go inside your component
componentWillMount() {
require("bundle-loader!./ui/Login.jsx")((loginFile) => {
Login = loginFile.default;
this.setState({ loginLoaded: true });
});
}
If you don't want to use it, there are more ways of importing your file async.

How overcome with '#' , coming in URL through DeepLinking in Ionic 2?

I am trying to implement navigation in Ionic 2. I have tried with DeepLinking and i got the result, but '#' sign is comming in URL.
When '#' sign will come in URL then Google Analytic will not recognize the website, that's why i have tried to implement navigation in different ways like Angular 2 Routing, that supports both (HTML5 or hash URL style), but unable to implement in Ionic 2.
Ex- http://localhost:8100/#/registration - This one working fine but i want without '#'.
Like http://localhost:8100/registration
Thanks for help
I put in a PR for #ionic/app-scripts 3.2.5 to remedy this:
https://github.com/ionic-team/ionic-app-scripts/pull/1545
In the meantime you can edit some project and dependency files to enable it:
src/app/app.module.ts:
IonicModule.forRoot(MyApp,
{
locationStrategy: 'path'
},
{
links: [
{ component: RegistrationPage, name: 'registration', segment: 'registration' },
{ component: LoginPage, name: 'login', segment: 'login' },
{ component: HomePage, name: 'home', segment: '' }
]
})
src/index.html:
<head>
...
<base href="/" />
...
</head>
node_modules/#ionic/app-scripts/dist/dev-server/http-server.js:
function createHttpServer(config) {
var app = express();
app.set('serveConfig', config);
app.get('/', serveIndex);
app.use('/', express.static(config.wwwDir));
app.use("/" + serve_config_1.LOGGER_DIR, express.static(path.join(__dirname, '..', '..', 'bin'), { maxAge: 31536000 }));
// Lab routes
app.use(serve_config_1.IONIC_LAB_URL + '/static', express.static(path.join(__dirname, '..', '..', 'lab', 'static')));
app.get(serve_config_1.IONIC_LAB_URL, lab_1.LabAppView);
app.get(serve_config_1.IONIC_LAB_URL + '/api/v1/cordova', lab_1.ApiCordovaProject);
app.get(serve_config_1.IONIC_LAB_URL + '/api/v1/app-config', lab_1.ApiPackageJson);
app.get('/cordova.js', servePlatformResource, serveMockCordovaJS);
app.get('/cordova_plugins.js', servePlatformResource);
app.get('/plugins/*', servePlatformResource);
if (config.useProxy) {
setupProxies(app);
}
app.all('/*', serveIndex);
return app;
}
The line app.all('/*', serveIndex); is what will redirect any 404 file or directory not found errors to index.html. The locationStrategy: 'path' setting can then work normally with deeplinks and redirects under these circumstances.
Try to use pathLocationStrategy instead of HashLocationStrategy.
Add this in app.module.ts
import { LocationStrategy,
PathLocationStrategy } from '#angular/common';
...
#NgModule({
...
providers: [
{
provide: LocationStrategy,
useClass: PathLocationStrategy
},
...
Or other way is
IonicModule.forRoot(MyApp, {
locationStrategy: 'path'
})
And make sure to have a valid base href.
So here is the list of things which I did. Hope this helps.
We need to remove # in path of every url because Google Analytics rejects the urls with # in them. In App Module , add {locationStrategy: 'path'} to your App Module as follows :
IonicModule.forRoot(MyApp, {
locationStrategy: 'path'
})
2 .Now # is removed from the url. But when you refresh or directly access the url, this wont work because this is expected behaviour for any SPA. When you refresh the page , server tried to find the page at the location mentioned. As stated by #Parth Ghiya above For eg: if you hit localhost/abc , then server tries to find abc/index.html which actually doesn't exist.So to resolve this , you have wrote configurations on my server i.e to point every request to index.html . I am using node express server to deploy the app. Use the following code to route every request to index.html -
var express = require('express');
var path = require('path')
var app = express();
app.use(express.static(path.resolve(__dirname, "www")));
app.use('/*', function(req, res){
res.sendFile(__dirname+ '/www' + '/index.html');
});
app.set('port', process.env.PORT || 3000);
app.listen(app.get('port'), function() {
console.log("listening to Port", app.get("port"));
});

Ckeditor usage in Ember

I want to use CKEditor with my Ember app.
I am 100% a n00b with Ember, but I'm getting there.
I have tried my darndest to figure this out, but I've gotten nowhere :(
I have tried to use ember-ckeditor. This ended up with the editor throwing a bunch of net::ERR_NAME_NOT_RESOLVED errors for things such as config.js and other "assets" it expected to find in the assets folder.
I have tried ember-cli-ckeditor. Same exact issues as above.
These two addons have pretty lame documentation. For example, I have no idea how provide a custom config file, CSS, etc. Or what if I want to use CkFinder?
The two above addons also throw some depreciated warnings when loading up the server, but I disgress....
I finally tried to manually include ckeditor v4.5.6 in the vendor folder.
I then included in ember-cli-build.js as such: app.import('vendor/ckeditor/ckeditor.js');
I'm not sure if I'm correct in doing this, and if so, how do I include use the editor plugin within my controller or component?
CKEDITOR.replace("content"); as per usual outside of Ember?
Please school me!
To use ckeditor without addons (creating your own component):
Install ckeditor using bower:
bower install ckeditor --save
Install broccoli-funnel, you will need it for ckeditor's assets:
npm install broccoli-funnel --save-dev
In your ember-cli-build.js:
At the top of file requere funnel
var Funnel = require('broccoli-funnel');
In app's options exclude ckeditor's assets from fingerprinting:
var app = new EmberApp(defaults, {
fingerprint: {
exclude: ['assets/ckeditor/']
}
});
Import ckeditor's js and assets:
app.import('bower_components/ckeditor/ckeditor.js');
var ckeditorAssets = new Funnel('bower_components/ckeditor', {
srcDir: '/',
destDir: '/assets/ckeditor'
});
/**
* If you need to use custom skin, put it into
* vendor/ckeditor/skins/<skin_name>
* Also, custom plugins may be added in this way
* (look ckeditor's info for details)
* If you don't need custom skins, you may remove
* ckeditorCustoms
*/
var ckeditorCustoms = new Funnel('vendor/ckeditor', {
srcDir: '/',
destDir: '/assets/ckeditor'
});
return app.toTree([ckeditorAssets, ckeditorCustoms]);
If your app is not in website's root, you may need to put this script in body section of index.html, before other scripts:
<script type="text/javascript">
window.CKEDITOR_BASEPATH = '/path-to/assets/ckeditor/';
</script>
Create a component. Warning: this is a code from my abandoned pet project, and I'm 99% sure that it will not work for you "as is" because of missing dependencies and because it was created for different html layout. But I think it may help anyway. If you wish to try and copy-paste it, here are dependencies:
npm install --save-dev ember-browserify
npm install --save-dev sanitize-html
Component's code:
/* globals CKEDITOR */
import Ember from 'ember';
import layout from '../templates/components/md-ckeditor'; //component's name!
import SanitizeHTML from 'npm:sanitize-html';
export default Ember.Component.extend({
layout: layout,
classNames: ['input-field'],
_editor: null,
bindAttributes: ['disabled', 'readonly', 'autofocus'],
validate: false,
errorsPath: 'errors',
init() {
this._super(...arguments);
const propertyPath = this.get('valueBinding._label');
if (Ember.isPresent(propertyPath)) {
Ember.Binding.from(`targetObject.${this.get('errorsPath')}.${propertyPath}`)
.to('errors')
.connect(this);
}
},
didInsertElement() {
var i18n = this.get('i18n');
if (Ember.isPresent(this.get('icon'))) {
this.$('> span').css('padding-left', '3rem');
}
this._setupLabel();
this._editor = CKEDITOR.inline(this.element.querySelector('.ckeditor'), {
skin: 'minimalist',
toolbar: [
['Cut', 'Copy', 'Paste', 'PasteText', 'PasteFromWord'],
['Undo', 'Redo'],
['Bold', 'Italic', 'Strike'],
['Link', 'Unlink'],
['NumberedList', 'BulletedList', 'Blockquote'],
['Source']
],
linkShowAdvancedTab: false,
linkShowTargetTab: false,
language: i18n.get('locale'),
removePlugins: 'elementspath'
});
this._editor.on('instanceReady', (e) => {
this._updateValidClass();
});
this._editor.on('change', (e) => {
this.set('value', e.editor.getData());
});
this._editor.on('focus', (e) => {
var label = this.$('> label, > i');
label.addClass('active');
});
this._editor.on('blur', (e) => {
var label = this.$('> label, > i');
var text = SanitizeHTML(e.editor.getData(), {
allowedTags: []
}).trim();
if (text !== '') {
label.addClass('active');
} else {
label.removeClass('active');
}
});
},
willDestroyElement()
{
this._editor.destroy();
this._editor = null;
},
id: Ember.computed('elementId', function () {
return `${this.get('elementId')}-input`;
}),
validClass: Ember.computed('value', 'errors', function () {
var errors = this.get('errors');
if (errors && errors.get && errors.get('firstObject')) {
return 'invalid';
} else if (!!this.get('value')) {
return 'valid';
} else {
return '';
}
}),
validClassChanged: Ember.observer('validClass', function () {
Ember.run.once(this, '_updateValidClass');
}),
_updateValidClass() {
if (this._editor && this._editor.container && this._editor.container.$) {
Ember.$(this._editor.container.$).removeClass('invalid valid').addClass(this.get('validClass'));
}
},
_setupLabel() {
const label = this.$('> label, > i');
if (Ember.isPresent(this.get('value'))) {
label.addClass('active');
}
}
});
Template:
{{textarea
id=id
value=value
name=name
required=required
readonly=readonly
disabled=disabled
maxlength=maxlength
class="materialize-textarea ckeditor"
classNameBindings="validate:validate: validClass"
}}
<label for="{{id}}">{{label}}</label>
<small class="red-text">
{{#if errors}} {{errors.firstObject}} {{else}} {{/if}}
</small>
Check next example
https://github.com/ebryn/ember-ckeditor/blob/master/addon/components/ember-ckeditor.js
Or next package ember-cli-ckeditor
https://www.npmjs.com/package/ember-cli-ckeditor

Serve static json file for translations

I'm using ember-i18n for translations and I'm trying to fetch translations live as described in ember-i18n wiki
Instead of loading translations from backend, I would load them from a static file. I've placed files lang.json in /public/i18n/ folder and I retrieve them using a service:
export default Ember.Service.extend({
ajax: inject.service(), // ember-ajax service
i18n: inject.service(),
fetch(lang) {
if (isEmpty(lang) || !ENV.APP.languages.contains(lang)) {
lang = "en";
}
let url = "http://" + window.location.host + "/i18n/" + lang + ".json";
return new Ember.RSVP.Promise((resolve, reject) => {
this.get("ajax").request(url, {
type: "GET"
}).then((json) => {
this.get('i18n').addTranslations(lang, json);
resolve(lang);
}, (params) => {
Ember.Logger.debug(params);
reject();
});
});
}
});
lang.json file contains just the json:
{
"key.foo": "Foo",
"key.bar": "Bar"
}
In dev it works like a charm, but I've some problems running tests. The json retrieved contains the content of the lang.json file but it's not loaded into the i18n service (for example if I run test with -s I see missing translation xxx everywhere.
Furthermore, test execution get slower and slower and after 10-15 tests it throws timeout errors.
Am I doing something that shouldn't be done or there something I'm missing?
Thanks
I'm using:
ember-cli: 2.6.2
ember: ~2.6.0
ember-i18n: ~4.2.1
Just for concept ( for your repo )
1) I open tests/index.html and modify it next way
<script src="assets/vendor.js"></script>
<!-- Next was added -->
<script>
var translations;
$.getJSON('/i18n/en.json').then(function(data){ translations = data; });
</script>
2) inside app/mirage/config.js
export default function() {
this.get("/i18n/:lang", function() {
return window.translations;
});
}
Git diff for my changes here http://pastebin.com/eGwAXM77

Ember 1.10+grunt+EAK: "Could not find <template_name> template or view" after migration from 1.9.1

I'm using Ember App Kit with grunt and I'm trying to switch to Ember 1.10 and can't get HTMLBars working :/
TL;DR
After migration, I've got my HTMLBars templates lodaded in Ember.TEMPLATES but they're not visible either by Ember nor in App.__container.lookup.cache.
Details
The steps I did:
updated ember and ember-data
updated package.json ("grunt-ember-templates": "0.5.0")
updated my Gruntfile.js (grunt.loadNpmTasks('grunt-ember-templates') added a task emberTemplates)
passed the options to emberTemplates:
{
debug: [],
options: {
templateCompilerPath: 'vendor/ember/ember-template-compiler.js',
handlebarsPath: 'vendor/handlebars/handlebars.js',
templateNamespace: 'HTMLBars'
},
'public/assets/templates.js': [
'app/templates/**/*.hbs'
],
};
removed handlebars.js from index.html and replaced ember.js with ember.debug.js
Now, I've got my public/assets/templates.js file generated in a proper way, I had several compilation errors coming from ember-template-compiler, so this part, I assume, is working fine.
Lastly, in the app, I can see all my templates loaded in Ember.TEMPLATES variable but unfortunately, they're not accessible from App.__container__.lookup.cache or App.__container__.lookup('template:<template_name>').
The way I'm trying to render the template that throws an error is (and it's working with Ember 1.9):
export default AuthRoute.extend({
renderTemplate: function() {
this.render();
this.render('user-details', {
into: 'base',
outlet: 'profile',
controller: 'user-details'
});
}
});
What am I missing? Any help would be appreciated.
Bonus question: what is debug field in emberTemplates configuration? If I don't define it, it raises an error (Required config property "emberTemplates.debug" missing.) while compiling. Could that be a possible reason?
Bonus question 2: where should templates.js file go? The intuition tells me /tmp but then, even Ember.TEMPLATES is an empty object...
EDIT [SOLUTION]:
I missed templateBasePath: "app/templates" line in the emberTemplates options. Because of that, Ember.TEMPLATES object was sth similar to this:
{
"app/templates/base.hbs": {},
"app/templates/components/component.hbs": {}
}
instead of:
{
"base.hbs": {},
"components/component.hbs": {}
}
which is the format that Ember resolver (ember-application/system/resolver) in the resolveTemplate method expects.
EDIT: using grunt-ember-templates and this Gruntfile task, I got it working:
emberTemplates: {
options: {
precompile: true,
templateBasePath: "templates",
handlebarsPath: "node_modules/handlebars/dist/handlebars.js",
templateCompilerPath: "bower_components/ember/ember-template-compiler.js"
},
"dist/js/templates.js": ["templates/**/*.hbs"]
}
Differences seem to be precompile: true and point the handlebarsPath to the dependency in node_modules. Also the templateBasePath makes the ids like application instead of templates/application. Or in your case app/templates/application.
To answer your Bonus question 2, put templates.js after you load ember.js but before your app.js. Mine script includes look like this:
<script type="text/javascript" src="/bower_components/ember/ember.debug.js"></script>
<script type="text/javascript" src="/bower_components/ember/ember-template-compiler.js"></script>
<script type="text/javascript" src="/js/templates.js"></script>
<script type="text/javascript" src="/js/app.js"></script>
====================================
EDIT: Ignore this newbness...
It seems like the grunt-ember-templates task is outdated, or its dependencies are outdated. Remove it. I was able to hack together this solution:
Use grunt-contrib-concat instead. The money is with the process option.
concat: {
dist: {
// other concat tasks...
},
templates: {
options: {
banner: '',
process: function(src, filepath) {
var name = filepath.replace('app/templates/','').replace('.hbs','');
var Map = {
10: "n",
13: "r",
39: "'",
34: '"',
92: "\\"
};
src = '"' + src.replace(/[\n\r\"\\]/g, function(m) {
return "\\" + Map[m.charCodeAt(0)]
}) + '"';
return 'Ember.TEMPLATES["'+name+'"] = Ember.HTMLBars.template(Ember.HTMLBars.compile('+src+'));\n';
}
},
files: {
'public/assets/templates.js': 'app/templates/**/*.hbs'
}
}
},
So the whole solution is as follows:
module.exports = {
debug: {
src: "app/templates/**/*.{hbs,hjs,handlebars}",
dest: "tmp/result/assets/templates.js"
},
dist: {
src: "<%= emberTemplates.debug.src %>",
dest: "<%= emberTemplates.debug.dest %>"
},
options: {
templateCompilerPath: 'vendor/ember/ember-template-compiler.js',
handlebarsPath: 'vendor/handlebars/handlebars.js',
templateNamespace: 'HTMLBars',
templateBasePath: "app/templates"
}
};
where all my templates reside in app/templates/ directory.
I'm still using:
<script src="/assets/templates.js"></script>
in index.html.
Maybe somebody will find it useful ;)