Ext.data.JsonP.command_app_single({"title":"Single-Page Ext JS Apps","guide":"
Contents
\n\nThis guide covers single-page Ext JS applications that do not use the generated scaffold\ndescribed in Using Sencha Cmd with Ext JS. While the convenient\ncommands like sencha app build
won't understand these applications and so cannot be\nused, you can use the lower-level commands provided by Sencha Cmd to produce builds and\nperform all of the same tasks.
The majority of the build process is handled by the Sencha Cmd compiler and the\npackage manager. These building blocks are connected and streamlined in a generated app,\nso that is typically the much simpler and recommended approach. If you need more control\nover the process, however, you can use these pieces directly in your own build process.
\n\nEven though this guide shows how to use Sencha Cmd at a lower level to support different\norganizational preferences, certain guidelines are still important. Please see:
\n\nCompiler-Friendly Code Guidelines
\n\nWe will consider a PHP application with the following folder structure.
\n\nindex.php # The application's markup file.\nbuild/ # The folder where build output is placed.\next/ # The framework distribution.\n src/ # The framework source tree.\njs/ # Folder containing the application's JavaScript code.\n app.js # Contains the Ext Application\n
\n\nThe \"index.php\"
file would look similar to this:
<html>\n <head>\n <script src=\"ext/ext-dev.js\" type=\"text/javascript\"></script>\n\n <script src=\"js/app.js\" type=\"text/javascript\"></script>\n </head>\n <body>\n <?php ... ?>\n </body>\n</html>\n
\n\nThis structure is similar to but not the same as the structure generated by Sencha Cmd.
\n\nIn order for Sencha Cmd to support as many server-side technologies as possible, the\ncompiler has to be guided to the parts of the markup file that are intended for its\nconsumption. Outside of the generated build process, the simplest way to do this is by\nadding special directives inside comments to your page. For example:
\n\n<html>\n <head>\n <!-- <x-compile> -->\n <!-- <x-bootstrap> -->\n <script src=\"ext/ext-dev.js\" type=\"text/javascript\"></script>\n <!-- </x-bootstrap> -->\n\n <script src=\"js/app.js\" type=\"text/javascript\"></script>\n <!-- </x-compile> -->\n </head>\n <body>\n <?php ... ?>\n </body>\n</html>\n
\n\nThe open and close tags of the x-compile
directive enclose the part of the markup file\nwhere the compiler will operate. The only thing that should be contained in this block\nare script
tags. The compiler will process all of these scripts for dependencies.
The exception to this is the \"ext-dev.js\"
file. This file is considered to be a\n\"bootstrap\" file for the framework and should not be processed in the same way. The\ncompiler ignores the files in the x-bootstrap
block, and they are removed from the\nfinal page, as we will see later.
The first job of the compiler is to examine and parse the JavaScript source code and\nanalyze its dependencies. These dependencies are expressed in code using Ext.define
and\nthe requires
(or uses
) directives. Also, base classes and mixins are considered to be\ndependencies in the same way as requires
.
The application requires its own code (in the \"js\"
folder) as well as some of the\nframework (in the \"ext\"
folder). The goal is to create a single JavaScript file that\ncontains all of the code needed from both folders and exclude any code that is not used.
Since most build processes create the production build in a separate folder, let's use the\n\"build\" folder to hold the outputs and thereby avoid overwriting any source code.
\n\nLets start with this command:
\n\nsencha compile -classpath=ext/src,js page -yui -in index.php -out build/index.php\n
\n\nThis command performs the following steps:
\n\n-classpath
switch provides the compiler with all of the folders containing source\ncode to be considered, in this case, the \"ext/src\"
and \"js\"
folders.page
command then includes all of the script
tags in \"index.php\"
\nthat are contained in the x-compile
block.\"ext/src\"
, \"js\"
, and \"index.php\"
, the compiler analyzes\nthe JavaScript code and determines what is ultimately needed by \"index.php\"
.\"index.php\"
file is written to \"build/index.php\"
.\"index.php\"
are concatenated, compressed using\nthe YUI Compressor, and written to the\nsingle file \"build/all-classes.js\"
.The compiled version of \"index.php\"
should look approximately like this:
<html>\n <head>\n <script src=\"all-classes.js\" type=\"text/javascript\"></script>\n </head>\n <body>\n <?php ... ?>\n </body>\n</html>\n
\n\nThe entire x-compile
section is replaced by the single script
tag that includes the\n\"all-classes.js\"
file. The rest of the page remains unchanged.
This is just one step of a complete build process. The others are typically simpler\n(for example, copying files) and are not considered here.
\n\nDue to the nature of dependency analysis, your application may contain code you know will\nnever be used. By understanding the compiler below the level of the sencha compile page
\ncommand, you can see how to go about further tuning this process. Beyond these techniques\nyou can also use the compiler without the page
command and operate purely on JavaScript\nsource files. For more information on this lowest-level of the compiler, see the\nSencha Compiler Reference
If you were to remove the -yui
switch from the compile command show above, you can\nexamine \"all-classes.js\"
and inspect the code that was identified as being needed by your\napplication. If you see classes that you would like to remove, you can do that with\nadvanced features of the compiler.
At its core, the compiler uses the concept of \"sets\" and set operations to manage what is\nincluded in the concatenated output file. It first builds the set of all files as it reads\nthe code from the -classpath
. The page
command then determines the subset of files used\nby \"index.php\"
.
To illustrate, let's assume that somehow the Tree package (Ext.tree
) is being pulled in\nto \"all-classes.js\"
and we are certain that that's incorrect. The following command\nremoves this namespace:
sencha compile -classpath=ext/src,js \\\n page -name=page -in index.php -out build/index.php and \\\n restore page and \\\n exclude -namespace Ext.tree and \\\n concat -yui build/all-classes.js\n
\n\nThe first change is to provide a name for the set of files produced by the page
command.\nBy naming the set we disable the automatic generation of \"all-classes.js\"
so we can adjust\nits contents before generating it explicitly.
This also illustrates the use of command chaining and category state discussed in more\ndetail in Advanced Sencha Cmd. To summarize these two concepts:
\n\nand
separates commands in the same category (compile
in this case).compile
is preserved across these commands.Lets break down the individual steps in the above command as it deviates from the original.
\n\nThe compile
command does the same as before and reads the code in the -classpath
.
sencha compile -classpath=ext/src,js \\\n
\n\nThe page
command determines what is needed by \"index.php\"
and generates the modified\nversion in \"build/index.php\". The page
command also saves the set of files in a set\nnamed page
(and does not generate \"all-classes.js\"
).
page -name=page -in index.php -out build/index.php and \\\n
\n\nThe restore
command restores the named set (page
) as the current set
. Most of the\nsubcommands of the compiler operate on the current set. Without this command, the\ncurrent set would be all files
.
restore page and \\\n
\n\nThe exclude
command removes all files in the Ext.tree
namespace from the current set.
exclude -namespace Ext.tree and \\\n
\n\nThe concat
command concatenates and compresses all files in the current set and writes\nthe result to \"build/all-classes.js\"
.
concat -yui build/all-classes.js\n
\n\nThere are many more commands and options provided to manipulate the current set. Basically,\nif you can imagine a way to arrive at the desired set of files using a sequence of set\noperations, the compiler can combine just those files for you. For more on this topic,\nsee the Sencha Compiler Reference.
\n\nThe \"bootstrap\" file included in the example application (\"ext-dev.js\"
) contains two very\nimportant things:
This second part is what allows requires
statements to use wildcards as in:
Ext.define(..., {\n requires: [\n 'Ext.grid.*'\n ]\n});\n
\n\nTo use similar syntax in your application, you need to provide the required metadata for\nthe dynamic loader. The following command generates such a file:
\n\nsencha compile -classpath=js \\\n meta -alias -out build/bootstrap.js and \\\n meta -alt -append -out build/bootstrap.js\n
\n\nThis file should be added to the x-bootstrap
section, like so:
<html>\n <head>\n <!-- <x-compile> -->\n <!-- <x-bootstrap> -->\n <script src=\"ext/ext-dev.js\" type=\"text/javascript\"></script>\n <script src=\"build/bootstrap.js\" type=\"text/javascript\"></script>\n <!-- </x-bootstrap> -->\n\n <script src=\"js/app.js\" type=\"text/javascript\"></script>\n <!-- </x-compile> -->\n </head>\n <body>\n <?php ... ?>\n </body>\n</html>\n
\n\nThere are other uses for code metadata. For details on generating metadata and what kinds\nof metadata are provided, see Generating Metadata.
\n\nNote. This is handled automatically for generated applications.
\n"});