Moment + Requirejs confusion with require - requirejs

I can't get my app to see moment, I have tried everything I've seen via googling and on stackoverflow.
require.config({
baseUrl: 'app',
paths: {
'angular': '../lib/angular.min',
'angularMessages': '../lib/angular-messages.min',
'angularResource': '../lib/angular-resource.min',
//moment stuff
"moment": '../lib/moment',
'momentLocale': '../lib/moment-with-locales',
'angular-moment': '../lib/angular-moment.min',
},
shim: {
angular: {
exports : 'angular'
},
"angular-moment": { "deps": ["momentjs"] }
}
});
require([
'app',
'angular'], function (app) {
require([
'moment',
'momentjs',
'momentLocale',
'angular-moment'], function () {
app.init();
});
});
Yet however I can get this to run no problems
// load moment.js as moment
require(['moment'], function(moment) {
// test if moment is loaded
alert(moment().format('dddd, MMMM Do YYYY, h:mm:ss a'));
});
Note I stripped out the other stuff in my require js as there are no problems whatever with those resources.

Related

Problems with require and a html file

I'm trying to require a html template file as part of my KnockoutJS component registration. According to Chrome's network tab, all the other files load fine except login-template.html which appears as
file:///home/leon/Dev/KnockOutJS/Component%20Example/js/lib/text.js
in my local file path. What Am I doing wrong here?
requirejs.config({
baseUrl: 'js/lib',
paths: {
app: '../app',
jquery: 'jquery-3.3.1',
knockout: 'knockout-3.4.2',
}
});
requirejs(['jquery', 'knockout', 'app/login-component', 'text!app/login-template.html'],
function ($, ko, loginComponent, loginTemplate) {
ko.components.register('login-component', {
viewModel: { require: loginComponent },
template: { require: loginTemplate }
});
ko.applyBindings();
});
You need to install the text plugin from https://github.com/requirejs/text

requireJs first steps - $ undefined

try to get familiar with require JS - but I don't understand what is wrong with this setup - can't call the $(document).foundation() because $ is undefined.
requirejs.config({
baseUrl: '/js',
paths: {
jQuery: 'script.php?file=jquery.min.js',
foundation: 'script.php?file=foundation.min.js'
}
});
require(['jQuery'], function($) {
require(['foundation'], function() {
$(document).foundation(); // $ undefined?
});
// ... more code with different require sections
});
Consider moving your logic into a separate file, for example app.js
Then, change the require(['jQuery'], function($) { ... call to something like requirejs(['app']).
In app.js you should define a module, something like:
define(['jQuery', 'foundation'], function($, foundation) {
$(document).foundation();
});

Proper way to share dependencies in Karma with RequireJS

I use Karma and jasmine for my unit tests. I have a main-test.js file to configure karma, and a main.js to configure my application.
main-test.js:
//
...
//
require.config({
baseUrl: '/base',
paths: {
jquery: 'components/jquery/dist/jquery', // this is copypaste
//another dependencies
},
//
...configuration
//
});
main.js
require.config({
paths: {
jquery: 'components/jquery/dist/jquery', // this is copypaste
//another dependencies
},
//
...configuration
//
});
What is the proper way to share paths between those two configurations?
We met the same problem with my team and ended up by requiring the main config into test-main.js:
// requiring global requireJS config
require(['/base/config/require.conf.js'], function() {
'use strict';
// first require.config overload: Karma specific
require.config({
baseUrl: '/base/src',
paths: {
'angularMocks': '../bower_components/angular-mocks/angular-mocks'
},
shim: {
'angularMocks': {
deps: ['angular']
}
}
});
require(['angularMocks'], function() {
var specFiles = [];
for (var file in window.__karma__.files) {
if (window.__karma__.files.hasOwnProperty(file)) {
if (/\/base\/src\/.*_test\.js$/.test(file)) {
specFiles.push(file);
}
}
}
// second overload to include specFiles and start Karma
require.config({
deps: specFiles,
callback: window.__karma__.start
});
});
});
Our starter app structure for projects using AngularJS + RequireJS is available here: angular-requirejs-ready.
I do not claim this is the proper way, only our way ;)

Merge requireJS files with grunt

I want to combine the js used in a simple requireJS solution.
This is my main.js
require.config({
paths: {
'jquery': 'jquery-2.0.3.min',
'dataTable': 'jquery.dataTables'
}
});
define(['jquery','dataTable'], function($) {
'use strict';
$(function () {
$('.tablesorter').dataTable();
});
});
And my gruntFile.js
module.exports = function(grunt) {
grunt.initConfig({
requirejs: {
production: {
options: {
name: "main",
baseUrl: "",
mainConfigFile: "main.js",
out: "optimized.js"
}
}
}
});
grunt.loadNpmTasks('grunt-contrib-requirejs');
grunt.registerTask('default', 'requirejs');
};
WHen I load optimized.js in the html like this
<script src="optimized.js"></script>
I get
ReferenceError: require is not defined
You must include require.js on the page before including optimized.js.
Like so:
<script src="/path/to/require.js"></script>
<script src="/path/to/optimized.js"></script>
I found out that requireJS only accepts 'main' as the data-main src
So instead of
<script data-main="optimized" src="require.js"></script>
I got
<script data-main="prod/main" src="require.js"></script>
And changed the grunt config to
requirejs: {
production: {
options: {
name: "main",
baseUrl: "",
mainConfigFile: "main.js",
out: "prod/main.js"
}
}
}
Looking at the comments in addition to the question, first I see that George Raith hit on one problem with your code: you needed to include require.js.
Then you said that $('.tablesorter').dataTable() is not executed. That's because you use define rather than require. Use this:
require(['jquery','dataTable'], function($) {
'use strict';
$(function () {
$('.tablesorter').dataTable();
});
});
A call to define only registers a module with RequireJS. It does not execute a module. So it is not surprising that $('.tablesorter').dataTable() would not execute. You have to use the form of require that takes a callback to do what you want to do.
As for including RequireJS with your project into a single file, you have to ask for it explicitly. The optimizer's documentation gives this example:
node ../../r.js -o baseUrl=. paths.requireLib=../../require name=main include=requireLib out=main-built.js
Your configuration (updated from the one in the question) would look something like this:
grunt.initConfig({
requirejs: {
production: {
options: {
name: "main",
baseUrl: "",
mainConfigFile: "main.js",
paths: {
requireLib: <path to require js>
},
out: "optimized.js",
include: "requireLib"
}
}
}
});
(I've not run this code, so lookout for typos.) You have to put the path to your require.js file for requireLib. We have to use requireLib as a module name because require is reserved. With this kind of configuration, you should be able to load only your optimized.js file.

Load files in specific order with RequireJs

I'm new to RequireJS and I'm stuck with the loading order.
I have a global project configuration that I need to be loaded before the modules located in js/app/*.
Here's my struture :
index.html
config.js
js/
require.js
app/
login.js
lib/
bootstrap-2.0.4.min.js
Here's the config.js file :
var Project = {
'server': {
'host': '127.0.0.1',
'port': 8080
},
'history': 10, // Number of query kept in the local storage history
'lang': 'en', // For future use
};
And here's my requirejs file (app.js) :
requirejs.config({
//By default load any module IDs from js/lib
baseUrl: 'js/lib',
//except, if the module ID starts with "app",
//load it from the js/app directory. paths
//config is relative to the baseUrl, and
//never includes a ".js" extension since
//the paths config could be for a directory.
paths: {
bootstrap: '../lib/bootstrap-2.0.4.min',
app: '../app',
},
shim: {
'app': {
deps: ['../../config'],
exports: function (a) {
console.log ('loaded!');
console.log (a);
}
} // Skual Config
},
});
var modules = [];
modules.push('jquery');
modules.push('bootstrap');
modules.push('app/login');
// Start the main app logic.
requirejs(modules, function ($) {});
But sometimes, when I load the page, I have a "Project" is undefined, because login.js has been loaded BEFORE config.js.
How can I force config.js to be loaded at first, no matter what ?
Note: I saw order.js as a plugin for RequireJS but it's apparently not supported since the v2, replaced by shim.
Ran into a similar problem today - we have bootstrapped data that we want to make sure is loaded before anything else, and that the module exposing that data is set up before any other modules are evaluated.
The easiest solution I found to force load order is to simply require a module be loaded before continuing on with app initialization:
require(["bootstrapped-data-setup", "some-other-init-code"], function(){
require(["main-app-initializer"]);
});
There's a possible solution to build a queue for modules to be loaded. In this case all modules will be loaded one-by-one in exact order:
var requireQueue = function(modules, callback) {
function load(queue, results) {
if (queue.length) {
require([queue.shift()], function(result) {
results.push(result);
load(queue, results);
});
} else {
callback.apply(null, results);
}
}
load(modules, []);
};
requireQueue([
'app',
'apps/home/initialize',
'apps/entities/initialize',
'apps/cti/initialize'
], function(App) {
App.start();
});
You won't have to worry about the load order if you define your js files as AMD modules. (Or you can use the shim config if you can't modify the config.js and login.js to call define).
config.js should look something like this:
define({project: {
'server': {
'host': '127.0.0.1',
'port': 8080
},
'history': 10, // Number of query kept in the local storage history
'lang': 'en', // For future use
}});
login.js:
define(['jquery', '../../config'], function($, config) {
// here, config will be loaded
console.log(config.project)
});
Again, shim config should only be used if calling define() inside the modules is not an option.

Resources