9
votes

I've created an application using Ext JS 4. controllers property in my app.js contains only the main controller:

Ext.application({
    name: 'MyApp',
    appFolder: 'app',

    controllers: [
        "main.App"
    ],

    loadController: function(controller) {
        var oController = this.getController(controller);
        oController.init(this);
        oController.onLaunch(this);
    }
});

MyApp.main.App controller loads additional controllers by name using getController() approach (see loadController() method). These controllers are loaded dynamically and are not listed in my index.html file.

In order to generate production version for deployment to server I am using Sencha Cmd by issuing the following command in my application folder:

sencha app build

Tool finishes normally and compresses all files into one big all-classes.js. The problem is that my dynamically loaded controllers are not included in that file.

Which is the correct way to make dynamically loaded controllers (over 100 in total) to be minified and processed by Sencha Cmd?

I know, that I can list them in my app.js, or include in some file using Ext.require, but I am seeking for correct approach for including over than 100 different controllers, views, models and stores automatically in my build. I believe that are other users of Ext JS, which are creating large-scale applications and are building somehow and I'll be grateful for any suggestions or just success stories, which will help me to find the correct way to build.

1

1 Answers

7
votes

I would put all controllers into the uses array. These should force the tool to keep track on them and include them into the build. On the other hand uses does not require the class to be available at definition time but guarantee them to be available the time the onReady(one is within the application) block(s) is(are) called.

Note that you will need to use the fully qualified names within the uses array!

I do not use the buildtool therefore I cannot test it but it should work.


Update from the comments example provided by @bhovhannes

bhovhannes: I've added a code in build.xml, which collects all names of my controllers into uses array when I do sencha app build. This way I fill nothing in uses array during development, just add controllers into controller folder, because all them are loaded dynamically from my app

app.js

Ext.application({
    name: 'MyApp',
    appFolder: 'app',

    controllers: [
        "main.App"
    ],

    uses: [
        /*ant-generated-content-start*/ /*ant-generated-content-end*/
    ],

    autoCreateViewport: true,
});

build.xml

<?xml version="1.0" encoding="utf-8"?>
<project name="MyApp" default=".help">
    <import file="${basedir}/.sencha/app/build-impl.xml"/>

    <target name="-before-build">

        <echo message="Collecting all controllers in application class property ... "/>
        <fileset id="app_controllers" dir="${app.dir}/app/controller" casesensitive="yes">
            <include name="**/*.js"/>
        </fileset>
        <pathconvert pathsep="," property="app_controller_names" refid="app_controllers" targetos="unix">
            <chainedmapper>
                <globmapper from="${app.dir}/app/*" to="${ant.project.name}/*" casesensitive="no" handledirsep="yes"/>
                <chainedmapper>
                    <regexpmapper from="^(.*)\.js$$" to='"\1"'/>
                    <filtermapper>
                        <replacestring from="/" to="."/>
                        <replacestring from="\" to="."/>
                    </filtermapper>
                </chainedmapper>
            </chainedmapper>
        </pathconvert>
        <echo message="Collected controllers: ${app_controller_names}"/>

        <echo message="Injecting into app.js ..."/>
        <replaceregexp file="${app.dir}/app/app.js"
                       match="/\*ant-generated-content-start\*/(.*)/\*ant-generated-content-end\*/"
                       replace="/*ant-generated-content-start*/ ${app_controller_names} /*ant-generated-content-end*/"
                       byline="true"
                />
    </target>

    <target name="-after-build">
        <echo message="Reverting to original app.js ..."/>
        <replaceregexp file="${app.dir}/app/app.js"
                       match="/\*ant-generated-content-start\*/(.*)/\*ant-generated-content-end\*/"
                       replace="/*ant-generated-content-start*/ /*ant-generated-content-end*/"
                       byline="true"
                />
    </target>

</project>