1. Motivation
To reduce page load time by reducing the requests of fetching JavaScript files.
2. Creating a production build manually
Download and Install Sencha Cmd and Extjs sdk
1) Download SenchaCmd-3.1.2.342-windows.exe and ext-4.2.1-gpl.zip
2) Install SenchaCmd-3.1.2.342-windows.exe
3) Add Sencha cmd bin directory to you path, for me, C:\tools\SenchaCmd\bin\Sencha\Cmd\3.1.2.342 is added to my path
4) Extract ext-4.2.1-gpl.zip, assume the extracted folder name is C:\tools\ext-4.2.1.883
Create a new Sencha Cmd Project for getting the configuration files required to build iem-web
1) Open a command prompt
2) Change directory to C:\tools\ext-4.2.1.883
3) Enter the following command
sencha generate app IEM ProjectBuild/IEM
4) You will see a generated project named IEM under C:\tools\ext-4.2.1.883\ProjectBuild\IEM
5) Why we need this step? We want to get the configuration files required by sencha cmd for iem-web, we can easily do modification on these files instead of creating them manually.
Copy Your Project files into the Sencha Cmd Project
1) Remove app folder under ProjectBuild/IEM
2) Copy iem-web/app folder to ProjectBuild/IEM
3) Copy iem-web/IemApp.js, iemForCompile.jsp, api-debug.js, Util.js to ProjectBuild/IEM
Create a Production Build
1) Modify ProjectBuild/IEM/.sencha/app/sencha.cfg file.
a) set app.classpath=${app.dir}/app,${app.dir}/iemApp.js
b) set app.page.name=iemForCompile.jsp
2) add “skip.sass=true” to ProjectBuild/IEM/.sencha/app/production.properties
3) Open a command prompt and change directory to ProjectBuild/IEM
4) Enter the following command:
sencha app build
5) You will see the generated files under C:\tools\ext-4.2.1.883\build\IEM\production
all-classes.js and iemForCompile.jsp
6) Rename iemForCompile.jsp to iem.jsp
7) Copy the all-classes.js and iem.jsp to your tomcat
8) Open iem.jsp and do the following change
a) Change
<link rel="stylesheet" type="text/css" href="../../resources/ext-theme-classic/ext-theme-classic-all.css">
To
<link rel="stylesheet" type="text/css" href="ext/resources/ext-theme-classic/ext-theme-classic-all.css">
b) Remove <link rel="stylesheet" href="resources/IEM-all.css"/>
9) Your final iem.jsp will look like this
Jsp related codes are omitted …
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>IEM</title> <link rel="stylesheet" type="text/css" href="ext/resources/ext-theme-classic/ext-theme-classic-all.css"> <link rel="stylesheet" type="text/css" href="css/app_style.css"> <link rel="stylesheet" type="text/css" href="css/iemStyles.css"> </head> <body> <div align="center" id="divLoadPage" class="loadingText">Loading page, please wait ... </div> </body> <script type="text/javascript" src="all-classes.js"></script> </html>
10) test your application at http://localhost:8080/iem-web/iem.jsp
3. Integrating the build with maven
Copy extjs related files and sencha cmd related files required by building process to iem-web\jsBuild folder.
Please note this step is to prepare the execution environment for iem-web, the JavaScript files of iem-web are not in this folder, and they will be copied in maven.
Run sencha generate app IEM ProjectBuild/IEM command under iem-web\jsBuild\ext-4.2.1.883 to generate an empty IEM project and the configuration files we need.
Still we don’t have the iem-web JavaScript files.
Modify configuration files as described on section “Creating a production build manually” to configure iem-web project properly.
The folder structure looks like as following screenshot:
Modify pom.xml to do the integration
1) Copy iem-web JavaScript files to jsBuild/ext-4.2.1.883/ProjectBuild/IEM/ for build
<plugin> <artifactId>maven-resources-plugin</artifactId> <version>2.4.3</version> <executions> <execution> <id>copy-single-files-for-sench-cmd-build</id> <phase>validate</phase> <goals> <goal>copy-resources</goal> </goals> <configuration> <outputDirectory>jsBuild/ext-4.2.1.883/ProjectBuild/IEM</outputDirectory> <resources> <resource> <directory>src/main/webapp/</directory> <includes> <include>api-debug.js</include> <include>iemApp.js</include> <include>iem.jsp</include> <include>Util.js</include> </includes> </resource> </resources> </configuration> </execution> <execution> <id>copy-app-folder-for-sench-cmd-build</id> <phase>validate</phase> <goals> <goal>copy-resources</goal> </goals> <configuration> <outputDirectory>jsBuild/ext-4.2.1.883/ProjectBuild/IEM/app</outputDirectory> <resources> <resource> <directory>src/main/webapp/app</directory> </resource> </resources> </configuration> </execution> </executions> </plugin>
2) We need to do some modification, because we need to run the “sencha app build” command under jsBuild/ext-4.2.1.883/ProjectBuild/IEM folder, so we need to modify some related path in iem.jsp
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-antrun-plugin</artifactId> <version>1.7</version> <executions> <execution> <id>modify iem.jsp for build</id> <phase>initialize</phase> <configuration> <target name="modify iem.jsp for build"> <replace file="${basedir}/jsBuild/ext-4.2.1.883/ProjectBuild/IEM/iem.jsp" token="ext/resources/" value="../../resources/"/> <replace file="${basedir}/jsBuild/ext-4.2.1.883/ProjectBuild/IEM/iem.jsp" token="ext/ext-all-debug.js" value="../../ext-dev.js"/> <replace file="${basedir}/jsBuild/ext-4.2.1.883/ProjectBuild/IEM/iem.jsp" token="ext/ext-all.js" value="../../ext-dev.js"/> </target> </configuration> <goals> <goal>run</goal> </goals> </execution> <execution> <id>copy sencha cmd output files and bankup the original jsp file</id> <phase>process-sources</phase> <configuration> <target name="copy sencha cmd output files and bankup the original jsp file"> <!-- first bankup the original iem.jsp --> <copy file="${basedir}/jsBuild/ext-4.2.1.883/build/IEM/production/iem.jsp" tofile="${basedir}/src/main/webapp/iemc.jsp"/> <copy file="${basedir}/jsBuild/ext-4.2.1.883/build/IEM/production/all-classes.js" tofile="${basedir}/src/main/webapp/all-classes.js"/> </target> </configuration> <goals> <goal>run</goal> </goals> </execution> <execution> <id>modify generated js file</id> <phase>process-sources</phase> <configuration> <target name="modify generated js file"> <replace file="${basedir}/src/main/webapp/iemc.jsp" token="../../resources" value="ext/resources"/> <replace file="${basedir}/src/main/webapp/iemc.jsp"> <replacetoken><![CDATA[<link rel="stylesheet" href="resources/IEM-all.css"/>]]></replacetoken> <replacevalue><![CDATA[]]></replacevalue> </replace> </target> </configuration> <goals> <goal>run</goal> </goals> </execution> </executions> </plugin>
3) Start the build by executing external command in maven or use maven execution plug-in to do this
a) By executing external command
<execution> <id>Creating a Production Build with Sencha Command</id> <phase>generate-sources</phase> <configuration> <target> <taskdef resource="net/sf/antcontrib/antcontrib.properties"/> <if> <equals arg1="${OS}" arg2="Windows_NT" /> <then> <echo message="invoking jsBuild.bat"/> <echo message="OS =${OS}" /> <echo message="os.name = ${os.name}" /> <echo message="os.arch = ${os.arch}" /> <echo message="os.version = ${os.version}" /> <exec dir="${basedir}" executable="${basedir}\jsBuild\jsBuild.bat"></exec> </then> <else> <echo message="invoking jsBuild.sh"/> <echo message="OS =${OS}" /> <echo message="os.name = ${os.name}" /> <echo message="os.arch = ${os.arch}" /> <echo message="os.version = ${os.version}" /> <exec dir="${basedir}" executable="${basedir}\jsBuild\jsBuild.sh"></exec> </else> </if> </target> </configuration> <goals> <goal>run</goal> </goals> </execution>
The content of jsBuild.bat:
@echo off set "CURRENT_DIR=%cd%" cd jsBuild\ext-4.2.1.883\ProjectBuild\IEM java -Xms256m -Xmx800m -jar ../../../senchaCmd/sencha.jar app build cd "%CURRENT_DIR%" exit
The content of jsBuild.sh
#!/bin/bash CURDIR=${PWD} BASEDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" echo change to project directory cd jsBuild\ext-4.2.1.883\ProjectBuild\IEM echo current directory is ${PWD} echo *********************************start building js******************************** java -Xms1024m -Xmx1280m -jar ../../../senchaCmd/sencha.jar app build echo *********************************end building js********************************** cd ${CURDIR} exit
b) Use maven execution plug-in
<execution> <id>Creating a Production Build with Sencha Command</id> <phase>generate-sources</phase> <configuration> <target name="Start building process"> <echo message="os.name = ${os.name}"/> <echo message="os.arch = ${os.arch}"/> <echo message="os.version = ${os.version}"/> <echo message="java.class.path = ${java.class.path}"/> <java dir="${basedir}/jsBuild//ext-4.2.1.883/ProjectBuild/IEM" jar="${basedir}/jsBuild/senchaCmd/sencha.jar" fork="true" failonerror="false" maxmemory="800m"> <sysproperty key="DEBUG" value="true"/> <jvmarg line="-Xms256m -Xmx800m"/> <arg value="app"/> <arg value="build"/> <classpath> <pathelement location="${basedir}/jsBuild/senchaCmd/sencha.jar"/> <pathelement path="${java.class.path}"/> </classpath> </java> </target> </configuration> <goals> <goal>run</goal> </goals> </execution>
The purpose of running bat or sh files is to run “sencha app build” under the specified folder jsBuild\ext-4.2.1.883\ProjectBuild\IEM, this is required by sencha cmd, otherwise they are a lot of configuration files need to adjusted and I am not sure whether we can adjust them correctly.
4) Also don’t forget to clean up the related files in a new round of building
<plugin> <!-- Clean up the rsults of copy resources --> <artifactId>maven-clean-plugin</artifactId> <configuration> <filesets> <fileset> <directory>${basedir}/src/main/resources/com</directory> </fileset> <fileset> <directory>${basedir}/src/test/resources/com</directory> </fileset> <!-- clean up the copied files for js build --> <fileset> <directory>${basedir}/jsBuild/ext-4.2.1.883/ProjectBuild/IEM/app</directory> </fileset> <fileset> <directory>${basedir}/jsBuild/ext-4.2.1.883/ProjectBuild/IEM</directory> <includes> <include>api-debug.js</include> <include>iemApp.js</include> <include>iem.jsp</include> <include>Util.js</include> </includes> </fileset> <!-- clean up the output files of js build --> <fileset> <directory>${basedir}/jsBuild/ext-4.2.1.883/build/IEM</directory> </fileset> <fileset> <directory>${basedir}/src/main/webapp</directory> <includes> <include>all-classes.js</include> <include>iemc.jsp</include> </includes> </fileset> </filesets> </configuration> </plugin>
5) A sample pom.xml related SenchaCmd is as following:
SenchaCmd Intergration with Maven
<plugin> <artifactId>maven-resources-plugin</artifactId> <version>2.4.3</version> <executions> <execution> <id>copy-single-files-for-sench-cmd-build</id> <phase>validate</phase> <goals> <goal>copy-resources</goal> </goals> <configuration> <outputDirectory>jsBuild/ext-4.2.1.883/ProjectBuild/IEM</outputDirectory> <resources> <resource> <directory>src/main/webapp/</directory> <includes> <include>api-debug.js</include> <include>iemApp.js</include> <include>iem.jsp</include> <include>Util.js</include> </includes> </resource> </resources> </configuration> </execution> <execution> <id>copy-app-folder-for-sench-cmd-build</id> <phase>validate</phase> <goals> <goal>copy-resources</goal> </goals> <configuration> <outputDirectory>jsBuild/ext-4.2.1.883/ProjectBuild/IEM/app</outputDirectory> <resources> <resource> <directory>src/main/webapp/app</directory> </resource> </resources> </configuration> </execution> </executions> </plugin> <plugin> <!-- Clean up the rsults of copy resources --> <artifactId>maven-clean-plugin</artifactId> <configuration> <filesets> <!-- clean up the copied files for js build --> <fileset> <directory>${basedir}/jsBuild/ext-4.2.1.883/ProjectBuild/IEM/app</directory> </fileset> <fileset> <directory>${basedir}/jsBuild/ext-4.2.1.883/ProjectBuild/IEM</directory> <includes> <include>api-debug.js</include> <include>iemApp.js</include> <include>iem.jsp</include> <include>Util.js</include> </includes> </fileset> <!-- clean up the output files of js build --> <fileset> <directory>${basedir}/jsBuild/ext-4.2.1.883/build/IEM</directory> </fileset> <fileset> <directory>${basedir}/src/main/webapp</directory> <includes> <include>all-classes.js</include> <include>iemc.jsp</include> </includes> </fileset> </filesets> </configuration> </plugin> <!-- <plugin> --> <!-- <groupId>org.codehaus.mojo</groupId> --> <!-- <artifactId>exec-maven-plugin</artifactId> --> <!-- <version>1.2</version> --> <!-- <executions> --> <!-- <execution> --> <!-- <id>Creating a Production Build with Sencha Command</id> --> <!-- <phase>generate-sources</phase> --> <!-- <goals> --> <!-- <goal>exec</goal> --> <!-- </goals> --> <!-- <configuration> --> <!-- <executable>${jsBuildScript}</executable> --> <!-- </configuration> --> <!-- </execution> --> <!-- </executions> --> <!-- </plugin> --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-antrun-plugin</artifactId> <version>1.7</version> <executions> <execution> <id>modify iem.jsp for build</id> <phase>initialize</phase> <configuration> <target name="modify iem.jsp for build"> <replace file="${basedir}/jsBuild/ext-4.2.1.883/ProjectBuild/IEM/iem.jsp" token="ext/resources/" value="../../resources/"/> <replace file="${basedir}/jsBuild/ext-4.2.1.883/ProjectBuild/IEM/iem.jsp" token="ext/ext-all-debug.js" value="../../ext-dev.js"/> <replace file="${basedir}/jsBuild/ext-4.2.1.883/ProjectBuild/IEM/iem.jsp" token="ext/ext-all.js" value="../../ext-dev.js"/> <replace file="${basedir}/jsBuild/ext-4.2.1.883/ProjectBuild/IEM/iem.jsp" token="ext/ext-all-dev.js" value="../../ext-dev.js"/> </target> </configuration> <goals> <goal>run</goal> </goals> </execution> <execution> <id>Creating a Production Build with Sencha Command</id> <phase>generate-sources</phase> <configuration> <target name="Start building process"> <echo message="os.name = ${os.name}"/> <echo message="os.arch = ${os.arch}"/> <echo message="os.version = ${os.version}"/> <echo message="java.class.path = ${java.class.path}"/> <java dir="${basedir}/jsBuild//ext-4.2.1.883/ProjectBuild/IEM" jar="${basedir}/jsBuild/senchaCmd/sencha.jar" fork="true" failonerror="false" maxmemory="800m"> <sysproperty key="DEBUG" value="true"/> <jvmarg line="-Xms256m -Xmx800m"/> <arg value="app"/> <arg value="build"/> <classpath> <pathelement location="${basedir}/jsBuild/senchaCmd/sencha.jar"/> <pathelement path="${java.class.path}"/> </classpath> </java> </target> </configuration> <goals> <goal>run</goal> </goals> </execution> <execution> <id>copy sencha cmd output files and bankup the original jsp file</id> <phase>process-sources</phase> <configuration> <target name="copy sencha cmd output files and bankup the original jsp file"> <!-- first bankup the original iem.jsp --> <copy file="${basedir}/jsBuild/ext-4.2.1.883/build/IEM/production/iem.jsp" tofile="${basedir}/src/main/webapp/iemc.jsp"/> <copy file="${basedir}/jsBuild/ext-4.2.1.883/build/IEM/production/all-classes.js" tofile="${basedir}/src/main/webapp/all-classes.js"/> </target> </configuration> <goals> <goal>run</goal> </goals> </execution> <execution> <id>modify generated js file</id> <phase>process-sources</phase> <configuration> <target name="modify generated js file"> <replace file="${basedir}/src/main/webapp/iemc.jsp" token="../../resources" value="ext/resources"/> <replace file="${basedir}/src/main/webapp/iemc.jsp"> <replacetoken><![CDATA[<link rel="stylesheet" href="resources/IEM-all.css"/>]]></replacetoken> <replacevalue><![CDATA[]]></replacevalue> </replace> </target> </configuration> <goals> <goal>run</goal> </goals> </execution> </executions> <dependencies> <dependency> <groupId>ant-contrib</groupId> <artifactId>ant-contrib</artifactId> <version>20020829</version> </dependency> </dependencies> </plugin>
4. Frequent build failure error
1) Try not code in the following way
Ext.define(‘YourClass’,{
name:’hello’,
store: Ext.create(‘StoreClass’);
});
Try to instantiate store in initComponent method
2) Missed some required class
3) Required class is in all-classes.js, but its definition after its usage