I am in to developing a large client side app with very complex views on each modules using Extjs5. I have developed apps in Extjs but they all compile to a single app.js file. So based on the complexity of the views in all the app mockups I am estimating the size of the app will be around 20MB to 25MB even after compiled.
I was thinking to split the modules as separate applications and create a master app with tabs or something, which triggered will be loading individual apps in a iFrame within the master app. But I doubt if the iframe behaviors are altered in different browsers or deprecated in any future browser releases, that will be another big problem.
So is there any way in sencha cmd, which compiles app in separate files based on modules and load them on demand out of the box ?
If not what is the advisable solution I should be going ahead with.
Starting with Sencha Cmd 6.5 you can split your code into multiple files. To achieve this, you have to split your code into exjts packages if it’s not already done:
In the end, you should have a similar folder structure to this:
workspaceDir
|
+->appA
+->appB
+->packages
|
+-> local
|
+->CoreComponents
+->ProcurementModule
+->ForumModule
+->BOMModule
+->ReportModule
In your app.json file you could add/move your packages from requires to uses. As a last step you have to add the new package-loader to the requires array in app.json.
You end up with something like that:
{
// [...]
"uses": [
"ProcurementModule",
"ForumModule",
"BOMModule",
"ReportModule"
],
"requires": [
"CoreComponents",
"package-loader"
]
// [...]
}
Next you need to start your Sencha Cmd build with the additional flag -uses.
If you do this, Sencha Cmd will build your optional packages first and add them to the resource folder in your build output directory.
sencha app build -uses production
It is important, that you don't have any references to classes in optional packages from your main application. Otherwise your build will fail.
Since your optional packages are not loaded automatically on page startup you need to trigger the loading process manually. I do it usually within the routing process of my AppControllers.
Here an example:
Ext.define('MyApp.view.main.MainController', {
extend: 'Ext.app.ViewController',
requires: [
'Ext.Package'
],
routes: {
'forum': {
before: 'loadForum',
action: 'showView'
}
},
loadForum(action) {
if (Ext.Package.isLoaded('ForumModule')) {
action.resume();
} else {
//Loading mask code here [...]
Ext.defer(() => { // it needs some time to show up the loading mask
Ext.Package.load('ForumModule').then(() => {
//Remove loading mask code here [...]
action.resume(); //proceed router process; all package files loaded
});
}, 500);
}
},
showView() {
this.getView().add({xclass: 'ForumModule.view.MainView'});
}
});
More information on this topic:
http://docs.sencha.com/cmd/guides/whats_new_cmd65.html#whats_new_cmd65_-_dynamic_package_loading
Related
I used a Gatsby starter for my static site, and one of the pages included in that starter is a demo page with all of the UI elements.
I want to keep the page (so I can copy and paste from the demo) but don't want to be publicly available. How do I "unpublish" without deleting the file?
Is there a way to tell gatsby-node.js to skip that page when generating the public facing site?
There are a bunch of Gatsby Node API helpers that you can use, one being deletePage.
If you have a page src/pages/demo.js, this will delete that page during creation.
// gatsby-node.js
exports.onCreatePage = async ({ page, actions: { deletePage } }) => {
if (page.path.match(/^\/demo/)) {
deletePage(page)
}
}
Lots of good options here, just wanna throw my hat in the ring for plugin options that prevent pages from being created in the first place:
If it is a page component, i.e inside src/pages folder, gatsby use a plugin called gatsby-plugin-page-creator to generate page, and it recently accept a ignore patterns.
There's a caveat, the built-in gatsby-plugin-page-creator doesn't take user options, so we'd have to rename the pages folder to ignore it.
root
└── src
- └── pages
+ └── screens <-- rename
└── index.js
└── ignore-file-name.js
And then in gatsby-config.js:
module.exports = {
plugins: [
{
resolve: `gatsby-plugin-page-creator`,
options: {
path: `${__dirname}/src/screens`,
ignore: [`ignore-file-name.js`],
},
},
]
}
If it is a programmatically page generated from markdown or json, you might be able to ignore it in gatsby-source-file-system, as pointed out in this github comment.
The example there even ignores file based on environment, which is more useful since you can still see your reference during development, but it won't show in build.
{
resolve: `gatsby-source-filesystem`,
options: {
path: `${__dirname}/content`,
ignore: process.env.NODE_ENV === `production` && [`**/draft-*`]
}
}
An alternative would be to add a "published" attribute to the frontmatter assuming it's a markdown page that could be a true or false value. Then add logic into your gatsby-node.js file which looks at this to determine whether or not to run createPage().
I am swapping out one IndexedDb wrapper(localForage) for another(Dexie) and I am unable to run the application because the recommended way to integrate it within the ExtJs framework is not working for me. What have I done wrong?
My current version/s of ExtJs:
framework: 6.6.0.258
Cmd: v6.6.0.13
Dexie version is latest
The Dexie documentation recommends that you set up your database like this
var db = new Dexie("MyDatabase");
db.version(1).stores({
myStoreName, "++id, indexOne, indexTwo",
myOtherStoreName, "++id, indexOne, indexTwo",
});
myExtJsFile.js
Ext.define('DataLayer.Inferface', {
extend: 'Ext.Component',
xtype: 'DLInterface',
config: {
stuff...
db: new Dexie("mydatabaseName"),
}
The way that the ExtJs documentation recommends using an external library is to reference it in the app.json file in the js array
app.json
"js": [
{
"path": "${framework.dir}/build/ext-all-rtl-debug.js"
},
{
"path": "dexie.js" //Dexie is located in the same folder as app.json
},
I get a successful build yet when I go to deploy it(run locally) I get the run-time error listed in the title of this question. I am aware that the intellisense in VSCode isn't working all that good, so I didn't really think much of it when I was not appearing to have access to the global Dexie object.
I have tried several different ways, and places to load this library with m=no luck. I would use a CDN, but it is an offline capable app so I really want the library locally. How should I be getting, referencing, and using 3rd party libraries in Ext?
Thanks.
If You use external library in Ext.define, try to include external libraries before extjs libraries (ext-all-rtl-debug.js, app.js etc.).
Another solution - don`t attach remote libraries on class defines - use initialize/initComponent instead. Example:
Ext.define('DataLayer.Inferface', {
extend: 'Ext.Component',
xtype: 'DLInterface',
config: {
stuff...
},
initComponent: function () {
this.db=new Dexie("mydatabaseName");
this.callParent(arguments);
}
I got a "framework" created by us using AngularJS. It allows to build questionnaire system and it has many different parameters that control the behavior of framework.
Using this framework we've created 2 projects: projectA and projectB. The difference between these projects are the settings and assets (css, img, ...)
Both projects are stored on the same branch in git and only config file defines the project customization.
I can't think of the best way how these 2 projects can be easily deployed separately from the same code source using Gulp or something other.
Here are some ideas I got for the moment:
1. Have both settings files and images (e.g. logo_A.png and logo_B.png) in the code and choose appropriate during build using Gulp
2. Create folder customizations that will have 2 subfolders A and B with corresponding settings and assets
3. Create separate repository for each project installation scripts (not the code) and these scripts will do all the work
What is the best way in this case?
Finally, the easieast and most understandible solution was to create additional custom folder.
Assets
In addition to normal application files I got now custom folder with 2 subfolders: A and B each of them containing assets (css, img) that correspond only to concrete project.
In gulp I've used yargs module which allows to pass parameters. After reading project name from input I can looks inside custom folder to see if there are resources interesting for me (I've just added custom folder into the resources paths).
var customPath = './custom/' + app.name;
exports.paths = {
web: {
//Resources
styles: ['./app/**/*.css', './app/**/*.scss', customPath + '/**/*.css', customPath + '/**/*.scss'],
...
And the call to build task now looks like this: gulp build --name A.
Configuration
One more thing was done for configuration file of AngularJS that contains constants. I've used gulp-ng-config plugin which allows to build AngularJS configuration (constants) file on fly. In my flow, first I check if custom configuration file exists inside custom folder I use it, if no I'm using default one from application.
var getAppScripts = function() {
return $.eventStream.merge(
gulp.src(config.paths.web.scripts)
.pipe($.jshint())
.pipe($.jshint.reporter('jshint-stylish'))
//.pipe($.eslint())
.pipe($.eslint.format()),
getAppConfig())
.pipe($.angularFilesort());
};
var getAppConfig = function() {
var configFile = config.paths.web.custom + "/app.config.yaml";
if (fs.existsSync(configFile)) {
return gulp.src(configFile)
.pipe($.ngConfig(config.app.name, {
parser: 'yml',
createModule: false
}));
}
else {
return gulp.src(config.paths.web.config);
}
}
I'm using VS 2015, ASP.NET 5 (MVC 6) and Gulp to write a SPA with angularjs and supplementary modules. My target framework is dnx451. I've read several best practices which state that the response from Index should have a strict no cache policy set, and all other resources (e.g. js, css, img) should all be heavily cached. In doing so, the browser always downloads the lightweight page and caches the scripts. When publishing, I am trying to have a gulp task which concats/uglifys all my JS files and outputs a single app.min.{version}.js (also for the less -> css file). This gives the benefit of always downloading the latest file version, but keeping them in cache while it is the latest and greatest.
Is there a way to get the Version (from project.json) and the build (from the * portion of project.json) from my gulp task? I am looking for a way to have the file {version} portion of the name match the version/build of the website.
I have seen examples of using process.env in gulp for VS environment variables, but am having trouble putting the pieces together to achieve the desired Version.Build format.
I have tried:
var project = require('./project.json');
gulp.task('js-publish', function(){
project.version; //this give 1.0.0-* (makes sense since its a string)
});
and
gulp.task('js-publish', function(){
process.env.BUILD_VERSION; //which is undefined
});
You want to use the gulp-rename NPM package to rename the file. Add gulp-rename to your package.json file. Here is an example of how it can then be used in your gulpfile.js:
var rename = require("gulp-rename");
// rename via string
gulp.src("./src/main/text/hello.txt")
.pipe(rename("main/text/ciao/goodbye.md"))
.pipe(gulp.dest("./dist")); // ./dist/main/text/ciao/goodbye.md
// rename via function
gulp.src("./src/**/hello.txt")
.pipe(rename(function (path) {
path.dirname += "/ciao";
path.basename += "-goodbye";
path.extname = ".md"
}))
.pipe(gulp.dest("./dist")); // ./dist/main/text/ciao/hello-goodbye.md
// rename via hash
gulp.src("./src/main/text/hello.txt", { base: process.cwd() })
.pipe(rename({
dirname: "main/text/ciao",
basename: "aloha",
prefix: "bonjour-",
suffix: "-hola",
extname: ".md"
}))
.pipe(gulp.dest("./dist")); // ./dist/main/text/ciao/bonjour-aloha-hola.md
I'm using the Sencha Command Line 3 tools with a newly generated Sencha Touch 2 application.
Assuming my app.js file looks like this:
Ext.application({
name: "CA",
event_code: "test123",
launch: function() {
console.log("application launched!");
}
});
My views and object stores depend on generating a URL based on CA.app.event_code equaling "test123";
During development in the browser, everything works fine, CA.app returns the variables I need.
When I compile my application with sencha app build and try to run the minified version in the browser, I get an error like this:
Error evaluating http://localhost:8888/app.js with message: TypeError: Cannot read property 'event_code' of undefined localhost:11
I'm not entirely sure why this is happening or how I can fix it. I am open to any and all ideas or suggestions, any pointers in the right direction will be greatly appreciated.
Ran into the exact same issue. You have no access to the namespaced app within the views... really sucks that they let you in development and not when built. Anyway, I got around it by adding a static helper class and using that all over my app:
In /app/util/Helper.js:
Ext.define('MyApp.util.Helper', {
singleton: true,
alternateClassName: 'Helper',
config: {
foo: "bar",
bat: "baz"
},
staticFunction: function() {
// whatever you need to do...
}
});
Then in your view or controller:
Ext.define('MyApp.view.SomeView', {
...
requires: ['Events.util.Helper'],
...
someViewFunction: function() {
var someValue = Helper.staticFunction();
// and you can use Helper.foo or Helper.bat in here
}
});
For reference, here's some documentation on Sencha Singletons. And one important note: make sure that your Helper singleton is in it's own file! If it's small, you may be inclined to put it at the bottom of your app.js, and things will work at first, and the build process will work, but the code will not. Don't worry, the build process puts all of your JS code in one big, compressed file anyway.