Introducing the New Dojo Web Builder

Background

Dojo’s build system has long been considered as one of the toolkit’s most important features. Using the build system will dramatically improve the performance of your Dojo application by optimising the JavaScript modules and CSS files. This reduces the download size and number of HTTP connections needed to load your application.

Today, The Dojo Toolkit’s build tools are about to improve even further with the launching of a brand new solution, The Dojo Web Builder!

The Web Builder is an online solution providing an intuitive web interface to the existing build tools, allowing you to create customised Dojo builds using just your web browser and much more. This new tool will dramatically lower the barrier to entry for the build system, easing new users into the process of using a build tool and improving the performance of unoptimised Dojo applications everywhere!

To start, use the Dojo Web Builder tool, or continue reading for more details. We have produced a number of screencasts showing off the tool’s features and walking you through the steps required for some common example builds:

Features

Browse catalogue of every module in Dojo, Dijit and DojoX, using text searching to quickly filter the entire results. Simply select desired modules to include those in a custom build. Currently serving over eight hundred modules for the 1.6 release.

Automatically generate custom Dojo builds using our remote service, no need to open terminals and run the intensive build system locally. When the build is complete, it will automatically start the download of the result. Progress indicator keeps you informed of status during a custom build.

Auto-analyse existing Dojo applications to discover module dependencies. Provide the Web Builder with a remote URL, upload a HTML page, zip archive or an existing build profile to have the tool show you any Dojo Toolkit or custom module dependencies uncovered. Custom builds using the results will automatically include your custom modules.

Customise builds even further in “Advanced Mode”. Want to include a Dijit theme with compressed CSS? Want to use Google’s Closure compiler for aggressive compression? Want to build multiple application layers? Want to generate builds for the WebKit platform? Need to generate a cross-domain build? Switch to using the Web Builder in “Advanced Mode” to unleash the ability to heavily customise build parameters.

Open source

The Dojo Web Builder project consists of two new components that were developed:

Dojo-based web application providing the interface to the build system through a web browser.

Backend service, allowing existing build system to be controlled through a RESTful interface.

The entire project will shortly be open-sourced, living on the Dojo Foundation’s Github repository, allowing anyone to contribute to its continuing development. More importantly, other users will be able to run local versions of the tool pointing at their own modules. For example, an organisation might provide an internal version allowing teams to easily generate new custom builds of a project’s modules, without having to distribute the entire project source. In addition, the tool can be configured to generate custom builds for older versions of The Dojo Toolkit, such as 1.5 and 1.4.3. Future plans for the project include native support for the AMD module and CommonJS package formats. This will allow the Dojo Web Builder to be used with a broad variety of JavaScript modules and packages external to Dojo. A full announcement will follow when the project’s source code is available.

Conclusion

Start using the Dojo Web Builder today. The hosted version is configured to provide access to the custom builds using the latest version of The Dojo Toolkit, 1.6.

I never thought that the building process was the problem. The problem has always been that the builds don’t work. The same is true now. I make a build with the web-builder auto-analyze, but it doesn’t work. Is there something I need to do to get a build to work? What I have done is:
* Replaced the src=”” part of my script tag from Dojo on google to the new file on my own server
* Deleted all the “dojo.require” lines

It never works for me. Am I missing something? As always when it comes to Dojo, I find it super difficult to find relevant documentation. All the tutorials (like the current quickstart guide to custom builds) I have found only cover the build process, never how to implement a build, so I’m just guessing.

I would love to use builds if they made my apps load faster, but either I’m missing something or something is very broken.

Hi,
disclaimer: I have not tried this yet, so these remarks are just a guess!
I would change 2 things in your approach:
1) when you load dojo from Google, you are using a CDN version (handling the cross domain scripting issues for you). I. e. you are loading dojo.xd.js instead of dojo.js, what you would do for a local installation. Not sure if the build process will create a CDN version for you, and if you still need the CDN version.

2) When you delete all dojo.require calls, those modules won’t be loaded – even in a custom build. You have to leave all of them in your code! You can also dojo.require modules which have not been added to the custom build, they will be added as non optimized resources to the build.

Olof – you need to keep your dojo.require lines anywhere you need to use something outside of dojo base. I’ve just whacked up a skeleton for my personal website at http://www.mace.im, where I am doing some very simple dojo stuff. Check out the source for that if you want an example of a small and straightforward use of dojo.require.

Uncaught SyntaxError: Unexpected end of input dwb.js:14
Failed to load resource: the server responded with a status of 404 (Not Found) http://build.dojotoolkit.org/js/release/dwb/Main.js
Uncaught Error: Could not load ‘dwb.Main’; last tried ‘../dwb/Main.js

We use the dojo build system since 1.3 with 3 layers (for different pages) successfully and it is not that hard to get the tooling right. In the end it is a command line script which needs a config file for layer definitions, nothing more. If you are into custom builds, you most likely use other tricks too (css compression, png optimization, …) which often need to be run like this too.

The only thing required is discipline in declaring your requires correctly and completely. But that should be done anyway for documentation and maintenance purposes.

The good thing about the web builder is in my opinion, that it strengthens visibility of this little gem and rendering it more explorable for beginners.

WHAT GIVES ???
But wait ! There is more… Try to add custom layers to your build and there is NO WAY to dojo.require them to your page. You must use tag to include them.
Also, If they have any dijit module it will not work with tag and THERE IS NO WAY TO INCLUDE THEM to your page.

The Auto-Analyze feature doesn’t work for me. I try to run it on https://www.onlinescoutmanager.co.uk/ as in the video, but I get an error, “Something went wrong… There was an error during analysis, what did you give us?! We’re really sorry, please try again.” Looking at firebug, I get this response:
HTTP ERROR 500

Problem accessing /api/dependencies. Reason:

Server Error

Caused by:

java.lang.NullPointerException
at org.dtk.resources.dependencies.ScriptParser.parseModulePathsExpr(ScriptParser.java:171)
at org.dtk.resources.dependencies.ScriptParser.parseNode(ScriptParser.java:144)
at org.dtk.resources.dependencies.ScriptParser.recursiveParse(ScriptParser.java:86)
at org.dtk.resources.dependencies.ScriptParser.recursiveParse(ScriptParser.java:89)
at org.dtk.resources.dependencies.ScriptParser.recursiveParse(ScriptParser.java:82)
at org.dtk.resources.dependencies.ScriptParser.recursiveParse(ScriptParser.java:82)
at org.dtk.resources.dependencies.ScriptParser.recursiveParse(ScriptParser.java:82)
at org.dtk.resources.dependencies.ScriptParser.recursiveParse(ScriptParser.java:89)
at org.dtk.resources.dependencies.ScriptParser.recursiveParse(ScriptParser.java:89)
at org.dtk.resources.dependencies.ScriptParser.recursiveParse(ScriptParser.java:89)
at org.dtk.resources.dependencies.ScriptParser.recursiveParse(ScriptParser.java:89)
at org.dtk.resources.dependencies.ScriptParser.recursiveParse(ScriptParser.java:89)
at org.dtk.resources.dependencies.ScriptParser.recursiveParse(ScriptParser.java:89)
at org.dtk.resources.dependencies.ScriptParser.recursiveParse(ScriptParser.java:89)
at org.dtk.resources.dependencies.ScriptParser.recursiveParse(ScriptParser.java:89)
at org.dtk.resources.dependencies.ScriptParser.recursiveParse(ScriptParser.java:82)
at org.dtk.resources.dependencies.ScriptParser.recursiveParse(ScriptParser.java:82)
at org.dtk.resources.dependencies.ScriptParser.recursiveParse(ScriptParser.java:76)
at org.dtk.resources.dependencies.ScriptParser.recursiveParse(ScriptParser.java:76)
at org.dtk.resources.dependencies.ScriptParser.parse(ScriptParser.java:58)
at org.dtk.resources.dependencies.ScriptParser.retrieveModulePaths(ScriptParser.java:276)
at org.dtk.resources.dependencies.WebPage.parseDjConfig(WebPage.java:206)
at org.dtk.resources.dependencies.WebPage.parsePreDojoScript(WebPage.java:192)
at org.dtk.resources.dependencies.WebPage.parse(WebPage.java:73)
at org.dtk.resources.Dependencies.analyseModulesFromWebpage(Dependencies.java:275)
at org.dtk.resources.Dependencies.analyseModulesFromUrl(Dependencies.java:240)
at org.dtk.resources.Dependencies.analyseDependencies(Dependencies.java:136)
at sun.reflect.GeneratedMethodAccessor198.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.wink.server.internal.handlers.InvokeMethodHandler.handleRequest(InvokeMethodHandler.java:63)
at org.apache.wink.server.handlers.AbstractHandler.handleRequest(AbstractHandler.java:33)
at org.apache.wink.server.handlers.RequestHandlersChain.handle(RequestHandlersChain.java:26)
at org.apache.wink.server.handlers.RequestHandlersChain.handle(RequestHandlersChain.java:22)
at org.apache.wink.server.handlers.AbstractHandlersChain.doChain(AbstractHandlersChain.java:63)
at org.apache.wink.server.internal.handlers.CreateInvocationParametersHandler.handleRequest(CreateInvocationParametersHandler.java:54)
at org.apache.wink.server.handlers.RequestHandlersChain.handle(RequestHandlersChain.java:26)
at org.apache.wink.server.handlers.RequestHandlersChain.handle(RequestHandlersChain.java:22)
at org.apache.wink.server.handlers.AbstractHandlersChain.doChain(AbstractHandlersChain.java:63)
at org.apache.wink.server.internal.handlers.FindResourceMethodHandler.handleResourceMethod(FindResourceMethodHandler.java:151)
at org.apache.wink.server.internal.handlers.FindResourceMethodHandler.handleRequest(FindResourceMethodHandler.java:65)
at org.apache.wink.server.handlers.RequestHandlersChain.handle(RequestHandlersChain.java:26)
at org.apache.wink.server.handlers.RequestHandlersChain.handle(RequestHandlersChain.java:22)
at org.apache.wink.server.handlers.AbstractHandlersChain.doChain(AbstractHandlersChain.java:63)
at org.apache.wink.server.internal.handlers.FindRootResourceHandler.handleRequest(FindRootResourceHandler.java:95)
at org.apache.wink.server.handlers.RequestHandlersChain.handle(RequestHandlersChain.java:26)
at org.apache.wink.server.handlers.RequestHandlersChain.handle(RequestHandlersChain.java:22)
at org.apache.wink.server.handlers.AbstractHandlersChain.doChain(AbstractHandlersChain.java:63)
at org.apache.wink.server.internal.handlers.HeadMethodHandler.handleRequest(HeadMethodHandler.java:53)
at org.apache.wink.server.handlers.RequestHandlersChain.handle(RequestHandlersChain.java:26)
at org.apache.wink.server.handlers.RequestHandlersChain.handle(RequestHandlersChain.java:22)
at org.apache.wink.server.handlers.AbstractHandlersChain.doChain(AbstractHandlersChain.java:63)
at org.apache.wink.server.internal.handlers.OptionsMethodHandler.handleRequest(OptionsMethodHandler.java:46)
at org.apache.wink.server.handlers.RequestHandlersChain.handle(RequestHandlersChain.java:26)
at org.apache.wink.server.handlers.RequestHandlersChain.handle(RequestHandlersChain.java:22)
at org.apache.wink.server.handlers.AbstractHandlersChain.doChain(AbstractHandlersChain.java:63)
at org.apache.wink.server.internal.handlers.SearchResultHandler.handleRequest(SearchResultHandler.java:33)
at org.apache.wink.server.handlers.RequestHandlersChain.handle(RequestHandlersChain.java:26)
at org.apache.wink.server.handlers.RequestHandlersChain.handle(RequestHandlersChain.java:22)
at org.apache.wink.server.handlers.AbstractHandlersChain.doChain(AbstractHandlersChain.java:63)
at org.apache.wink.server.internal.log.ResourceInvocation.handleRequest(ResourceInvocation.java:92)
at org.apache.wink.server.handlers.RequestHandlersChain.handle(RequestHandlersChain.java:26)
at org.apache.wink.server.handlers.RequestHandlersChain.handle(RequestHandlersChain.java:22)
at org.apache.wink.server.handlers.AbstractHandlersChain.doChain(AbstractHandlersChain.java:63)
at org.apache.wink.server.internal.log.Requests.handleRequest(Requests.java:76)
at org.apache.wink.server.handlers.RequestHandlersChain.handle(RequestHandlersChain.java:26)
at org.apache.wink.server.handlers.RequestHandlersChain.handle(RequestHandlersChain.java:22)
at org.apache.wink.server.handlers.AbstractHandlersChain.doChain(AbstractHandlersChain.java:63)
at org.apache.wink.server.handlers.AbstractHandlersChain.run(AbstractHandlersChain.java:48)
at org.apache.wink.server.internal.RequestProcessor.handleRequestWithoutFaultBarrier(RequestProcessor.java:207)
at org.apache.wink.server.internal.RequestProcessor.handleRequest(RequestProcessor.java:154)
at org.apache.wink.server.internal.servlet.RestServlet.service(RestServlet.java:119)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:533)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1351)
at org.eclipse.jetty.servlets.UserAgentFilter.doFilter(UserAgentFilter.java:77)
at org.eclipse.jetty.servlets.GzipFilter.doFilter(GzipFilter.java:133)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1322)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:473)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:119)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:514)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:226)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:920)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:403)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:184)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:856)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:117)
at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:247)
at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:151)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:114)
at org.eclipse.jetty.server.Server.handle(Server.java:352)
at org.eclipse.jetty.server.HttpConnection.handleRequest(HttpConnection.java:596)
at org.eclipse.jetty.server.HttpConnection$RequestHandler.content(HttpConnection.java:1066)
at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:805)
at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:218)
at org.eclipse.jetty.server.HttpConnection.handle(HttpConnection.java:426)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:510)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint.access$000(SelectChannelEndPoint.java:34)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:40)
at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:450)
at java.lang.Thread.run(Thread.java:662)

I´m having exactly the same problem since a few days ago. I´m not being able to make a build although i´m even trying to do it with a zip archive that has worked fine in other ocasions.
I always reach the same error:
“Something went wrong… There was an error during analysis, what did you give us?! We’re really sorry, please try again.”

I think this problem may be due to a a new release of this tool.
Best regards

Something seems to be wrong with the build tool, or with the way i am using it.

I used it a couple of months back, and it generated a perfectly working build for me. however when i try to do the same this time, it just refuses to work.

The dojo file that is generated doesnt contain all of the dependencies.

To confirm that it isnt a problem in my new code i did this:
1. Used the build from the last time
2. Commented out sections from my new code that required dependancies that werent in the previous build. (And this worked)
3. Then i used the freshly generated build, with the same commented code, and this doesnt work. (And this didnt work)

So is it possible that a bug has crept into the code based since july?

Thanks,
When building the images are corrupt.
To reproduce this *bug*, make a simple build containing for example a dialog and a button (under dijit/form).
This tool is really important and useful if it can get to be mature.
Thanks again

Does the Auto-Analyse work? I’ve tried DOJO application Archive and the Existing Profile options and I’m not able to get it to work. I get the following Javascript error:
“NetworkError: 500 Internal Server Error – http://build.dojotoolkit.org/api/dependencies”
dependencies
TypeError: _2d4 is undefined
…this.rows.styleRowNode(_619,_61a);}},_mouseOut:function(e){this.rows.setOverRow(…
dwb.js (line 14)

The build tool has not been working for some time now. It appears to be missing a resource (Main.js). Also, the Twitter API on this page has been deprecated and the widget has ceased functioning. Thanks for your attention to this; I really need the build tool.