RequireJS loading jquery-ui fails after optimization - jquery-ui

I'm not sure what causes this, but jquery-ui doesn't seem to work after optimization.
Without optimization, the project runs fine. $ contains $.ui. (Let's call this develop)
After optimization, functions depending on jquery-ui fail because $.ui does not exist.
I've been messing around with shims and requires for hours, but the result is always the same (or worse, $ not even working, although it still works in the non-optimized version.
What piece of logic am I missing?
requirejs.config({
baseUrl : 'js',
waitSeconds : 10,
urlArgs : 'cache='+Date.now(),
paths: {
"conf" : "remix/config",
"jquery" : "lib/jquery",
"jqueryUi" : "lib/jquery.ui",
"domReady" : "lib/domReady",
"bootstrap" : "lib/bootstrap",
"jsviews" : "lib/jsviews"
},
// I've had many configurations.
// Basically, develop almost always works, optimized never works.
shim: {
"jqueryUi" : {
deps : ['jquery']
},
"jsviews" : {
deps : ['jqueryUi']
},
"bootstrap" : {
deps : ['jsviews']
}
}
});
require(['domReady!', 'jsviews', 'jqueryUi', 'bootstrap'], function() {
console.log($);
// Develop: $.ui exists
// Optimized: $ exists, $.ui does not.
// (And jsviews only in some modules.)
});

According to answer: https://stackoverflow.com/a/17536078/2463365 and refernced tutorial: Load jQuery UI with requireJS.
I've just added exports: '$'
shim: {
"jqueryUi" : {
exports : '$',
deps : ['jquery']
},
and it works.

Related

Rollup.js code splitting - Prevent extra bundle to be created

I'm trying to generate two bundles (only two) using Rollup.js:
commonBundle.js
bundle2.js
bundle2.js depends on commonBundle.js.
The current result of rollup -c is actually 3 files instead of the 2 I want:
commonBundle.js
bundle2.js
commonDep-6c053814.js
Yes, commonDep.ts is indeed used by both commonBundle.ts and bundle2.ts. But since bundle2.ts depends on commonBundle.ts I was expecting the common dependency (commonDep.ts) to be included in the resulting commonBundle.js, not to be a separate bundle!
Is there a way to make all shared dependencies to be bundled inside a single bundle that needs to be imported by the others?
rollup.config.mjs :
export default {
input: {
commonBundle: "./src/commonBundle.ts",
bundle2: "./src/bundle2.ts"
},
output: {
dir: "./public",
format: "es"
},
plugins: [resolve({ browser: true }), commonjs(), typescript()]
};
commonBundle.ts :
import { sayHello } from "./commonDep";
export * from "./commonDep"; // export all common dependencies!
export function commonBundleFunction() {
sayHello("from common bundle");
}
bundle2.ts :
import "./commonBundle"; // depends on the common bundle!!!
import { sayHello } from "./commonDep";
export function bundle2Function() {
sayHello("from bundle2");
}
commonDep.ts :
export function sayHello(name: string) {
console.log("Hello " + name);
}

including devdependencies in package.json

I'd like to generate my devDependencies based on need. For this I have an array in my generator and some operations like this:
var FiddleGenerator = generator.Base.extend({
init: function() {
this.devDependencies = [];
},
//...excluded for brevity
gruntConfigure: function() {
this.devDepedencies = [
'grunt',
'grunt-contrib-watch',
'grunt-contrib-connect'
];
},
installStuff: {
if(this.option('skip-install')) return;
this.npmInstall(this.devDependencies, { saveDev: true });
}
});
The issue here is when the user opts to skip the npm installation and later does it manually (i.e. npm install) nothing gets installed.
However, I cannot simply write a package.json file like that...what versions do I put against each package in order to have them look like the following:
"devDependencies": {
"grunt": "~0.4.2",
"grunt-contrib-watch": "~0.5.3",
"grunt-contrib-connect": "^0.7.0"
}
Just write the devDependencies to the package.json file manually inside the JS code (this.fs.writeJSON). No need to use npmInstall() for that.
You can see this being done here: https://github.com/yeoman/generator-node/blob/master/generators/gulp/index.js#L38-L69

Getting Karma, 6to5ify and Istanbul to play ball

I have Browserify, 6to5ify and Karma to play nice, successfully running my specs. When I add code coverage however, things go south. I've tried several approaches:
Add browserify-istanbul transform to my karma.conf.js. However, this results in it trying to run instrumentation on my spec-files as well it would appear.
Run coverage preprocessor on my source files. But because istanbul (even douglasduteil/karma-coverage#next) doesn't read my 6to5ify browserify transform, this crashes immediately on the first file it tries to parse (because of the import statement), or when I use karma-coverage#next, it doesn't respect the browser mapping in my package.json (mobile project, mapped Backbone to Exoskeleton).
Right now my karma.conf.js looks like this:
module.exports = function(karma){
karma.set({
frameworks: ["browserify", "mocha", "chai-sinon"],
browserify: {
debug: true,
extensions: [".js", ".hbs"],
transform: ["6to5ify", "hbsfy"]
},
reporters: ["dots", "osx", "junit", "coverage"],
coverageReporter: {
type: "text"
},
junitReporter: {
outputFile: "spec/reports/test-results.xml"
},
preprocessors: {
"src/javascript/**/*": ["coverage"],
"spec/**/*": ["browserify"]
},
browsers: ["PhantomJS"],
files: ["spec/unit/**/*Spec.js"],
logLevel: "LOG_DEBUG",
autoWatch: true
});
};
I'm kind of lost how to get this all working together. I tried following these instructions, but that didn't work because it didn't follow my browser node in package.json. Any help would be greatly appreciated.
So, apparently I need browserify-istanbul, and I need the browserify configure hook, like so:
var to5ify = require('6to5ify');
var hbsfy = require('hbsfy');
var cover = require('browserify-istanbul');
var coverOptions = {
ignore: ['**/*Spec.js', '**/lib/*.js', '**/fixtures/*.hbs'],
defaultIgnore: true
}
module.exports = function(karma){
karma.set({
frameworks: ["browserify", "mocha", "chai-sinon"],
browserify: {
debug: false,
extensions: [".js", ".hbs"],
configure: function(bundle){
bundle.on('prebundle', function(){
bundle
.transform(to5ify)
.transform(hbsfy)
.transform(cover(coverOptions));
});
}
},
reporters: ["dots", "osx", "junit", "coverage"],
coverageReporter: {
type: "text"
},
junitReporter: {
outputFile: "spec/reports/test-results.xml"
},
preprocessors: {
"spec/**/*": ["browserify"]
},
browsers: ["PhantomJS"],
files: ["spec/unit/**/*Spec.js"],
logLevel: "LOG_DEBUG",
autoWatch: true
});
};

how to control how wiredep generates bower file path and how to control which files is added/removed

my app has directory as follows
app -> appName -> index.html (js,css)
and for some reason, this appName wrapper folder is messing up wiredire
{ dest: '.tmp/concat/scripts/vendor.js',
src:
[ '../bower_components/es5-shim/es5-shim.js',
'../bower_components/angular/angular.js',
'../bower_components/json3/lib/json3.js',
'../bower_components/angular-resource/angular-resource.js',
'../bower_components/angular-cookies/angular-cookies.js',
'../bower_components/angular-sanitize/angular-sanitize.js',
'../bower_components/angular-animate/angular-animate.js',
'../bower_components/angular-touch/angular-touch.js',
'../bower_components/angular-route/angular-route.js' ] },
this is what would've been produced if directory is as follows
app -> index.html(js,css)
{ dest: '.tmp/concat/scripts/vendor.js',
src:
[ 'bower_components/es5-shim/es5-shim.js',
'bower_components/angular/angular.js',
'bower_components/json3/lib/json3.js',
'bower_components/angular-resource/angular-resource.js',
'bower_components/angular-cookies/angular-cookies.js',
'bower_components/angular-sanitize/angular-sanitize.js',
'bower_components/angular-animate/angular-animate.js',
'bower_components/angular-touch/angular-touch.js',
'bower_components/angular-route/angular-route.js' ] },
and wiredep does change the index.html's script content and how can I control that flow? sometimes its stripping out angular-sanitize from its script[src]
You Should use the replace option of wiredep:
wiredep(
{
fileTypes: {
html: {
replace: {
js: '<script src="/app/appName/{{filePath}}"></script>'
}
}
}
})
Will generate:
<script src="/app/appName/bower_components/angular/angular.js"></script>
This is my gulp setup (same principle apply to Grunt, just pass the same options to it).
gulp.task('wiredep' , function()
{
return gulp.src('./app/index.html')
.pipe(wiredep({
'ignorePath': '../'
}))
.pipe(gulp.dest('./app'));
});
You can look at the wiredep source code in the lib/inject-dependencies.js (line:80~85)
map(function (filePath) {
return $.path.join(
$.path.relative($.path.dirname(file), $.path.dirname(filePath)),
$.path.basename(filePath)
).replace(/\\/g, '/').replace(ignorePath, '');
}).
It just replace the bit you supply (or not if you don't give it one).
Hope that helps.
Have you tried adding cwd to the options block?
Ex:
// Automatically inject Bower components into the app
wiredep: {
options: {
cwd: 'app/appName'
}
....
}

Trying to use jqplot with jquery mobile, marionette and requirejs

I am trying to use jqplot with Jquery mobile, marionette and requirejs. I have included all jqplot required CSS as well as script files in head tags, but when i am trying to plot a chart using below code
define([ 'jquery', 'plot' ],
function($) {
console.log("Success..Inside Offer Page Script.");
console.log("Plot..."+$.jqplot);
console.log("jquery..."+$);
$.jqplot.config.enablePlugins = true;
var s1 = [ 2, 6, 7, 10 ];
var ticks = [ 'a', 'b', 'c', 'd' ];
plot1 = $.jqplot('chart1', [ s1 ], {
seriesDefaults : {
renderer : $.jqplot.BarRenderer,
pointLabels : {
show : true
}
},
axes : {
xaxis : {
renderer : $.jqplot.CategoryAxisRenderer,
ticks : ticks
}
},
highlighter : {
show : false
}
});
});
it gives me errors like
Uncaught TypeError: undefined is not a function jqplot.barRenderer.js:41
(line 41: $.jqplot.BarRenderer.prototype = new $.jqplot.LineRenderer();)
Uncaught TypeError: Cannot call method 'push' of undefined jqplot.pointLabels.js:377
(line 377: $.jqplot.postSeriesInitHooks.push($.jqplot.PointLabels.init);)
The plot in my above code's define is
define([
'../scripts/ext_libs/jquery.jqplot'
],
function () {
var plot;
require([
'../scripts/ext_libs/jqplot.barRenderer',
'../scripts/ext_libs/jqplot.pointLabels',
'../scripts/ext_libs/jqplot.categoryAxisRenderer',
],
function () {
plot = $.jqplot;
});
return plot;
});
Can anyone please help me how can i solve these errors. Is their a problem using jqplot with requirejs?
Thanks in advance.
I'm not using marionette, but everything else works fine on my side. I have a jqplot module like this:
define([
'../js/plugins/jqplot/jquery.jqplot'
, 'css!../js/plugins/jqplot/jquery.jqplot'
],
function () {
var plot;
require([
'../js/plugins/jqplot/plugins/jqplot.barRenderer'
, '../js/plugins/jqplot/plugins/jqplot.logAxisRenderer'
, '../js/plugins/jqplot/plugins/jqplot.categoryAxisRenderer'
, '../js/plugins/jqplot/plugins/jqplot.canvasAxisTickRenderer'
, '../js/plugins/jqplot/plugins/jqplot.canvasTextRenderer'
, '../js/plugins/jqplot/plugins/jqplot.pointLabels'
, '../js/plugins/jqplot/plugins/jqplot.enhancedLegendRenderer'
],
function () {
plot = $.jqplot;
});
return plot;
}
);
which I'm requiring requiring normally from my page script like this:
require(["plot"], function (plot) {
// do something here with plot or... $.jqplot
};
You should be able to use $.plot right away, because once you require the module, jqplot will be available on $.
EDIT:
Try this:
define([ 'jquery', 'plot' ],
function($) {
console.log("Success..Inside Offer Page Script.");
console.log($);
console.log($.jqplot);
$.jqplot.config.enablePlugins = true;
var s1 = [ 2, 6, 7, 10 ];
var ticks = [ 'a', 'b', 'c', 'd' ];
plot1 = $.jqplot('chart1', [ s1 ], {
seriesDefaults : {
renderer : $.jqplot.BarRenderer,
pointLabels : {
show : true
}
},
axes : {
xaxis : {
renderer : $.jqplot.CategoryAxisRenderer,
ticks : ticks
}
},
highlighter : {
show : false
}
});
});
Bit late to the game but.... above doesn't work because require is async to return, so able to return jqplot without any jqplot plugins loaded! async safe solution below
Nasty problem, as it's a chain of three dependencies
jquery is required for jqplot which is required for jqplot plugins, I have a simpler solution based on the same lines as the one above
first do your requirejs "main.js" config like so
requirejs.config({
paths: {
"jquery": "path/to/jquery-1.10.2.min",
// WORKAROUND : jQuery plugins + shims
"jqplot.core": "path/to/jquery-jqplot-1.0.8.min",
"jqplot": "jquery-jqplot-module-with-plugins-1.0.8"
},
shim: {
"jqplot.core": {deps: ["jquery"]},
"jqplot": {deps: ["jqplot.core"]}
}
});
create a wrapper file module file called "jquery-jqplot-module-with-plugins-1.0.8.js", containing :
// wraps jquery jqplot plugin in define statement
define([
"jquery",
"path/to/jqplot.highlighter.min",
"path/to/jqplot.cursor.min",
"path/to/jqplot.dateAxisRenderer.min",
"path/to/jqplot.canvasTextRenderer.min",
"path/to/jqplot.canvasAxisLabelRenderer.min",
"path/to/jqplot.enhancedLegendRenderer.min",
"path/to/jqplot.pieRenderer.min",
"path/to/jqplot.donutRenderer.min",
], function($) {
var jqplot;
jqplot = $.jqplot;
return jqplot;
});
Then when ever you need jqplot with those plugins, simply call for "jqplot" which will load "jquery" then "jqplot.core" then all the jqplot modules, then finally return the jqplot object :)
require(["jquery", "jqplot"], function ($, $jqplot) {
console.log("Success..Inside Require JS");
console.log("Plot...", $.jqplot, $jqplot);
});
or
define(["jquery", "jqplot"], function ($, $jqplot) {
console.log("Success..Inside Define JS");
console.log("Plot...", $.jqplot, $jqplot);
});
tada! :)
ps jquery plugins are evil, no suggestion how to fix that situation, just a statement of fact
cheers
Ant
Looks like plot is returned before require(...) initializes it. I used to have common solution and my plot was partly populated. I ended up with setting all jqplot plugins in shim and changed my `plot.js' accordingly, as was suggested here.
requirejs.config
shim: {
'jqplot': ['jquery'],
'lib/jquery/jqplot/plugins/jqplot.canvasTextRenderer': ['jqplot'],
'lib/jquery/jqplot/plugins/jqplot.pieRenderer': ['jqplot'],
'lib/jquery/jqplot/plugins/jqplot.barRenderer': ['jqplot'],
'lib/jquery/jqplot/plugins/jqplot.categoryAxisRenderer': ['jqplot'],
'lib/jquery/jqplot/plugins/jqplot.canvasAxisLabelRenderer': ['jqplot'],
'lib/jquery/jqplot/plugins/jqplot.enhancedLegendRenderer': ['jqplot'],
'lib/jquery/jqplot/plugins/jqplot.highlighter': ['jqplot'],
}
plot.js
define(['lib/jquery/jqplot/plugins/jqplot.canvasTextRenderer',
'lib/jquery/jqplot/plugins/jqplot.pieRenderer',
'lib/jquery/jqplot/plugins/jqplot.barRenderer',
'lib/jquery/jqplot/plugins/jqplot.categoryAxisRenderer',
'lib/jquery/jqplot/plugins/jqplot.canvasAxisLabelRenderer',
'lib/jquery/jqplot/plugins/jqplot.enhancedLegendRenderer',
'lib/jquery/jqplot/plugins/jqplot.highlighter'],
function() {
return $.jqplot;
});

Resources