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.
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>
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.
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
来源:https://stackoverflow.com/questions/14755401/sencha-cmd-404-errors-when-running-built-production-version