Dojo custom build: which files to deploy - dojo

First, we're new to Dojo and are free do things the "new" way, so I'm mostly ignoring the pre-1.7 sections of the documentation. Still, I'm coming up confused when comparing various articles, documents, and sample scripts.
The bottom line is that I can't find a straightforward write-up on how to create and deploy a custom build for Dojo. Most specifically, which .js and .css files we need to deploy. There's a lot of documentation on creating a build, but none I've found on deploying.
I eventually gathered that building everything into a single dojo.js is a reasonable practice for mobile, and that I simply have to extract that one file out of the build directories and deploy it to my server, but then I get missing CSS references, and it doesn't seem like trial-and-error is the correct way to resolve those.
Here's our specific, current case:
<script type="text/javascript">
require(
// deviceTheme to auto-detect device styles
[
"dojox/mobile",
"dojox/mobile/parser",
"dojox/mobile/deviceTheme"
]);
</script>
Here's the build profile:
dependencies = {
stripConsole: "normal",
layers: [
{
name: "dojo.js",
customBase: true, // prevent automatic inclusion of dojo/main
dependencies: [
"dojox.mobile.parser",
"dojox.mobile",
"dojox.mobile.deviceTheme"
]
}
],
prefixes: [
[ "dijit", "../dijit" ], // example included; not clear why
[ "dojox", "../dojox" ]
]
}
(Executed by the dojo-release-1.7.2-src\dojox\mobile\build\build.bat script.)
So I guess the specific questions are:
Which CSS files do I deploy for this case?
How do I know in general which files, including CSS files, to deploy?
Is there a good, current tutorial that I'm missing?
Are the existing scripts up-to-date? For example, why does mobile-all.profile.js use dependencies= instead of the profile= that the 1.7 build tutorial describes?

Which CSS files do I deploy for this case?
This is conditional, if a page uses a specific module and it has its own css-rules, include them.
This is not the way, but starting out with dojo.css (base, reset), dijit.css (base, layouts and more), nihilo.css (example theme) and android.css (example theme) would make a good foundation
If you want to use a theme, include the 'basename', e.g. dojox/mobile/themes/iphone/iphone.css
If for instance iphone.css does not '#import' some exotic widget you use, include the css which is delivered by the widget itself (as example, dojox/widget/ColorPicker/ColorPicker.css). Docs for each widget _should make not of this.
How do I know in general which files, including CSS files, to deploy?
There is no harm in uploading all files, the loader will decide which to get from cached-build, which to leave alone and what to download during runtime.
deploy everything.. when you build a 'action=release' all files are minified within the prefixes defined dojo (defaults, allways), dijit, dojox and any packages you add.
the build results in optimized toolkit-tree, deploy all or you might face a situation where a conditional include (Toggler.js for instance, or acme.js selector incl etc) is missing.
Is there a good, current tutorial that I'm missing?
By 'thumbrule', any 1.6+ docs are stable, but they mostly say the same. As you start a profile, it may get a bit trial and error (the sequence of inline-html inclusion of script files is of outmost importance). What you posted looks good, though think about if customBase:true is nescessary.
Make sure you have seen this for versions 1.6-1.7 and version 1.8
Are the existing scripts up-to-date? For example, why does mobile-all.profile.js use dependencies= instead of the profile= that the 1.7 build tutorial describes?
You can use the existing ones, out the box. The builder however is changing, moving up against the much debated 2.0 release. For now, the new schemes are allowed as well as the regular ones. But in fact the variable name can be foo or bar, only the variable's value is put to use. The file must 'return' a single object.
As i understood, the reason is that CommonJS Packages/1.0 is the new bible for AMD and builder 1.7+. It has allways been the 'thumb' scheme the package hierachy has followed however - but the syntax will most likely get more and more strict the closer we move to 2.0. (see if you can hook up with snover on #dojo # irc.freenode.org)

Related

How do you add dependency to a Pharo image?

After building an application using Seaside I managed to push my Pharo image code to GitHub using iceberg. I was able to clone it into a new Pharo image on a new machine. However, loading the package into the image seems to generate an error requesting some seaside dependencies. I still don't understand the concept of adding a dependency to a Pharo image. Could one explain to me how to go about doing it? I need it for code deployment and collaboration.
I'm sorry, I don't understand completely your question. If you mean how can you define a project (which can have dependencies, etc.), something like you would be doing with, for instance, maven, you need to define a Baseline.
A baseline is a class (and a package) that you need to define and save with your sources. Take this one as example: https://github.com/estebanlm/logger/blob/master/src/BaselineOfLogger/BaselineOfLogger.class.st
(this is the smallest example I found, and the project itself is not very interesting).
I will explain it in parts:
You have a class named BaselineOfLogger that inherits of BaselineOf and is placed in a package with the same name of the baseline (this is important, for the tools to find it later).
You define a method tagged with the pragma baseline (pragmas are a little bit like annotations):
BaselineOfLogger >> baseline: spec [
<baseline>
spec for: #pharo do: [
self beacon: spec.
spec package: 'Logger' ].
]
as you can see this method defines a "spec" for Pharo:
- it will load beacon project (we'll see this later)
- it declares it will load the package Logger.
The method beacon: is defined like this:
BaselineOfLogger >> beacon: spec [
spec
baseline: 'Beacon'
with: [ spec repository: 'github://pharo-project/pharo-beacon/repository' ]
]
and as you can see, it points to another project (and another baseline).
Now, since you need Seaside, your Baseline could look something like this:
BaselineOfMyProject >> baseline: spec [
<baseline>
spec for: #pharo do: [
spec
baseline: 'Seaside3'
with: [
spec repository: 'github://SeasideSt/Seaside:v3.2.4/repository' ]
spec package: 'MyPackage' ].
]
Finally, in your image, to load you will do something like this:
Metacello new
repository: 'github://yourname/yourprojectname/src';
baseline: 'MyProject';
load.
This is more or less like that. But please note than declaring dependencies is a complicated matter (no matter the language you use) and the example I made will cover just the very basics.

Webpack 4 referencing npm vendor scripts

I'm trying to get my head around Webpack 4 for a medium-to-large scale (MVC) website.
For the solution, I want to use the following, base vendor scripts/styles:
jQuery vLatest minified version
Bootstrap, but only the grid, no javascript or anything else
The site consists on several templates different from each other. Some might have an image gallery where I want to use Owl Carousel vLatest and so on, so forth.
As I've understood, the vendor bundle should only contain the scripts/styles that is used across the entire site, so i.e., the Owl Carousel script/styles should not be a part of the vendor scripts since it's only used for one, maybe two specific templates.
I've installed jQuery and Bootstrap via npm so they're in the node_modules folder. Question is: how do I tell Webpack to use the minified version of jQuery in the vendor bundle? And how do I tell it to use only the grid component from Bootstrap? And what about the other third party scripts/styles, should they be included as their own entry?
My webpack.config.js entry file looks like this:
entry: {
'mysite.bundle.css': './scripts/webpack-entries/mysite.styles.js',
'mysite.bundle.js': glob.sync('./scripts/mysite/*.js'),
'vendor.bundle.js': [
'./node_modules/jquery/dist/jquery.min.js'
],
'vendor.bundle.css': [
'./node_modules/bootstrap/scss/bootstrap-grid.scss'
],
}
What feels weird about this is, that I could just aswell reference the jquery.min.js directly on my view and import bootstrap-grid.scss directly in my .scss files. Same could be said with the Owl carousel (and other vendor scripts)
Also, if I just do this: 'vendor.bundle.js': ['jquery'] the entire non-minified jQuery library is loaded rather than the minified version.
How exactly do you work with Webpack and NPM this way? :-)
Thanks in advance.
You can use { resolve } to configure aliases:
{
resolve: {
alias: {
'jquery': require.resolve('jquery/jquery.min.js')
}
}
}
However, I would caution first to focus on getting a viable build that's suitable for development and then enhance the configuration as needed to optimize for production. For example, during development you want to include all the sources with their entirety with good source maps. When you get to the point of publishing, use something like Environment Variables to introduce a flag that will enforce the necessary configuration.
No, it's not necessary to create entry points for particular vendor sources. This is reminiscent of the past practices. You should create individual entry points to logically split your large codebase into distinct bundles, like: the public web, the administrative application, the customer application, should you have the need to do so.
Also, don't spend too much time creating entrypoints to group vendor sources and such. Write your modules as you would, from the perspective of a developer, require from them what they depend on and then use webpack { optimize.minimizer }, other minification plugins and it's dependency graph heuristics to create necessary chunks using { optimize.splitChunks }.
Short answer is, and this has been true for webpack for a long time: do not change the way you write and organize sources to satisfy webpack. It's polished and sophisticated enough that it will accommodate to your style of authoring.

How to get dojox in Dojo Tool Kit?

I can find dojo.js and dijit-all.js but I cannot find the dojox.js. Does anyone know how to build dojox.js? Any help would be highly appreciated.
Assuming you're asking for a kitchen-sink dojox module, there is none. The dojox package includes a wide variety of components for various purposes - it wouldn't be a stretch to think of each subfolder of dojox to be its own package, really. No application would ever use nearly everything in dojox at once - and if it did, its load time would be terrible, because dojox is quite large due to the nature of what it is.
dijit-all.js is generally not recommended for a similar reason, though all of dijit is not nearly as large as all of dojox. Hence the comment in the module stating as much.
For that matter, dojo/dojo.js is not a kitchen sink per se either. When used with async: true, it is only the Dojo loader; without async: true (in legacy mode), it is the loader plus dojo/_base and its dependencies.
Ideally you should only be loading modules you absolutely need; AMD in particular encourages this as opposed to the legacy dojo.require / global namespace system. If you architect your applications in a reasonable manner with a single top-level module, it is possible to create a custom build with a layer based around that module which will automatically include all its dependencies (and only its dependencies). See the "Layers" section of the Creating Builds tutorial.

DOJO build that does not include DOJO base

Is this possible using v1.6.1? Due to the Xdomain configuration of my client's dojo deployment, it is necessary to execute a new build each time dev code changes. As you can imagine, this is a huge time waster.
From everything I can see there is no way to exempt the core from the build playing by DOJOs rules. So I am wondering if there is a way to break the rules (modifying the Rhino calls?) to get to where I need to be.
A couple thoughts.
You can avoid building most of dojo (dijit, dojox) but I imagine you already know that
This restriction you are facing seems odd. Isn't there some way you can just upload the specific JS files you are editing during development?
Maybe if you give more details on the client setup, I can help you brainstorm a way around this problem.
Update
Here's what I think you need: Customize Dojo Base in Build. This allows you to specify particular bits of the dojo base to include.
This works in pre-1.7, so you should be good.
Appears to be exactly what you want:
layers: [
{
name: "dojo.js",
customBase: true,
dependencies: [
]
},
// ... remainder of profile
]
This will give you the absolute bare minimum of dojo (which you still don't need for your dev scenario, but which will drastically reduce the amount of files processed).
For other use cases, you can use the dependencies attribute to add in other stuff from dojo core.
Update 2:
Here's a couple build-time optimization suggestions:
1) Don't intern strings, and don't compress, when in dev.
There are arg values you can pass to avoid these time-consuming steps (example is for ant build):
<arg value="internStrings=false"/>
<arg value="layerOptimize=false"/>
2) Build to a ram disk to speed copying of files
Dojo supports mix-and-match - so you can use xdomain and/or custom build for the stuff that does not change - and use regular dojo.require for the JS/widget that is changing often - and then just push that JS to see the change without a new xdomain/custom build/deployment
You can explore using local modules with xdomain build. Also, Dojo allows using multiple custom builds - so you can do a stable custom build for the widgets that don't change so much and another smaller build for code that is changing frequently.
Why not use dojo 1.7, load asynchronously, and rely on it's legacy support? http://livedocs.dojotoolkit.org/loader/amd

Dojo vs Dijit - files to include or reference?

I've been reading O'Reilly book "Dojo - The Definitive Guid" but somethings are still not definitive to me.
They talk about "bootstrapping" and getting the dojo.css from the AOL CDN".
When I'm testing on my machine, should I use the CDN? Or should I wait and use that only when I deploy?
Secondly, the book talks about CDN for dojo, but not for dijit.
I'm developing on Google App Engine (GAE) - so having the 2000+ Dojo/Dijit files in my Javascript directory is a little annoying, because it slows down my upload to GAE each time.
Firebug is giving me this error:
GET http://localhost:8080/dijit/nls/dijit-all_en-us.js 404 not Found
GET http://localhost:8080/dijit/_editor/plugins/FontChoice.js 404 not Found
I downloaded the sample from here:
http://archive.dojotoolkit.org/nightly/dojotoolkit/dijit/themes/themeTester.html?theme=soria
and I'd like to "simply" get it to run on my machine under local google app engine (which is the localhost:8080 that you see in the URLs above).
I see this statement which probably is causing the second 404 above:
dojo.require("dijit._editor.plugins.FontChoice");
One other error:
cannot access optimized closure
preload("en-us") dijit-all.js (line 479)
anonymous("dijit.nls.dijit-all", ["ROOT", "ar", "ca", 40 more... 0=ROOT 1=ar 2=ca 3=cs 4=da 5=de 6=de-de 7=el 8=en 9=en-gb])dijit-all.js (line 489)
dijit-all.js()
dojo.i18n._searchLocalePath(locale, true, function(loc){\n
To continue for now, I'm going to try to copy the entire dijit library, but is there a solution short of that?
My current script includes look like this:
<script type="text/javascript" src="/javascript/dijit.js"></script>
<script type="text/javascript" src="/javascript/dijit-all.js" charset="utf-8"></script>
I got the dijit.js file by copying and renaming dijit.js.uncompressed.js to dijit.js.
You have a few options actually:
You could use the CDN for everything (though using the full source locally does give you better error messages). Google has them as well. Dijit is here: http://ajax.googleapis.com/ajax/libs/dojo/1.3.2/dijit/dijit.js FYI. This has many advantages in my opinion. User caching of the JS being the primary one.
Build a layered file. I think the O'Reilly book has a section about it but the PragProg book is better in this regard IMO. There's also this doc on dojocampus.org about building. This will trim down the files you need to upload to GAE and speed up your app loading. This is actually what I do in order to cut down on HTTP requests.
Keep doing what you are doing. :)
Regarding the errors you are seeing about 404 for en-us files are essentially harmless. Here's a better description.
You also might be reloading dijit files by using dijit.uncompressed.js and dijit-all.js and causing problems in the process...but I'm not sure about this one.
I just want to clarify that when using CDN all you need to include is the main Dojo script. The rest will be pulled in automatically when you dojo.require() them.
If for some (technical) reasons you don't want to use the X-Domain loader (CDNs use this type of loader), you can do a custom build (well-described in many places). After the build you copy only relevant files to your server. No need to copy all 2000+ tests, demos, unused DojoX projects, Dijits and so on.
During the build you will create a single minified file (or a few layers), which will include all Dojo JavaScript code you use. If you use Dojo widgets, their templates will be already inlined, so you do not incur hits for them. As part of the build CSS files are combined together and minified too. So literally in most cases you will have just two files: a Dojo layer, which includes everything + your custom code, and a CSS file. In more complex cases you may have more files, but usually we are talking about handful.
How to make sure that everything is in the build? Fire up your favorite network analyzer (Live HTTP Headers, Firebug, Fiddler2, or Charles Proxy would do fine) and see if you hit any files outside of your build. If you do — include them in the build, or try to figure out why they are requested, and eliminate these requests (some localization-related calls are fine).
Personally I would start with the CDN option — works well, no hassle, hosted by somebody else with fat pipes.
To address your first question, use the full source version locally for development, so that you can get clearer debug info which points to a legible line in source, rather than the single line the minified version is reduced to. Use the CDN for production.