Inject kendo ui with requirejs - kendo-ui

The documentation on kendo ui and requirejs seems to miss some stuff.
They tell me how to use kendo.web.min which have everything included:
http://www.kendoui.com/blogs/teamblog/posts/13-05-08/requirejs-fundamentals.aspx
(search for keyword 'shim')
but I am not interested in adding the big 2MB kendo.web.min script, I just want to shim the
kendo.grid.min but this file has a dependency to kendo.data.min which again has a dependency
to kendo.core.min.
How can I tell requirejs to load also kendo.data.min and kendo.core.min before kendo.grid.min is loaded and after jquery has been loaded. I just guess this would be the correct order.
This is what I have tried from the above telerik link:
requirejs.config({
paths: {
'text': '../Scripts/text',
'durandal': '../Scripts/durandal',
'plugins': '../Scripts/durandal/plugins',
'transitions': '../Scripts/durandal/transitions',
'knockout': '../Scripts/knockout-2.3.0',
'jquery': '../Scripts/jquery-2.0.3',
'kendoGrid': '../Scripts//kendo.grid.min',
},
shim: {
"kendoGrid": {
deps: ["jquery"]
}
}
});
What is the correct way of defining the kendo dependencies like kendo.data and kendo.core ?
At the moment I am getting an exception on application startup from durandal in the systems.js saying:
"Failed to load composed module (viewmodels/DocumentBrowser). details: The property \"jQuery\" of an undefined or null reference can not be 'accessed'.
I know this error is not directly about kendo, but since I introduced kendo ui with requirejs in the DocumentBrowser module I get this exception!
UPDATE
According to CodingWhitSpike`s advise I have changed my requirejs configuration:
requirejs.config({
paths: {
'text': '../Scripts/text',
'durandal': '../Scripts/durandal',
'plugins': '../Scripts/durandal/plugins',
'transitions': '../Scripts/durandal/transitions',
'knockout': '../Scripts/knockout-2.3.0',
'jquery': '../Scripts/jquery-2.0.3',
'moment': '../Scripts/moment',
k: "../Scripts/kendo"
}
});
define(['durandal/app', 'plugins/dialog', 'knockout', 'services/dataservice', 'plugins/router', 'moment', 'k/kendo.grid.min'],
function (app, dialog, ko, dataservice, router, moment, kendoGrid) {
$("#grid").kendoGrid(...); => kendoGrid is instantiated and it works :)
});

This is taken from the official Kendo docs at http://docs.kendoui.com/getting-started/using-kendo-with/using-kendo-with-requirejs
<!-- first, load RequireJS -->
<script src="require.js"></script>
<!-- configure RequireJS with two logical paths:
- "app/" will be used for your files
- "k/" will be for Kendo UI modules -->
<script>
requirejs.config({
paths: {
app: "/path/to/your/files",
k: "http://cdn.kendostatic.com/VERSION/js"
}
});
require([
"http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js",
"app/foo",
"app/bar",
"k/kendo.menu.min",
"k/kendo.grid.min"
], initApp);
function initApp() {
// main entry point of your application
}
</script>
Assuming that kendo has set up dependencies of their modules correctly, setting up a path like k: "http://cdn.kendostatic.com/VERSION/js which points to the modules directory (NOT one individual module) and use a module in like k/kendo.grid.min should all that's required.

Related

RequireJS data-main does not load from html files at different paths

Using RequireJS successfully for a single page application for quite some time. Finally adding JS unit tests to exercise model classes. I have a single config for src modules and another for test modules. (I want to keep test files out of the shipping distribution)
I can load src from index.html and test from LocationTest.html only if both files are in the same top-level folder. I would like to move LocationTest.html inside the test folder, but no change to data-main or the test config file seems to work.
Here is the file layout for the happy path...
/www
- index.html
- LocationTest.html
- js
- src
- lib
- require.js
- require_src_config.js
- require_main.js
- require_test_config.js
- require_test.js
- model
- Location.js
- (other src model classes)
- test
- lib
- (jasmine libs)
- model
- LocationTest.js
- (other test model classes eventually)
index.html
...
<script type='text/javascript' data-main='js/src/lib/require_main' src='js/src/lib/require.js'></script>
...
LocationTest.html
...
<script type='text/javascript' data-main='js/src/lib/require_test' src='js/src/lib/require.js'></script>
...
js/src/lib/require_src_config.js
requirejs.config({
// Base URL for main application
baseUrl: 'js',
// Shortcuts to modules relative to baseUrl
paths: {
Location: 'src/model/Location'
(many other modules...)
}
});
js/src/lib/require_test_config.js
requirejs.config({
baseUrl: 'js',
// Paths (no extension)
paths: {
// Tests
LocationTest: 'test/model/LocationTest',
// Framework
jasmine: 'test/lib/jasmine/jasmine',
jasmineHtml: 'test/lib/jasmine/jasmine-html',
jasmineBoot: 'test/lib/jasmine/boot',
},
// Make external libraries compatible with requirejs (AMD)
shim: {
jasmineHtml: {
deps : ['jasmine']
},
jasmineBoot: {
deps : ['jasmine', 'jasmineHtml']
}
}
});
js/src/lib/require_main.js
requirejs(['./require_src_config'], function (require_src_config) {
(Application Code)
});
js/src/lib/require_test.js
requirejs(['./require_src_config'], function (require_src_config) {
requirejs(['./src/lib/require_test_config'], function (require_test_config) {
requirejs(['jasmineBoot'], function (require) {
requirejs(['LocationTest'], function (LocationTest) {
// Trigger Jasmine
window.onload();
});
});
});
});
The above all works, although I do not understand why I had to revise the path to require_config_test.js in require_test.js. The baseUrl for both configs is 'js'.
I would like to move LocationTest.html to js/test/model.
1) What should my data-main be set to?
2) How (and why) does this impact require_test.js settings?
3) Is there a better way to nest (or not) the configs for src and test to ensure src gets loaded first?
I was hoping to only have to set data-main to the path of the file with the entrypoint and be flexible to move things around. Thanks for your help!

How to combine `css-modules` with normal `sass`, preferably in `webpack`

TLDR: How to combine css-modules with normal sass, preferably in webpack.
The Setup:
I am working on the styling build process for an e-commerce website. The site's styles are currently done in sass along with the js through a gulp browserify build process.
I have recently added a single page app that is built using react with webpack and babel. Inside of that application I am taking advantage of css-modules provided by webpack to scope the class names to each react component.
The problem:
I would like to incorporate the styles from the webpack css-modules build in with the main styling bundle for the site. To do this, I was considering building a webpack configuration to build the styles for the whole site. The problem I have is how to get the styles which are currently built by the single page webpack configuration and inject just the style chunk into a global webpack configuration that handles styles for the whole site. I should mention that I would like to keep the two configurations as separate as possible
The Questions:
Is there a proper way of having decoupled webpack builds where one is still able to use chunks from the other?
If so, how do I do it so that the css-module setup stays in the single page configuration, and the extract-text-webpack part along with a boring sass build goes into a global configuarion?
If not, how should I go about having one section of sass go through the css-modules workflow, and still combine it with the bundle from the rest of the site.
Thanks in advance.
EDIT
based on #Alexandr Subbotin's answer, I have updated my webpack to look something like the code below. I did have to change names and paths because of the code belongs to my employer, so there may be slight errors.
var ExtractTextPlugin = require('extract-text-webpack-plugin');
const JSDIR = './build/js/';
const STYLES = './build/css/bundle.css';
module.exports = {
entry : {
'styles' : './src/styles.scss',
'app' : './src/index.js',
// a javascript file that includes the root of the single page app.
'single-page' : './src/single-page/styles-entry.js',
},
output : {
path : JSDIR,
filename : '[name].js', // normally compiles my
publicPath: 'http://localhost:8080/',
},
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
loader : 'babel-loader',
query : {
presets: [
'react','es2015','stage-0',
]
},
},
{
test : /\.scss$/,
loader: ExtractTextPlugin.extract('style?sourceMap', 'css?-url&sourceMap!sass?sourceMap'),
exclude : /\/single-page\//,
},
{
test : /\.scss$/,
loader: ExtractTextPlugin.extract(
'style?sourceMap',
'css?-url&modules&importLoaders=1&localIdentName=SinglePage__[name]__[local]!sass?sourceMap'
),
include : /\/single-page\//,
}
]
},
plugins : [
new ExtractTextPlugin(STYLES, {
allChunks : true,
}),
],
resolve : {
alias: {
"eventEmitter/EventEmitter": "wolfy87-eventemitter",
},
extensions: ['', '.js','.jsx'],
},
}
If I understood your question you want to apply css-modules only to one part of your application and leave simple sass building process in other parts.
To do this you can use exclude and include options in loaders. I.e. if you have your single page application inside single-page directory your webpack config can be:
module: {
entry: {
// it is your global sass styles
application_css: './css/application.scss',
// it is main file of your SPA bundle. Somewhere inside you will use require('./styles.scss') that should be processed by css-modules
spa_index: './single-page/index.js'
},
loaders: [
...,
{
// This loader will build all your sass that are not in `single-page` directory
test: /\.scss$/,
loader: ExtractTextPlugin.extract('style', 'css!sass'),
exclude: /\/single-page\//
},
{
// This loader will handle all your css module in `single-page` directory
test: /\.scss$/,
loader: 'style!css?modules!sass',
include: /\/single-page\//
},
],
...
}
So, in this case all css from single-page/ will use css modules, and the rest won't.
EDIT:
If you take a look in API section of ExtractTextPlugin documentation you find
The ExtractTextPlugin generates an output file per entry, so you must use [name], [id] or [contenthash] when using multiple entries.
In your example you have have two chunks with css (styles and single-page), but only one output ./build/css/bundle.css. If you change your output to ./build/css/[name].css your will have two css files: styles.css with your global css and single-page.css with SPA styles.

AMD - want to load viewModel when main.js is called instead of defining each view model in require.configure.js

While using MVC and requireJs for AMD i am stuck in a problem where i want to load the view-model script when the main script file for respective module is called instead of defining all the view-models in require.configure.js
Here is the Sequence of Code:
BundleConfig.cs
bundles.Add(new ScriptBundle("~/bundles/app").Include(
"~/Scripts/Common/require.configure.js",
"~/Scripts/Common/require.js"));
Index.cshtml
#section scripts {
#Scripts.Render("~/bundles/app")}
<script data-main="Scripts/BookService/Testing/HomeMain"></script>
require.configure.js
var require = {
baseUrl: "/",
paths: {
"bootstrap": "Scripts/Common/bootstrap",
"jquery": "Scripts/Common/jquery-1.10.2",
"knockout": "Scripts/Common/knockout-3.3.0",
"knockout-projections": "Scripts/Common/knockout-projections.min",
"domready": "Scripts/Common/domReady",
/////////View Models///////////////////////////////////////
"HomeViewModel": "Scripts/BookService/Testing/HomeViewModel"
},
shim: {
"bootstrap": {
deps: ["jquery"]
}
}}
HomeMain.js
require(['knockout', 'HomeViewModel'], function (ko, appViewModel) {
ko.applyBindings(new appViewModel());});
HomeViewModel.js
define(['jquery','knockout'], function ($,ko) {
return function appViewModel() {
//viewModel here
}
});
Scripts File hierarchy:
You can use require.config for adding to config at run time. I am not sure if this is officially supported (will try to find references), but when I tried it worked.
Use it like following to add new paths to your config whenever you want.
require.config({
paths : {
"HomeViewModel" : '/path/to/homeviewmodel'
}
});
Take care of the absolute and relative path as per requirement.

Attaching multiple views to a controller in ExtJS 4 MVC

This is using the standard ExtJS 4 MVC library and structure.
I am trying to attach multiple views to a single controller so I can create instances of them later to add to panels. Unfortunately I am getting errors about the view when I add the second one and ExtJS is blocking the syntax errors it appears so that I am unable to see where the issue is.
If I comment out ViewOrders from the list below it works fine, but if it is in there then I get the following error:
An uncaught error was raised with the following data: ext-all-debug-with-comments.js (line 7864)
msg:
"The following classes are not declared even if their files have been loaded: 'PVAL_App.view.ViewOrders'. Please check the source code of their corresponding files for possible typos: 'app/view/ViewOrders.js'"
sourceClass: "Ext.Loader"
sourceMethod: "onFileLoaded"
Here is my controller:
Ext.define('PVAL_App.controller.Viewport', {
extend: 'Ext.app.Controller',
views: [
'Viewport', 'ViewOrders'
],
init: function() {
console.log('Viewport controller init()');
}
});
Here is my ViewOrders view:
Ext.define('PVAL_APP.view.ViewOrder', {
/* Begin Definitions */
extend: 'Ext.panel.Panel',
alias: 'widget.ViewOrders',
requires: [
'Ext.panel.Panel',
'Ext.data.ArrayStore'
],
border:false,
layout: 'fit',
//autoScroll: true,
initComponent: function() {
}
});
I doubt this is needed but this is my application file:
Ext.Loader.setConfig(
{
enabled: true
});
Ext.application({
name: 'PVAL_App',
appFolder: 'app',
autoCreateViewport: true,
controllers: [
'PVAL_App', 'Viewport'
],
launch:function() {
// Nothing yet.
//console.log(this.controllers);
}
});
I cannot seem to figure out if it is a syntax error or if this is an issue with the framework. I have experienced close to the same issue if I try to link to another controller from within one which makes me believe that this might be a constraint of the framework.
The problem here is that the class name in your app/view/ViewOrders.js script does not match the view name. Instead of Ext.define('PVAL_APP.view.ViewOrder', { you need the plural (and correct case) Ext.define('PVAL_App.view.ViewOrders', {. Either that our you can change your filename and refernece to the singular and just correct the case.

Dojo Build with NLS - requireLocalization(..) fail?

My question, while at first somewhat similar to this one, seems to be a more basic question - and might be signaling a bug in the build system. I've created a custom build for my dojo application. I only build one layer right now, here's what the profile script/object looks like:
dependencies = {
stripConsole: "all",
action: "release",
optimize: "shrinksafe",
releaseName: "myProject",
// list of locales we want to expose
localeList: "en-gb,en-us,de-de",
layers: [
{
// Name: a relative path from the dojo.js in the desination directory.
name: "../../myProject.js",
dependencies: [
"myPackage.MyDataStore",
// MyWidget depends on a few other widgets, and has its own
// translation files.
"myPackage.MyWidget"
]
}
],
prefixes: [
// These paths are relative to the location of dojo.js
[ "dijit", "../dijit" ],
[ "dojox", "../dojox" ],
[ "myPackage", "../../../src/myPackage" ]
]
}
When I run a build with that description it outputs files in the following directory structure:
release/
release/myProject/
release/myProject/dijit/
... dijit ...
release/myProject/dojo/
... dojo ...
release/myProject/dojox/
... dojox ...
release/myProject/myPackage/
... my custom package ...
release/nls/
myProject_en-us.js
myProject_de.js
etc..
../myproject.js
../myProject.js.uncompressed.js
Finally, in my test HTML page - I've got the following:
<script type="text/javascript">
var djConfig = {
debug: true,
parseOnLoad: false,
modulePaths: { // paths to directories in relation to dojo's location.... hurr.
'myPackage': '../myPackage',
'dojox': '../dojox',
'dijit': '../dijit'
}
};
</script>
<script type="text/javascript" src="./release/myProject/dojo/dojo.js.uncompressed.js"></script>
<script type="text/javascript" src="./release/myProject.js.uncompressed.js"></script>
<script type="text/javascript">
dojo.addOnLoad(function(){
dojo.require('myPackage.MyDataStore');
dojo.require('myPackage.MyWidget');
var store = new myPackage.MyDataStore();
var widget = new myPackage.MyWidget({
store: store
}, dojo.byId('testWidget'));
widget.startup();
});
</script>
But unfortunately, Firebug spits this out at me:
Bundle not found: MyWidget in myPackage , locale=en-us
What I Think is Happening
I've traced through some of the code leading up to the above error and it seems like the dojo.i18n._preloadLocalizations() call at the end of the file doesn't actually load in the correct nls file from ./release/nls.
Any idea how to fix this without resorting to manually including the nls files with <script> tags?
It's a bug of dojo, you should not use '..' in your layers name in case it will generate a NLS package.
please refer to http://bugs.dojotoolkit.org/ticket/5225

Resources