Uglifying a RequireJS/Backbone project into one single .js file? - backbone.js

I worked along the following tutorial to try to optimize my project into one single .js file, but unfortunately I can't seem to get the expected results. I get r.js to create an optimized folder for me, but instead of a single file, I get uglified copies of each individual .js file in their respective folders. Seems like that last concatenation step is somehow missing.
I'm trying to leverage an existing config file instead of using paths, I don't know if that specific step is breaking it.
My build/app.build.js is:
({
appDir: '../',
baseUrl: 'js',
mainConfigFile: '../js/config.js',
dir: '../../my-app-build',
modules: [{
name: 'main'
}]
})
My main.js file has the config file as its dependency:
require(["config"], function() {
require(['underscore', [...]
[...]
}
}
And the config file is where all of my project dependencies are declared:
require.config({
baseUrl: "js",
paths: {[...]},
shim: {...]},
});
Does anyone have insight into why I might not be getting that single file output that I'm looking for? I tried the other approach in this post, but that only ever produces main.js for me with the config file prepended to it.
Thanks!

The issue was caused by the following option missing from the r.js build configuration file:
findNestedDependencies: true
Without it, r.js would not go past the first require in main.js, thus loading only config.js and none of the next level of dependencies. Just for reference (note that it saves the product of optimization in the same source folder, which is not ideal) looks like this:
({
baseUrl: '.',
mainConfigFile: 'config.js',
name: 'main',
out: 'main-build.js',
findNestedDependencies: true,
})

I had the same problem and got the solution from the Github Issue list. May be this configuration parameters will help you too
https://github.com/jrburke/r.js/issues/379
If you only want one JS file built, instead of using dir: use out: for a single JS file build.

Specify output filepath:
({
// ...
out: '../main.min.js'
})

Related

TypeScript with Relay: Can't resolve generated module

In my MessageItem.tsx component I have the following code:
const data = useFragment(
graphql`
fragment MessageItem_message on Message {
date
body
}
`,
message as any
);
After running relay-compiler --src ./src --schema ../../schema.graphql --language typescript --artifactDirectory ./src/__generated__, a module named MessageItem_message.graphql.ts gets generated.
But when I run the app it gives me an error:
Failed to compile.
./src/components/MessageItem.tsx
Module not found: Can't resolve
'./__generated__/MessageItem_message.graphql'
The reason is only components at the src root can refer to the right path (./__generated__), whereas components in a folder actually need to refer to the path (../__generated__) but it's not doing so.
How can I configure the path?
Edit .babelrc to point to the artifactDirectory
// .babelrc
{
"plugins": [
[
"relay",
{
"artifactDirectory": "./src/ui/graphql/types"
}
]
]
}
Remove "--artifactDirectory ./src/__generated__" from the relay-compiler options.
By default it seems the Relay compiler puts a "__generated__" directory in the directory with any source code containing GraphQL.
As a result any "./__generated__" references anywhere and at any level in the source code hierarchy now work as they should.
Thanks to #ThibaultBoursier for the pointer.
PS I wonder if the --artifcactDirectory option is just meant to be used to change the name of the artifact directory, rather than its location?
Just moments ago I ran into the same issue. The reason is that the relay-compiler is using the artifactDirectory setting to decide where to put the generated files, but the babel-plugin-relay exposing the graphql tag needs to get the very same argument otherwise it just attempts to include a colocated relative file.
I fixed it in my case by configuring the plugin with a babel-plugin-macros.config.js file as follows (where the artifactDirectory is the same as the one supplied to the relay-compiler):
module.exports = {
relay: {
artifactDirectory: "./src/ui/graphql/types",
},
};
This solution assumes you are using the macro via babel-plugin-macros, otherwise you might need to supply that argument via the .babelrc file but I have no experience with that unfortunately.

Render all Jade files in large Express application using folder structure?

How can I configure Express to render all Jade files regardless of path? The application I'm on is large with a very complex structure. I'm successfully serving static files however I need many of them to be rendered. We are using Jade for all files needing markup.
I'm worried that the pattern below will force me to create a route alias for every folder that has a Jade file... which would be bad. I would like to tell Express to simply render everything with a .jade extension... OR... allow me to create a route PREFIX for the root that would cause a Render operation instead of Static.
client
app
services
modules
moduleA
itemA
itemAList.jade
itemAList.js
itemADetails.jade
itemADetails.js
itemB
itemBList.jade
itemBList.js
itemBDetails.jade
itemBDetails.js
moduleB
itemC
itemCList.jade
itemCList.js
itemCDetails.jade
itemCDetails.js
itemD
itemDList.jade
itemDList.js
itemDDetails.jade
itemDDetails.js
assets
js
css
server
config
views
Routes.Config.js
module.exports = function(app){
app.get('/*', function(req, res){
res.render('../../client/' + req.params[0]);
});
app.get('/', function(req, res){
res.render('../../client/index', {});
})
}
Express.Config.js
[snip]
app.use(express.static(path.join(constants.rootPath, '/client')));
I would use a Grunt file watcher to kick off a compile any time your .jade files are created or saved. By using the Gruntfile.js below, you can issue the command grunt watch and have this automagically occur in the background:
module.exports = function(grunt){
grunt.initConfig({
jade: {
compile: {
options: {
client: false,
pretty: true
},
files: [{
cwd: "client/app/templates",
src: "**/*.jade",
dest: "client/app/modules",
ext: ".html",
expand: true
}]
}
},
watch: {
html: {
files: 'client/app/templates/**/*.jade',
tasks: ['jade'],
options: {
atBegin: true,
interrupt: true
}
}
}
});
grunt.loadNpmTasks("grunt-contrib-jade");
grunt.loadNpmTasks("grunt-contrib-watch");
grunt.registerTask('default', ['jade']);
}
Now, this assumes that you will create a "templates" folder parallel to the "modules" folder and put all of your .jade files there in the structure you want. You may then add your controllers and other .js files to the modules folder structure as normal.
I'm not sure how Grunt will behave with the source and destination both pointing to the same folder. However, if you REALLY want to keep your .jade and .html files in the same folder, or if you don't want to create a "templates" structure, you SHOULD be able to simply change the cwd variable to point to the "modules" folder:
files: [{
cwd: "client/app/modules", // templates folder removed
src: "**/*.jade",
dest: "client/app/modules",
ext: ".html",
expand: true
}]
NOTE:
Sounds like you've misunderstood some of the fundamentals. From what I'm learning, within a typical MEAN application, there is generally a folder structure that is meant to be purely static. In your example, this would be your "client" folder. By specifying special routes, you individually decide how every other case is handled. The example above is meant to accomplish what I think you're asking while still maintaining the purpose of the "static" area.
UPDATE: Don't use same folder!
I went back and tried using the same folder for the source and destination. This caused Grunt to hang without any way to break out of it. This hang does NOT occur when they are different. So, use the file as-is with the "templates" folder.

Extensible.log is undefined

I am trying to get the Calendar Pro from Extensible to work.
if I do everything as the example says here, I get an undefined for the log function on Extensible.js :
However everything looks alright in my code :
Ext.Loader.setConfig({
enabled: true,
disableCaching: false,
paths: {
"Extensible": "js/lib/extensible-1.5.2/src",
"Extensible.example": "js/lib/extensible-1.5.2/examples"
}
});
Ext.require([
'Extensible.calendar.CalendarPanel',
'Extensible.calendar.data.MemoryEventStore',
'Extensible.calendar.CalendarPanel',
'Extensible.example.calendar.data.Events'
]);
Both the src and the examples paths are correct.
My Extinsible folder structure sits next to the extjs src like this :
It seems like I am missing something or Extensible is not yet being initialised properly.
Looks like you just forgot to include the Extensible.js by adding it to your requires statement:
Ext.require([
'Extensible.Extensible', //here
'Extensible.calendar.CalendarPanel',
'Extensible.calendar.data.MemoryEventStore',
'Extensible.calendar.CalendarPanel',
'Extensible.example.calendar.data.Events'
]);
This will include the main Extinsible.js file as well as the calendar and example files.
As mentioned on the support forums:
The Extensible.log error typically means that you are using the source
code from Github without compiling it first. Either run the build
script per the README file, or stick to the download zip containing
the pre-built files.
If you are using a properly-built version of the framework and still getting this error then you might provide more details about how you set things up.

Any easy way to add build version info to coverage test results

I am using karma-coverage to measure the unit test coverage in my project and everything works in that regard just fine. I use HTML reporter into default directory.
However, I would need to "stamp" the coverage report with the build version information that I do have available using grunt-git-describe, which is currently used in the AngularJS app footer that loads the resulting version.json file. I didn't find any direct way to use this version.json file in the html reports from karma-coverage. So if anybody has a good idea how to do it, I would appreciate a lot.
Thanks in advance!
I did manage to implement this with a sort-of work around. I use text-replace module in grunt after running karma to do this. If some one has a better solution, please share as this is a bit of a hack, but it works ok. As karma-coverage's html reports in my environment goes to the projects' root /coverage/ folder, I made a recursive text replace into every .html file there looking for the default footer and adding my version info there...
First, installed grunt-text-replace
$ npm install grunt-text-replace --save-dev
Then I made a following replace function in gruntfile.js:
grunt.initConfig({
replace: {
coverage: {
src: ['coverage/**/*.html'],
overwrite: true,
replacements: [
{
from: '<div class="meta">Generated by',
to: function(){return grunt.config.get('task.replace.versionString');}
}
]
}
},
// and your other stuff in initConfig()
And I added a new task into grunt for this:
grunt.registerTask('coverage', 'Adds version info to coverage results', function(){
grunt.task.requires('version'); // The 'version' task creates a 'version.json' file
var vers = grunt.file.readJSON('version.json');
// Set the desired string to be used in text-replace -function
grunt.config.set('task.replace.versionString', '<div class="meta">Version ' + vers.version + ', Tag "' + vers.revision[0] + '"<br>Generated by');
grunt.task.run(['replace']);
});
A bit ugly but works like a charm ;-)

Require.js build not concatenation scripts loaded with Jam

Following one of the chapters of "Developing Backbone.js Apllication" by Addy Osmani (O'Reilly) about Grunt-BBB (Backbone Boilerplate Buddy), I just couldn't manage to create a build profile.
Here is the filesystem tree used for this :
/builds
/closure
/rhino
/config
/build.js
build.sh
/development
/* Grunt-BBB files after init */
/app
/styles
index.css
app.js
config.js
main.js
router.js
/test
/* Not important files used for testing */
/vendor
/h5bp
/css
main.css
normalize.css
/jam
/backbone
backbone.js
package.json
/bakbone.layoutmanager
bakbone.layoutmanager.js
package.json
/jquery
jquery.js
package.json
/lodash
lodash.js
lodash.min.js
lodash.underscore.min.js
package.json
require.config.js
require.js
/js
/libs
almond.js
require.js
/distribution
/* Empty dist directory where the optimized / minified / concatenated files should go */
Here are the steps I followed in the /development directory :
1) Install Grunt-BBB (npm install -g bbb)
2) Download r.js, a part of the Require.js project (git clone https://github.com/backbone-boilerplate/grunt-bbb)
3) Initialize the files of the boilerplate (bbb init)
Here is the build.js file I used to configure the r.js AMD loader for the Google Closure compiler :
({
appDir: '../../development',
baseUrl: 'app',
dir: '../../distribution',
optimize: 'closure', // 'uglify2'
paths: {
backbone: '../vendor/jam/backbone/backbone',
'backbone.layoutmanager': '../vendor/jam/backbone.layoutmanager/backbone.layoutmanager',
jquery: '../vendor/jam/jquery/jquery',
lodash: '../vendor/jam/lodash/backbone.min'
},
modules: [
{
name: 'main'
}
],
onBuildRead: function(moduleNames, path, contents) {
return contents;
//return contents.replace(/console\.log\(([^\)]+)\);/g, '')
// .replace(/debugger;/, '');
}
})
and this is the build.sh file I use :
#!/usr/bin/env bash
# r.js directory
RJSDIR="r.js"
RJS="$RJSDIR/dist/r.js"
# Rhino directory
RHINODIR="rhino"
RHINO="$RHINODIR/js.jar"
# Google Closure Compiler directory
CLOSUREDIR="closure"
CLOSURE="$CLOSUREDIR/compiler.jar"
# Build config directory
CONFIGDIR="config"
CONFIG="$CONFIGDIR/build.js"
# Launch compillation
java -Xms256m -Xmx256m -classpath "$RHINO":"$CLOSURE" org.mozilla.javascript.tools.shell.Main "$RJS" -o "$CONFIG" $#
My goal is to optimize, minify, concatenate all the JavaScrit file including the libraries and templates (which I don't have yet, I am only using the boilerplate files) but also CSS files.
The result I get by running ./build.sh is that every files are correctly minimised (besides CSS rule inlining, but that is besides the point) and concatenated but resources that are loaded and managed by the Jam (package manager that combines NPM and Require.js) aren't concatenated.
The reason for that since they are already loaded / managed by Jam, they are not redeclared in the JavaScript files AMD style.
In conclusion, my questions are the following :
How can I rewrite my build.js configuration file so that resources that are loaded by Jam also get included and concatenated in the release / dist file ?
How can I make it so that the concatenated resources aren't copied in the realse / dist directory ? Is it possible to configure this in the build.js file or should this go in my build.sh file ?
Edit : New build.js file :
({
appDir: '../../development',
baseUrl: 'app',
dir: '../../distribution',
optimize: 'closure', // 'uglify2'
paths: {
requirejs : '../vendor/jam/require',
backbone: '../vendor/jam/backbone/backbone',
'backbone.layoutmanager': '../vendor/jam/backbone.layoutmanager/backbone.layoutmanager',
jquery: '../vendor/jam/jquery/jquery',
lodash: '../vendor/jam/lodash/backbone.min'
},
name: 'main',
include: ['requirejs'],
onBuildRead: function(moduleNames, path, contents) {
return contents;
//return contents.replace(/console\.log\(([^\)]+)\);/g, '')
// .replace(/debugger;/, '');
}
})
And here is the error :
file:///vendor/js/libs/require.jsFailed to load resource: The requested URL was not found on this server.
file:///app/styles/index.cssFailed to load resource: The requested URL was not found on this server.
require.js is never included by r.js unless you instruct it to do so. See this link:
http://requirejs.org/docs/optimization.html#onejs
The link refers to command-line options, but the build file options are broadly the same:
you need to define a dummy module for require.js in your paths:
paths: {
requireLib : '/path/to/require.js'
backbone: '../vendor/jam/backbone/backbone',
'backbone.layoutmanager': '../vendor/jam/backbone.layoutmanager/backbone.layoutmanager',
jquery: '../vendor/jam/jquery/jquery',
lodash: '../vendor/jam/lodash/backbone.min'
},
and include it:
name "main",
include: ["requireLib"],
You can ensure that allnested dependencies are resolved by setting:
findNestedDependencies: true,
You can configure an output path using 'out' in your build file
out: "path/to/my/builtfile-1.0.0.js",
Sorry I don't know enough about jam to say whether jam would override this setting
_Pez

Resources