Search code examples
extjsextjs4sencha-cmd

Sencha CMD: 404 errors when running built production version


I have converted my existing ExtJS 4.1.3 application to use the Sencha CMD recommended structure and tools. I created the structure first, then put my existing app JS files at the place where the single-page JS app should be located.

I currently access the development version of my application at:

{my-server-side-app-url}/sws/dt/index.jsp

where sws is the Sencha workspace and dt is the Sencha single-page app. So far, no problems I believe. Then I run the command:

sencha app build

within my app's directory. This completes with several Yui Compressor Warning (Trailing comma is not legal in an ECMA-262 object initializer warnings, but no errors. So I the production index.jsp page (which uses all-classes.js file, which receives the concatenated output of the app build command above) at URL:

{my-server-side-app-url}/sws/build/dt/production/index.jsp

The issue occurs when all-classes.js attempts to load several files which in theory should be included within itself. These include the controllers which are specified in app.js.

Why are these files not being concatenated in all-classes.js? Below is a screenshot of Chrome attempting to load them from all-classes.js, and of course not finding them.

enter image description here

What did I try? Tried to tweak my app.js to require the controllers via requires; or to make the classes required available via uses as recommended by this question/answer pair, but to no avail.


Solution

  • Try to include all classes you need inside uses or requires section of your app.js.

    Note, that if controller is requiring some views, you may omit that view in require section of app.js, since it will be included anyway when sencha tool will be parsing your controller.

    Try to use full paths when adding files to uses/requires section of app.js. That is, write MyApp.controller.pages.Home or MyApp.store.users.List but now pages.Home or users.List.

    You can use -before-build and -after-build Ant targets to modify your app.js just before sencha tool's YUI minimizer phase start.
    In my case I ended up with searching for all controllers inside app/controller folder and adding their names to uses section of app.js. For it that was enough, since other needed classes were required from within my controllers.

    In order to be able to find uses section of app.js, I've used special comment

    /*ant-generated-content-start*/ /*ant-generated-content-end*/
    

    My app.js

    Ext.application({
        name: 'MyApp',
        appFolder: 'app',
    
        controllers: [
            "main.App"
        ],
    
        uses: [
            /*ant-generated-content-start*/ /*ant-generated-content-end*/
        ],
        autoCreateViewport: true,
    });
    

    My 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>