I need clarity into being able to modularize my JavaScript code that leverages Ext JS. My objective is to create custom classes that extend Ext JS widgets, distribute code among several JavaScript files (.js files).
I have looked into documentation on Ext.Loader but I didn't quite follow the approach to ensure class dependency resolution. My code in a single JavaScript file is working as desired, given that the code sequentialization is as per dependency. But once I break the code in several JavaScript files and want to use in multiple pages, my dependency is in a disarray as all my pages require different classes with varied dependencies.
Considering that I easily achieve code separation and reuse quite easily in regular backend coding, this has baffled me. Please help with inputs. I'm using Ext JS 4.1.1
To enable dependency resolution when creating custom components, use the requires param of Ext.define. It looks like this:
Ext.define("My.custom.Widget", {
alias: "widget.mywidget",
requires: [
"My.custom.TextField",
"My.custom.ComboBox",
"My.custom.Store"
],
constructor: function(config){}
/* ... */
});
For more information, you should read Dynamic Loading and New Class System from the Sencha website. It goes into more detail about how dynamic loading works. It's actually really cool once you get the hang of it.
Almost forgot. You can explicitly call Ext.require to load certain files when you need them. It supports wildcards, aliases and such. There's also Ext.exclude to prevent certain files from loading.
Sencha has some really great guides to help you master the framework.
http://docs.sencha.com/ext-js/4-1/#!/guide
A good one to start with is this one: http://docs.sencha.com/ext-js/4-1/#!/guide/application_architecture Application Architecture. This guide clearly shwos you how to modularize you code and the folder structure the Loader is expecting.
Please have a look at it.
Related
I have a normal, not a REST application. But I don't know if this is relevant. I'd like to use require.js as I have a couple of JS files. I know that AssetBundles can be used, however, my application is not started with a HTML-GET requeset, so AFAIK I cannot use them since assets will not be created.
Background info: my application behaves like a REST application. It provides one JS file that will load other JS files (with require.js; this JS files contain AJAX requests to get JSON data from the application). There are no HTML actions. It provides just JSON data.
Some of those files are libraries like jQuery. jQuery is already provided by Yii2 so I thought the browser could fetch this jquery.js file by require.js somehow. However, it is stored in a #web/assets/54509f77/ folder where 545097ff is dynamic. Same is with bootstrap.js or CSS files. So, how could I define it in require.js?
Can anyone provide an example how to set up a require.js scenario with the Yii2 assets? Or doesn't this make sense and I should provide my own jquery.js?
Feel free to downvote if this is all stupid. I have no experience with require.js...
I've never used require.js, but I have had to turn off Assets when using grunt.
In my experience, if you're not taking advantage of the benefits of Assets (Bundles and dependencies) - you might as well turn it off and provide your own libraries.
$config = [
// ...
'components' => [
// ...
'assetManager' => [
'bundles' => false,
],
],
];
The tricky bit is to get all the Yii JS files back in, and i would refer you to samdarks chapter on Grunt even if you're not using it. It might be helpful.
The following JS files must be included to use the Yii Widgets
"vendor/bower/jquery/dist/jquery.js",
"vendor/bower/bootstrap/dist/js/bootstrap.js",
"vendor/yiisoft/yii2/assets/yii.js",
"vendor/yiisoft/yii2/assets/yii.validation.js",
"vendor/yiisoft/yii2/assets/yii.activeForm.js"
AFAIK, in Meteor, when compiling app, all javascript files and all css files will be merged to one file. I think this behavior will slow down app (because user must download all css and javascript that unnecessary for that page). Moreover, this behavior makes our app not dynamic, because maybe some page, we need different css or javascript files.
So my question is: How can we choose custom javascript and custom css for a template ? Does Meteor support this ?
Thanks :)
AFAIK Meteor is not supporting this exactly in that way. So you are left with two workarounds. One would be writing a own extension which helps you in that regard or finding one which already exists. And the other would be putting your special resources somewhere in the /yourMeteorApp/public folder which is excluded from the merge process (see http://docs.meteor.com/#/full/structuringyourapp). And now you could write some template specific logic to load and evaluate JS and CSS resources from there when your template is accessed. Resources in public are available directly on root level - so public/js/my.js would be available under www.example.com/js/my.js.
UPDATE:
This answer is quite old and in modern Meteor apps you should make use of the import logic (and the imports folder) which didn't exist in that way when I originally answered this: https://guide.meteor.com/structure.html#intro-to-import-export
This should be the best way to handle any dynamic JS requirements and strucutre an app by far nowadays.
In practice this has yet to be a problem for me. The combined javascript files are minified and obfuscated. The fact that any "page load" within the UI is done without a server GET makes the UI quite snappy. I have over 20 packages which add up to 2.1MB of js loading when the app cold-starts. Even on iOS it feels fast.
I like keeping myself busy building modular web-applications, but don't want to spend time where I can save some..
For example I'm building a news module that should be easily implemented over multiple sites, because the same web-application is used.
However not all websites will need a news module. Is it better/easier/faster to create an inline stylesheet/javascript file built into the module itself, than to create a big external stylesheet/javascript with all the libraries? Even though the file for the news module is not needed on all other webpages?
It seems to be much easier to create an inline library in the module itself. So that this only gets loaded when needed, and saves load time and bandwidth on the other pages.
The other thing is that I like writing 'plug-and-play' modules. Say I move a file across the file server into the module folder, and the application will take care of the rest. With inline sheets, I dont have to add new lines to the header/footer etc.
What is the best solution for this? When also taking into account that I rather spend 10 minutes moving a file and it works, than to spend 1 hour appending external libraries just because its more of a 'good practice'?
If you re building web applications, are you using the MVC patern? Do you separate your concerns? (your Templates/Views, your Models, and your logic(Controllers))
If you follow MVC, it makes easier maintaining and customizing your app.
To answer to your exact question, what you need is RequireJS. This way you have only one place to declare your requirements, and RequireJS will handle the rest.. Load order and more..
Quoting from the requirejs website:
Over time, if you start to create more modular code that needs to be
reused in a few places, the module format for RequireJS makes it easy
to write encapsulated code that can be loaded on the fly.
Inline is never a solid way to maintain CSS. Take care to separate the description of your layout from your views. You can easily include the file in the same directory as the module so it should not be an issue.
Or if you want just to load "on fly" some script you can use jQuery.getScript , http://api.jquery.com/jQuery.getScript/ . Otherwise you should follow George's way.
We are developing a javascript component to be used in a JSF app and we're using Dojo.
The thing is we only need specific parts of the library and we'd like to only insert into our webapp the files/folders we use to accomplish our goal.
We could do this 'by hand' but in the future we might need to add other functionality from Dojo and then we will not know what resources we need -> I guess by this moment you realised we are no Dojo/js gurus.
Basically we are looking for a way to automate this process. We were thinking of getting a list of the dependencies and then create a small script to 'filter' the files.
Is this possible ? Have anyone tried this before ?
Thanks.
I may be misinterpreting your request, but I think dojo does what you want out of the box. Since the latest versions of dojo follow the Asynchronous Module Definition (AMD) format, you use a global require function to describe what dependencies a specific block of code have, and only those modules are loaded. An example from the sitepen dojo intro:
require(["dojo/dom", "dojo/domReady!"], function(dom){
var greeting = dom.byId("greeting");
greeting.innerHTML += " from Dojo!";
});
If you only want to have to to load a single <script/> tag, you'll want to look into the dojo builder. Using the online build tool You can select what packages you want included into the dojo.js layer and it will bundle everything up into a zip file that includes dojo.js/dojo.js.uncompressed.js which contains dojo core in addition to the modules you selected.
Ok, we did this by doing the following (just in case anyone will need this):
* declare a JSF filter and map it to /js/* (all dojo resources are under /js folder, this may need to be modified to fit your folder structure); this way, all requests for a dojo resource will be filtered.
* in the filter class, get all the requested files: (HttpServletRequest) request).getRequestURI() and write it line by line in a file: now you have all the needed resources.
* parse that file with a script, line by line, and copy the files to another location -> build the folder structure.
* use the created files in your WebContent folder (or wherever you need it), you have a clean library -> you only deploy what you use.
The web is littered with full-blown JavaScript libraries who say they will save your day and make your web development life much easier. You get encouraged to include these “mere 80 kb” libraries that is supposed to be the solution to all your needs, and practically make the web site work by itself. Needless to say, I’m not a big follower of JavaScript libraries,, especially since they almost always include lots of superfluous code, so I thought I’d put together a tiny library with only essential JavaScript functions.
The result of that is EJ – Essential JavaScript.
EJ consists of functions that I use all the time and they make writing JavaScript go faster and the result is being able to do work more efficiently. It is also about having the things you would write again and again for every web site you produce in one neat and tiny file instead, to be able to focus on the new things you need to address
We have a large web project, where we need components which can talk to each other which can be put in a central repository of components for different projects.
Using reuirejs and Backbone for the modular development. Went through different boilerplate available for backbone and requirejs, but none matched my requirement. So I have created following directory structure. It can be explained as follows.
---resources
|---custom-components
|---mycomponent
|---js
|---views
|---models
|---collections
|---css
|---templates
|---mycomponent.js
|---mycomponent2
|---js
|---views
|---models
|---collections
|---css
|---templates
|---mycomponent2.js
|---libraries
|---backbone
|---underscore
|---jquery
|---jquery-ui
|---jqueryplugins
|---jcarouselite
|---thirdpartyplugins
|---page-js
|---mypage.js
|---mypage2.js
resources directory will contain all the resources. Under that we will have 4 directories as mentioned.
libraries, jqueryplugins and thirdpartyplugins are obviusly the directories for the name they say.
page-js directory will contain the actual main-js which will be used inside our html file as requirejs data-main attribute.
Custom-component is where all widgets created by us will reside, as you can see it has a js file with same name as that of the component, which will be entry point of this widget. This directory also has directories for js, css and templates. CSS and templates will be loaded by text plugin and CSS plugin respectively. Js directory will contain all the backbone code to make this widget work.
Custom components will be asked by main-js residing in page-js.
Coming to what I need.
1. I want experts to have review this directory structure in perspective of large web projects, where you will need to share your widgets with other teams. suggestions are welcome.
2. My each custom-component will define a module, which will have dependencies within package structure as well as outside package structure. I want to know, if there is any way to use r.js to optimize only my custom widget dependency within package structure and let the plugins and libraries optimized separately.
3. I am developing single page ajax application, so I will be asking modules on demand so I need to cleanup modules and widgets when I dont need them, is there any way for cleaning up I should be aware of?
About the directory structure
As a directory structure pattern, I highly recommend using directory structure of cakePHP. it's really robust as in words!! I'm running multiple apps (one of them is as big as Groupon) and it works just like a charm.
You may need to tweak it a little because, you know, cake is a PHP framework and yours is a javascript one.
Here is the cake's awesome MVC directory structure:
Please note that you may host thousands of apps on a single cake installation. so if you're interested, what are you waiting for? go to their site and read their docs.
About the cleaning up techniques
Well, here is one of the downsides of the Javascript which I don't like. there is no real way to destroy a OO module like in Java or C++. here we don't have such things like C++'s ~ destructors.
For many years, programmers use module = null to free up memory from un-used codes.
Take a look at these also:
Can dynamically loaded JavaScript be unloaded?
Loading/unloading Javascript dynamically
How to unload a javascript from an html?
Hope it helps and good luck on designing your app ;D
Probably I'm late in answering this, but anyway let me share my views here, incase someone else finds it useful.
Your directory structure looks alright. It is always a better design to keep your business components self contained in to a particular directory. I will not recommend Cake MVC structure which break the Open Close Principle. Also have a look at the directory structure recommended by http://boilerplatejs.org which is a reference architecture for large scale JavaScript development.
I do not get the question very clear. when r.js is run it will optimize all JS files it find in the directory (exclude possible) and then create a single script by going though the dependency tree. In production you only need that single script (plus locale files if i18n plugin is used)
Read my blog post below. It might give you some hints: http://blog.hasith.net/2012/11/how-much-multi-page-single-page.html