As a member of the Sencha Professional Services team, I am often tasked with helping our customers start new projects based on the Ext JS and Sencha Touch frameworks.
More often than not, Sencha Cmd is the foundation of these projects — and while Sencha has documentation explaining its robust features, I find that it’s crucial to explain how Sencha Cmd fits into an application development workflow.
Before we dive into the workflow itself, let’s step back and explore what Sencha Cmd is and why it is so valuable for enterprise software development.
Table of Contents
What is Sencha Cmd?
Sencha Cmd is a command-line suite of tools for building your Sencha applications. Although it has been a part of the Sencha toolbox for a few years, Cmd has recently matured into the cornerstone of Sencha application development.
From scaffolding a new project to minifying and deploying your application to production, Sencha Cmd provides a full set of lifecycle management features to complement your Sencha project. With a rich command line syntax and Ant integration, Cmd is perfect whether you want to integrate it into your enterprise build environment or use it by itself.
Why should enterprises use Sencha Cmd?
Beyond the obvious benefits of lifecycle management tools, apps built using Sencha Cmd have a standardized architecture. This means that apps are easy to maintain and upgrade — but it also means that all Sencha developers build apps the same way.
By standardizing the tools and the application architecture, enterprises can expect all Sencha applications to integrate with their internal systems consistently. Development and deployment can now happen more quickly, and developers require less training and knowledge transfer.
Let’s take a look at the typical workflows that Sencha developers use to build their desktop and mobile applications.
Sencha Cmd: Architectural Workflow
Whether you’re building an app with Ext JS or Sencha Touch the development workflow is essentially the same. However, some commands are needed more often than others.
When first starting a Sencha application, you will likely need the following commands:
- sencha generate workspace
- sencha generate app
- sencha cordova/phonegap init
- sencha upgrade and sencha app upgrade
sencha generate workspace
The first step in building any Sencha application is to create a workspace. The Sencha workspace is an environment in which multiple applications, libraries and frameworks (e.g. Touch and Ext JS) live side-by-side with their shared resources — helping Sencha Cmd understand the pages, frameworks, and the shared code used by the various parts of your application. This also enables Sencha Cmd to automate many common tasks.
To create a Sencha workspace:
sencha generate workspace ~/path/to/workspace
This command is normally only needed once, as the first step in the application development workflow.
sencha generate app
Once we have our workspace we should use Sencha Cmd to scaffold the initial application architecture. This will create an Ext JS or Touch application with default settings and all required dependencies:
sencha -sdk ~/path/to/extjs_or_touch_sdk generate app MyAppName ~/path/to/workspace/app
If you run this command from within an Ext JS or Touch SDK folder, you can drop the -sdk flag:
sencha generate app MyAppName ~/path/to/workspace/app
This command is also generally used once, at the very beginning of a project. However you might use this command more often if you create multiple apps inside the same workspace.
sencha cordova/phonegap init
Many of our customers who build mobile apps with Sencha Touch will also want to package their HTML5 application using Cordova or PhoneGap. Luckily, Sencha Cmd makes this really easy.
While the documentation and a previous post from Ross Gerbasi explain this process in more detail, integrating Cordova and PhoneGap in your Sencha app can be as simple as two steps:
- Create a config.xml file which contains important metadata for your application (see the API docs linked above for an example and more resources).
- Run the following:
sencha cordova init [appId]
or
sencha phonegap init [appId]
…where appId is the fully-qualified app ID from your platform’s developer portal (e.g. com.sencha.myapp).
Sencha Cmd will then automatically scaffold the relevant application pieces through its hooks with the Cordova and PhoneGap CLIs. Later in your development workflow, simply run sencha app build native and Sencha Cmd will automatically copy your bundled application resources into the configured projects for iOS, Android or other platforms.
This command is only needed once, at the point when you first integrate a Sencha Touch application with Cordova or PhoneGap.
Sencha Upgrades
Every so often you’ll need to upgrade your application to either (1) a newer version of Sencha Cmd, or (2) a newer version of the Ext JS or Touch SDK. Using the latest versions of the Sencha tools makes good sense, so you always have the latest bug fixes and performance improvements.
To upgrade Sencha Cmd to the latest version, we can use the sencha upgrade command:
sencha upgrade
Your terminal will automatically check for a newer version of Sencha Cmd and install it.
To upgrade an application to a newer version of Ext JS or Sencha Touch we need the sencha app upgrade command. Simply download the newest framework SDK and then run the following:
sencha app upgrade ~/path/to/new/SDK
However it’s possible that you may have customized a few important pieces of the Sencha application architecture, and you may not want the upgrade process to touch these bits. Luckily, Sencha Cmd has a few optional flags:
- -noa (or –noappjs): Disable upgrade of app.js
- -nob (or –nobackup): Disable backup of application before upgrade
- -nof (or –noframework): Upgrade only the Sencha Cmd scaffolding and not the SDK
Sencha Cmd: Day-to-Day Development Workflow
In the day-to-day development of a Sencha app, developers often need to view their applications in the browser, edit code and test their apps in various environments. Therefore, most developers will use the following commands on a daily basis:
- sencha web start
- sencha app watch
- sencha app build
sencha web start
Now that we have an application started, we can immediately view it in our browser by launching a local web server. No need to configure IIS or Apache on your machine — Sencha Cmd has one built-in.
sencha web start
By default, Sencha Cmd will start a websever hosting our app at http://localhost:1841, so watch the terminal for any additional information.
sencha app watch
At this point, we can begin coding our app.
Having said that, we periodically need to tell Sencha Cmd about updates to our code, so the application knows:
- where its dependencies are located
- that classes have been added, removed, or renamed
- that updated resources (like SASS) need to be recompiled
Running sencha app watch streamlines this process, so we don’t have to manually ask Sencha Cmd to refresh the application.
By running this command in your terminal:
sencha app watch
…Sencha Cmd will watch the filesystem for any changes. When it sees anything change that our application might depend on, Cmd will automatically regenerate our bootstrap files and/or recompile our CSS.
sencha app build
Once we have achieved some level of “completeness” in our application, we will want to use Sencha Cmd to gather the necessary resources and build a version of our app for testing or deployment.
The sencha app build command offers several build environments to accommodate the various deployment needs of your organization. Sencha Cmd also allows additional options for more granular control of the application build process.
The basic format is relatively simple:
sencha app build [options] [environment]
The build environments are:
- testing: meant for QA prior to production. All JavaScript and CSS source files are bundled, but not minified, which makes it easier for debugging if needed
- production: creates a production build that is normally hosted on a web server and serves multiple clients (devices). The build is offline-capable using HTML5 application cache and has built-in over-the-air delta updating feature
- package*: creates a self-contained, re-distributable production build that normally runs from local file system without the need for a web server
- native*: first generates a ‘package’ build, then packages it as a native application, ready to be deployed to native platforms
The commonly used build options are:
- -c (or —clean): Remove previous build output prior to executing build
- -d (or —destination): The directory to which the build output is written
- -r* (or —run*): Enables automatically running builds with the native packager
*Note: this is a Sencha Touch-specific option
Therefore, a full application build command might look like:
sencha app build -c production
Advanced Cmd Workflow
Now that we’ve covered the important commands you’ll be using with Sencha Cmd, let’s take a moment to explore some more advanced pieces of the Sencha application architecture.
Understanding these areas becomes essential when you need to customize how Sencha Cmd views and builds your application.
build.xml
Understanding the application build process is integral to customizing how Sencha Cmd compiles your code.
Internally, the sencha app build command does basic validation and calls in to the Apache Ant build script found in “build.xml” at the root of the application. Specifically, it calls the “build” target of this script. This means the entire build process can be examined, extended and (if necessary) even modified.
configuration files
Sencha Cmd configuration properties are available to the build script but also drive many other features of Sencha Cmd (like the compiler).
In most cases, you can tell where each property comes from by its prefix:
- app. — See “app.json” and “.sencha/app/sencha.cfg”.
- workspace. — See “workspace.json” and “.sencha/workspace/sencha.cfg”.
- framework. — See “cmd/sencha.cfg” in the Ext JS or Sencha Touch SDK.
- cmd. — See “sencha.cfg” in the Sencha Cmd install folder.
build properties
There are many ways to configure build properties, the simplest being to edit one of the build properties files. To decide which file to edit, it is helpful to know the priority of each of these files and under what conditions they are loaded.
- local.properties — If present, this file is loaded first and its properties have the highest priority. As this file is intended to be applied only locally it should not be committed to source control.
- Sencha Cmd configuration properties — “sencha.cfg” in the Sencha Cmd install folder
- .sencha/app/${build.environment}.properties — Setting properties in these files allows you to have different values for properties based on the type of build being run.
- .sencha/app/native.properties
- .sencha/app/package.properties
- .sencha/app/production.properties
- .sencha/app/testing.properties
- .sencha/app/build.properties — These properties are loaded next and have lower priority over the build-environment-specific properties. These are properties that are used by all (or most) environments.
- .sencha/app/defaults.properties — These properties are the last (default) values to load. This file is “owned” by Sencha Cmd and will be updated each release as new properties are added. This file serves as a reference for the defined set of build properties but should not be edited.
The only properties that have higher priority than local.properties are those passed in via the command line.
For example, you might know that Sencha Cmd uses YUI Compressor to compress your JavaScript code during a sencha app build native. But did you know that using Google Closure or UglifyJS instead is just as easy?
In ~/.sencha/app/defaults.properties you’ll see the following around line 150:
# enables / disables yui compression build.compression.yui=0 # enables / disables closure compression build.compression.closure=0 # enables / disables uglify compression build.compression.ugilfy=0
Additionally, ~/.sencha/app/native.defaults.properties sets the YUI flag for you:
# enable yui compression build.compression.yui=1
To use one of the other minification tools, simply set a different value for that property in a higher-level settings file (e.g. ~/.sencha/app/native.properties):
# disable yui compression build.compression.yui=0 # enable closure compression build.compression.closure=1 #or for UglifyJS #build.compression.ugilfy=1
Cmd Packages
One of the newer features of Sencha Cmd is the concept of packages. Sencha packages are simply self-contained code or theme libraries intended for easy distribution and consumption. The general idea is similar to packages in npm, Ruby gems, and Python eggs — just specific to the Sencha ecosystem.
Sencha packages are a great way to share common user extensions or themes — and because many enterprises have built their own core libraries, Sencha packages are the easiest way to integrate that code across applications.
See the sencha generate package documentation for more details.
Conclusion
Sencha Cmd has cemented itself as the foundation of the Sencha application platform. From scaffolding a new project, to minifying and deploying your application to production, the Sencha Cmd lifecycle management features are essential to the enterprise development workflow.
By learning the basic commands Sencha Cmd uses to create and build applications, developers can expect the standard application architecture to smoothly integrate with their existing systems and deployment processes. Understanding the more advanced portions of the Sencha build process will allow developers to completely customize how Sencha Cmd compiles their code.
For more specific information about how Sencha Cmd works with the Ext JS and Sencha Touch frameworks, please read the guides available in each framework’s API docs.
@receptor
That would probably be a topic for it’s own post… but I agree that would be very helpful!
I’ve added that idea to our list of future topics, so hopefully we can tackle that soon.
@Chris K
One of the best benefits of Sencha Cmd’s packages is the ability to re-use code across projects, regardless of where they live. I’ll be very interested to hear about any experience you gain from trying it – definitely reach out at some point!
@Chris K
If your “core” package is part of the same Sencha workspace as your app then this is automatically handled in the way you describe. If they are in completely separate locations… then you would likely have to use Ant in some way to tie into the Cmd workflow.
Nice article.
Arthur,
Great article! I’m working on a project that is a collection of standalone Sencha Touch apps that all pull in a common “core” library. A few months back, I tried to convert this core library into a Sencha Cmd package so that we could take advantage of all the good stuff associated with packages, but I ran into issues coming up with a good development workflow for the core package along with all the applications that depend on it.
The main issue is that when I’m working on a new feature in of one of the apps, I want the app to depend on the “development” (a.k.a. HEAD or SNAPSHOT) version of the core package so that I can make changes to the core package and the app in parallel without having to cut a release of the core package. Once the feature is complete, I’ll make the necessary commits in the core package and application and cut the necessary releases, it’s just the development workflow leading up to that point that seems like would be a pain.
Any ideas?
@DevGuy
I would say it depends on how you look at Sencha Cmd. If Sencha Cmd *is* your build process (for the greater project, not just the Sencha JS application) then you’d have to look into creating custom Ant tasks – which you *can* do pretty easily.
If Sencha Cmd *is not* your build process (but rather a step in a larger process, like Grunt or anything else) then that’s an acceptable approach as well.
I don’t think Cmd is necessarily intended to be a build process for your entire project, though I have seen many developers use it that way.
Interesting article.
But what about running tests during the build process? We use a lot of unit tests for our internal logic and automated UI tests. These need to be run within the build process which is done by our build server (Jenkins). Whenever a test fails the build process needs to be aborted.
As far as I can see, it’s not possible to run this scenario using Sencha Cmd. Lacking this feature, Sencha Cmd is beeing used within our projects for core features only. It is embedded in a Grunt Script, that runs additional tasks including our tests. It would be nice if you could add features like this to your tool, as automated tests are an integral component in an enterprise development workflow.
Very informative article, thanks for sharing the knowledge. Could you please also include Archtect 3 into the workflow? How do you manage multiple Architect applications which are part of shared workspace?
Thanks, Arthur. I hadn’t considered using Sencha workspaces for the same reason Westy mentioned above where all of our apps live in separate git repos and we’d like to keep it that way.
But now that I’ve had more time to think about it, I think we might be able to keep our existing dedicated repo structure and just use a script to initialize the Sencha workspace on each developer’s machine, clone the necessary repos, etc… I’ll give that a shot and see where I end up. Thanks!
Thanks, this great: simple, concise
I agree with Chris Weed suggestion : should be an official documentation guide !
Interesting. Will certainly be coming back to this when I get the chance to look at upgrading our codebase again…
One issue I have with Sencha Cmd, and workspaces, are that it does not fit very well into our code structure.
We have multiple mercurial repos; one core repo with common code shared between all of our products, a few other satellite ones that are included in some of our products, and generally one for the product itself.
These repos don’t just contain JS, but database and server-side code too.
Workspaces in Cmd don’t seem to support this, since the workspace seems to have to wrap all of the contained code, and thus be outside of a repo.
What’s needed, in my view, is the ability to create a workspace and add applications to it by path, as needed. Maybe you can do this now, but last time I looked into it I couldn’t find a way.
This is one of the reasons we are still on Ext 4.1.3.
I’ll know more the next time I try and upgrade…
Cheers,
Westy
Fantastic article! Could you move this into the guides? There are some key components in here that I’ve found through using the cmd help portion and I think it would be nice for people to view the guide and see this level of detail.
I do have a question around the “watch” command. Does it run the build? Seems like a strange question, but I’m currently running the “sencha app build production” quite often as I have occasionally found the build version would break while the development version wouldnt. Is it possible to do something like:
sencha app watch production
?
@westy
Without knowing more specifics about your particular setup, it’s hard for me to comment. Cmd has fully Ant integration, so in theory your Sencha workspace can live wherever you want – you could simply use Ant to move application builds to the “correct” folder in your repo.
Alternatively you can use multiple workspaces – one within each of your “products”. Any common code shared between “products” might live outside in its own Cmd package… but as I said the possibilities are many, and I don’t want to muddy the waters with speculation.
@Chris Weed
We’re working to revamp our documentation, so I’ll be sure to put this on the list of content which needs to be centralized.
“sencha app watch” does not run “build” – it recompiles your sass (sencha ant sass) and refreshes the bootstrap data (sencha app refresh). You’ll still need to run production builds via “sencha app build production” since that takes more resources and in most cases (at least in my experience) isn’t necessary for day-to-day development.
Great post! Trying to see how Cmd’s package would make sense in a larger “portal” type application where other sub-applications are also ExtJS based applications on different hosts (iframed in some cases).
The way we’ve done this is to source ext-all.js from a shared CDN for all apps. This way, Cmd would just serve the purpose of packing + minifying application specific (non core ExtJS) code.
Any thoughts on best way to tackle this?
I’ve always wondered about Sencha Cmd because I don’t use it directly, ever. I use Sencha Architect’s build button, which no doubt shells out to Sencha Cmd. I certainly have never used “sencha generate workspace” before.
Hi, the Japanese translation of this blog article is here: http://www.xenophy.com/sencha/10851
Link to the Japan Sencha User Group: http://www.meetup.com/Japan-Sencha-User-Group/
@Arthur and @Chris K I noticed your discussion on packages and it sounds somewhat similar to what I’ve been trying to get my head around. There’s a forum thread on the topic that didn’t get particularly far (https://staging.sencha.com/forum/showthread.php?282562-Best-practices-for-developing-shared-packages-under-source-control).
The suggestion of how to work in development makes sense, but I’m not sure how you go about doing a production build. I’d want the production build to depend on a specific version of the package – not necessarily the HEAD from source control. The trouble is that the development source goes in the same place as the source for a package that gets pulled from a remote repository – and I’ve seen Cmd complain about version mismatches when it tries to do a refresh.
So how does one do a build that references specific package versions when the workspace already includes the development source? I’m wondering if we need to tweak the build process to use a different folder for packages, thereby forcing it to get packages from the remote repository instead of the place where we already have development source.
@Kent
The easiest way would be to create a local repository of your own packages. The idea being you personally manage the package versions by running “sencha package build” when a package is ready for a new version release. The resulting .pkg file can then be added to your local repository.
See this link for more information on that:
– http://docs.sencha.com/cmd/4.0.0/#!/guide/command_packages
Next, you can configure your Sencha applications to use a specific version of a package by setting a “@x.x” postfix in app.json. Again, see the link above (“Version Restrictions” section) for more details.
That should answer all of your questions.
@Arthur Thanks, but I think I’m missing something (I’ve read all of those guides on the site).
For development purposes, we can have a workspace that includes both the application and package source from source control (using the HEAD). That’s fine. Next step, we can build the package and push into a local repository. That can be taken a step further and the package can be pushed into a remote repository (we think we’ve figured out how to push that into a Nexus server). Ideally, that would even be done by a continuous integration/build server.
The final piece is where I get hung up. If I go into the workspace and set the dependency version numbers in app.json, then the build will try to make sure the packages folder includes the correct version so the correct JS is included in the build. The build will try to expand the package from the local repository (and get it from the remote repository if necessary). The location where expanded packages go is the same place where the development source already resides. When there are version mismatches between what is already in the packages folder and the desired version for the build, then the build generates a warning message and ultimately fails. A specific scenario I think I’d like to address is when someone is working on a change to a package and has committed code to source control, but the app needs to be build with a prior, stable version of the package. In that case, I believe the build will fail because of the version mismatch between what’s already in the packages folder and the desired version for the build. Hence I’m wondering if a build should really use a different packages folder in order to force the build to use the version from the repository. The caveat being that using a separate packages folder means that ALL packages would need to be available via either the local or remote repository – at least I think that’s how it would work.
@kent
Ok, so really the problem boils down to the fact that you want your app(s) and package(s) to live in the same workspace for development (HEAD) – but that you expect application builds to use specific versions of a package (x.x). Do I have that right?
I’ll be honest and say I haven’t ever tried that scenario… but here’s what I think should work.
Your package code (HEAD) should be located here:
~/sencha_workspace/packages/foo/
Your app code should be located here:
~/sencha_workspace/MyApp/
MyApp needs version 1.1 of “foo”, so MyApp/app.json would say “foo@1.1″… which should install the package code here:
~/sencha_workspace/MyApp/packages/foo/
As I said, that’s how I would *expect* this to work… and if it doesn’t there’s two possibilities:
(1) some paths in your Cmd property files (e.g. sencha.cfg) may need to be edited to NOT include the package HEAD folder
(2) there could be a bug in how Cmd gathers things together in a workspace
As a workaround, you could put the package HEAD code into it’s own separate workspace/folder. Let me see if I can get one of my colleagues to comment on this particular situation.
@Arthur
“Ok, so really the problem boils down to the fact that you want your app(s) and package(s) to live in the same workspace for development (HEAD) – but that you expect application builds to use specific versions of a package (x.x). Do I have that right?”
Yes – this is correct.
A difference in what I’ve seen vs. your comments is the location of packages used by an application. Instead of being placed in “~/sencha_workspace/MyApp/packages/foo/” I’ve seen them go into “~/sencha_workspace/packages/foo/” (which is the location of the HEAD source). It might be good if the packages did go in a different folder. Digging through Ant scripts, it looks like there is a ‘legacy’ setting for specifying the location of application packages that would put the application packages in a subfolder of the application. In a sense, that is somewhat similar to what I was saying about having the build use a different packages directory.
Thanks – it might be interesting to hear what your colleague might say.
@Arthur thanks, the workflow is very useful!
I’ve tried Sencha Cmd to create applications, but view parts of those applications could not be imported by Architect (2.2.3/3 ). The thing is if use Cmd then Architect can’t involved in development any more. I have to create applications with Architect for view parts and add in the rest to the applications (i.e. model,store, controller etc.). So my question is how can we make Sencha Cmd work cooperatively with Architect or vice versa ?
@vng
Sencha Architect uses Cmd under the hood, so there’s no reason you can’t add Architect into the mix here. By default Architect won’t create a “workspace” for you, just the app. One caveat however is that multiple Architect projects inside a workspace could be tricky.
If you need a workspace for whatever reason, you would simply generate your Sencha workspace using Cmd then use Architect to create an app as usual.
Pulling Cmd “packages” into an Architect gets a bit tricky as well but can be done. There are a lot of variables in a case like this, so if you’re trying to accomplish that I’d recommend starting a forum thread with specifics.
@Kent –
We will look at providing a way to configure separate “generate package” location vs “extract package” location, but it does seem like if you have the packages in source control it would be best to share them that way. The value I think to having these separate is one can mark the entire folder of extracted packages as “ignored by source control”.
The Cmd package repository is really intended to be used to share packages with those that do not *also* have the source arriving via source control.
It sounds like you would have two copies of a package under development. But wouldn’t that would mean that one developer needs the app pointed at the stable (extracted) version and the developer working on the package would need it pointed at the modified (source controlled) version? It seems that situation would be better suited to a branch for working on the new version of the package. But perhaps I am not fully understanding your scenario.
@Arthur
It’s knowledge to me Architect also uses Cmd under the hood, thank you. What if workspace already created in Architect, can I use the day-to-day deployment as a standalone part in Cmd?
If fact, my project merge Touch and Ext JS within one code base by separate workspace. File hierarchy similar to:
MyProject:
desktop (Architect created)
— app (controller, model, store,view)
— metedata
— .architect
— desktop.xds
tablet(Architect created)
— app (controller, model, store,view)
— metedata
— .architect
— tablet.xds
common
— app (controller, model, store)
resource
index.thml
By this hierarchy, we can achieve:
[1]after the application deployed, users can access both desktop and tablet application with one URL based on device type;
[2]maximum reuse code between Ext JS and Touch;
[3]can separate launch each project in Architect with .xds file, and don’t interfere each other. This ensure there is no dependency between View of Touch and Ext JS;
[4]Architect only use to create project View part (but need empty placeholder for model, store and controller, otherwise each save of Architect will flush code edited from non-Architect IDE);
[5] model, store, controller can be generate/shared with different Javascript IDE, but any changes of View has to be modified in Architect;
[6] using mixing to share common code for tablet and desktop;
I’d pretty like to your way to build, watch, package, and deploy (testing, production) application.
If possible, how far it be? what Ant tasks can be used to customiz?
thanks a lot,
vng
@vng
As I said in my previous comment, you’ll probably want to post this type of question in the forums. I imagine any answer will involve a lot of detail and probably a lot of back-and-forth.
I think I’ve finally seen through my difficulties understanding building with packages. At least to me, it comes down to sharing packages between pages (applications) in the same workspace and sharing packages between projects in other workspaces. In short, we should manage those slightly differently. I’ll update the forum post that I initially referenced as time permits.
Thanks
@Arthur
I move the topic to forum at https://staging.sencha.com/forum/showthread.php?284289-discussion-about-quot-Using-Sencha-Cmd-in-an-Enterprise-Application-Development-Workflow-quot&p=1039889#post1039889
thanks
Good day;
Our company has a product which used several of our customers, around 80, is developed for multi-company.
This product was separated into modules and has changes daily. The product was uploaded on multiple servers and has too many modules, therefore it becomes difficult to execute the command “sencha app build” because the entire application be built again and should be up to all servers.
Sencha CMD would be possible to use some form in which only needed to build the module to which you make the change?
Thank you very much for your prompt response.
Hi!
Have you looked at Cmd app build documentation at
http://docs.sencha.com/cmd/6.x/advanced_cmd/cmd_build.html
The Cmd Forum will be better place to discuss this specific type of question
https://staging.sencha.com/forum/forumdisplay.php?8-Sencha-Cmd
Thanks.
Is there any compressor other than YUI Compressor which is used to compress css file on production build in sencha cmd?
Fashion has compression built in for CSS output, which is what we use for css compression for Ext JS 6 and newer.
create sencha workspace it’s shown below error .
‘sencha’ is not recognized as an internal or external command,
operable program or batch file.