Best way to import JavaScript files into one file? - javascript

I have a background in coding in languages that have a concept of "classes". Now that I am coding JavaScript, I would like to code in a similar way so that each object oriented "class" I create is its own separate file.
see Accessing "Public" methods from "Private" methods in javascript class
see http://phrogz.net/JS/classes/OOPinJS.html
In other languages, I would create import statements at the top of the class file to ensure other custom classes that were used within a class file so that the other custom classes were compiled into the final binary.
Of course JavaScript is not a compiled language; however, I would still like to be able to be include some kind of "import" statement at the top of custom class files so I could ensure the imported JS "class" file was available for the user's browser to download.
It would be ideal if there were a 3rd party tool that combined all of my separate class files into one JS file so the browser only had to make one HTTP request for a single JS file instead of many calls for each indicidual JS "class". Does anyone know if such a tool exists where it would do the following:
allowed me to choose which JS files that I wanted to include in a single JS file
crawled thru the files I selected in step 1 and found all the "import" statements at the top of each custom "class" file. These "import" statements could simply be specially formatted comments in the code that the 3rd party recognizes as import statements.
The 3rd party would then create the single JS file with all of the files that were selected from step 1 and from all of the imported files that were found in step 2.
Some popular JavaScript frameworks seem to do just that. For example, jQueryUI allows you to customize the download of a single jQueryUI source file by allowing the user to check off which objects you want to use. If you uncheck an element that is needed for an item that you checked off, then the form tells you that there is a dependency you need to rectify before being able to proceed to download the file.
see http://jqueryui.com/download/
So is there a 3rd party tool that allows a developer to use some kind of "import" statement comment to ensure that many dependent JS files (and only the ones that the developer needs) to be combined into a single JS file?

RequireJS was built for exactly this purpose.

Have a look at Require.js. It lets you import various javascript files in a modularized fashion and add the required dependencies between them. Also at the end you can minify them all into one single JS file using r.js

A trivial batch file can do this for you:
#for %i in (classes/*.js) type %i >> build.js
This works best if your JS source files are all in one folder, and this example assumes that folder is named classes. It gets a bit more complicated if you have subfolders, but a similar principle can be applied.

Have a look at GruntJS, JQuery uses it for building. If you don't care for HTTP requests, you can use already mentioned RequireJS, which also has nice async methods to load files, which can improve perfomance in some situations.

Check out this class https://www.youtube.com/watch?v=KnQfGXrRoPM
This allows for importing on the fly within classes. also it allows
for importing all classes within an folder and all of its sub folders.
and its really simple because it is just a prototype function added to String.
just by adding the importer class you will call in classes like "com.project.Classfile.js".import();
or "com.project.*".import() to get all sub-classes.
fork on - https://github.com/jleelove/Utils

Related

How to deal with multiple identical classes in a project?

In a multi-tenant project, tenants could have different UI and functionality. To that end, there is a structure like this:
TenantA
SiteHeader.ts (class named SiteHeader)
TenantB
SiteHeader.ts (class named SiteHeader)
... 20 other tenants
On the web page, the .js declaration dynamically generates (server-side) the reference to the correct tenant:
<script src="../{CurrentTenant}/SiteHeader.js"></script>
On this same page, Main.ts needs to reference the correct SiteHeader. Since I can't (and don't want to) have import {SiteHeader} from 'TenantA/SiteHeader' and import {SiteHeader} from 'TenantB/SiteHeader' and 20 others, I am forced to simply declare it as a var, which points to whatever js was loaded by the parent page:
declare var SiteHeader;
However, it causes Duplicate identifier errors in each SiteHeader.ts. And occasionally in the Main.ts as well. I am able to drop down to the command line and compile each SiteHeader.ts manually, but it's chore.
How can I resolve this sort of situation?
Not that it matters much, trying to bring TypeScript to an old school WebForms project in Visual Studio 2019.
You could create interface SiteHeader and make all tenants implement it. But I am not sure how runtime would work with <script> tag in combination with external modules. Have you considered internal modules (namespaces) or using dynamic import() (should be supported in TypeScript)?

How to reduce JavaScript Files in Magento?

I am new to Magento but work in webdev for several years now.
My goal is to optimise an existing Magento installation in terms of speed.
Looking at all the JS and CSS files used within this installation the first thing I aim for is to combine those file or better reduce the number of modules used. I am aware of the "combine files" function within the config menu, but that does lead to conflicts between jQuery and prototype which is why I am trying to first get an understanding of what types of frameworks/modules etc are used.
This is a list of all JS-files required by the homepage of this installation:
jquery-1.12.3.min.js
prototype.js
ccard.js
validation.js
builder.js
effects.js
dragdrop.js
controls.js
slider.js
js.js
form.js
script.js
menu.js
translate.js
cookies.js
func.js
jquery.easing.1.3.min.js
efects.js
jquery-1.11.0.min.js
jquery-migrate-1.2.1.min.js
jquery.noconflict.js
swiper.min.js
jquery.easing.js
jquery.scrollTo.min.js
jquery.global.js
remodal.min.js
jquery.themepunch.tools.min.js
jquery.themepunch.revolution.min.js
easyzoom.js
ios-orientationchange-fix.js
jquery.swipebox.min.js
jquery.themepunch.plugins.min.js
jquery.themepunch.revolution.js
jquery.slider.js
jquery.selectbox.js
jquery.bxslider.min.js
jquery.tweet.js
cookieconsent.min.js
gtm.js?id=GTM-5W7V6F
analytics.js
ec.js
What would be the best approach to clean up this list in order to keep functionality while reducing request and load?
For starters i see that you load 2 versions of jQuery
jquery-1.12.3.min.js and jquery.easing.1.3.min.js
What i did was combine the javascript files with the config settings like you said and use the jQuery.noConflict() https://api.jquery.com/jquery.noconflict/. Don't use the $ (dollar) sign to use jQuery but write it fully because prototype also uses it and it creates problems sometimes. There will be some problems which you should try to fix. Sometimes it's just adding a ; to the end of the file or function.
I then tried to figure out what code was needed and what wasn't so i could remove some of it.
Magento Inbuilt provide this things
Login admin panel
goto System->configuration->Advanced->Developer->JavaScript Settings and set Merge JavaScript Files to yes
You can do same for css and you will see very few request in your web page

How to make a plugin based project

I want to make a web based application that can have plugins/apps 'installed' to it. What i mean by Apps is say a weather app which has its own CSS and JS files in a container with a specific ID like id="Weather-app".
The Problems: (Assuming everything is on the same server)
Having Duplicate IDs, Class'
Conflicting script and style sheets
how to actually check a folder named 'Plugins', Find a file named Weather-app and then load the contents of 'Weather-app' into the main Application.
I have looked around on Google and haven't managed to find any information on how you would go about this. Hopefully someone on here will know. I would like to use JavaScript & JQuery if possible. I dont know if there is already a source out there for this purpose but if there is a link would be great!
1 - Avoid the use of IDs for generics, always use classes instead.
2 - Prefix the classes on HTML generated by plugins you are creating with some name space. i.e.: js-plugin-foobar-nameOfClass
You can avoid having the user add a ".js" and a ".css" file for each pluggin. You can generate css classes with javascript. That way you will only have to import one file for each pluggin: How to dynamically create CSS class in JavaScript and apply?
Take a look at the jQuery widget factory, you can build your plugins to use it, and that should facilitate your life. They also have some coding guidelines: http://jqueryui.com/widget/

How do I put multiple files into a single namespace/module? (javascript)

I've been reading about the module pattern, but everything I read assumes that the entire contents of the module will be in a single file. I want to have one file per class.
I've resorted to doing this at the top of every file:
if(window.ModuleName === undefined) { window.ModuleName = {}; }
ModuleName.ClassName = function () { ... }
But this allows files to be included without their dependencies, which is also annoying. For example, lets say there is ClassA which uses ClassB, and "ClassB.js" is left out of the HTML, then ClassA will throw up errors. As far as I'm aware Javascript lacks an import statement, so in this case I actually want everything to be in a single file.
I assume that large javascript projects are broken up into multiple files, so there has to be a way around this. How is it generally done? Is there some tool that will combine multiple class files into a single module file?
This is a big topic but let me explain as much as I can. Javascript requires that you have preloaded anything you intended to use, which is why your module pattern has all the "things" in the same file. But if you plan to separate them in different files then you have to manage it before using. I suggest the following approaches
Concatenate them before serving them in the server. For example in jsp, you can create a servlet that returns contenttype = "text/javascript", inside that servlet you can append all the scripts you need in one dynamically generated script then return it to the client.
In your ant or maven builds etc, there are configurations where in you can concatenate them the files you want together. This is a common practice therefore you should find many reference in the internet.
Lazy-load javascripts. This is my preferred way. I use Lazyload javascript library. Basically I declare the dependencies of certain codes much like "import" in Java, then before i call any of them i load their dependencies. This allows for optimized dependency loading without scripts redundancies. The problem is you need to write some fairly complicated scripts to do this.
Hope to help.

Grails: Javascript files in views folder

I'd like to split my views in Grails into 2 files a .gsp file and a .js file so that I get a cleaner Javascript separation from my views. So here's an example:
views/index.gsp
views/index.js
views/home/index.jsp
views/home/index.js
But when I simply add the index.js script reference like this:
<script src="index.js" type="text/javascript"></script>
all I get is a 404.
Does anyone knows how to deal with this?
A great benefit would be to have the ability to use view data inside the index.js file to produce the desired content.
Matthias.
Actually, it should be perfectly possible to serve a JS file (or any other file type) as a GSP from your grails-app/views/ directory. The only thing you have to do, is define a suitable URL mapping for those GSPs, e.g.:
"/javascript/home/index"(view:'/home/index.js')
With this URL mapping, you can put your JS code into grails-app/views/home/index.js.gsp (note the trailing .gsp) and you can use any grails tags in your JS source. To ensure that your JS is delivered with the correct content type, you may want to place
<%# page contentType="text/javascript"%>
at the beginning of your GSP.
Unfortunately, the createLink tag doesn't support link rewriting to views, but it should be easy to write your own tag to create those links.
Anyways, keep in mind that this won't have a very positive impact on your app's performance. It's usually better to have static JS files (and also serve them as static resources) while passing dynamic stuff as parameters to JS functions for example. This will also keep you from some headaches wrt. caching etc.
The idea is good, but Grails has this directory structure for a reason. The view folder is intended for a certain artifact type (views)..
You could clone your view folder structure under web-inf, but that gives you more work as I guess the idea behind this is to keep related files close together for convenience reasons.
Even though I'm not to excited about storing Javascript together with the view I loved Robert's idea of hooking into the build process by using build events to copy javascript sources into the right directory! If you decide to go down that road you might as well compress the sources while you're at it. ShrinkSafe is popular library.
I don't think you are allowed to access js inside views/
if you need to do that ... here is the trick
create your js and rename it with myjs.gsp (use "")
iniside _myjs.gsp type you js
... write down you js in here ...
inside you gsp (for example: index.gsp, view.gsp, etc)
type this tag to upload you js
Update 2:
Grails offer the possibility of hooking into the build lifecycle using custom events.
An event handler can be written which synchronises all JavaScript files under grails-app/views with the target folder of web-app/js.
Place the custom code in $PROJECT/scripts/Events.groovy. The PackagingEnd is a good target for the invocation, since it happens right after web.xml is generated.
eventPackagingEnd = { ->
// for each js file under grails-app/views move to web-app/js
}
Update
If you'd like the JavaScript files simply 'meshed' together, you can do that using symlinks, e.g.:
grails-app/views/view1/index.js -> webapp/js/view1/index.js
As far as I know, there is no way of forcing grails to directly serve content which is outside of web-app.
Alternatively, you can inline your JavaScript, but that can have performance implications.
JavaScript files belong under web-app/js.
Then you can reference them using <g:javascript src="index.js" />.

Categories