-->

Sencha CMD: 404 errors when running built producti

2020-07-29 23:22发布

问题:

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.

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.

回答1:

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>


回答2:

I still do not understand the problem fully but this is what I did to fix the issue.

I had two models; App.js and Window.js which had a hasMany and belongsTo relationship respectively. In App.js:

associations: [{
    type : 'hasMany',
    model: 'WD.model.Window',
    name : 'windows'
}]

while in Window.js I had:

associations: [{
    type : 'belongsTo',
    model: 'WD.model.App',
    associationKey: 'appId'
}]

I started to suspect these parts as causing the problem because they were the only ExtJS modules giving a 404; the other modules that give a 404 depend on the model files which use hasMany and belongsTo.

I simply removed the associations snippets pasted above (because right now I'm not using them as they don't really work, because I still have to load the data myself rather than children being loaded automagically). Then re-ran sencha app build, and the production version works properly!

If anyone (particularly someone from Sencha) knows exactly why my clumsy fix works, please answer the question or comment below, and I will update the answer.

Thanks @bhovhannes for your answer which still led to useful insight to the problem; +1ed.



回答3:

I had equal problem too,, To solve this problem I just change the name of class. I built using SenchaCmd 3.1.xx and Sencha Touch 2.2