Server settings in modern JavaScript apps - javascript

I'm looking for a solution to have server settings in a config file of some sort separate from the JS app (which I could be running in dev or prod (built) mode) but allow for the server to replace the file with a new one at random point in time (when settings have changed) and allow the JS app to pick it up and refresh it's settings.
This is mainly for setting URLs to API endpoints.
My choice of JS framework is Angular 1 and 4 but answers geared generally towards various JS frameworks/libraries are applicable.

to have server settings in a config file of some sort separate from the JS app
If you are thinking about having your server settings exposed to the front you are gonna have a bad time ;)
I will assume that you think you will keep API URLs and maybe some config along with it in a separate file while you develop. Then I can advise two approaches:
1.) SIMPLE - Have a single JS file with a single object with all the necessary API URLs and settings in a tree like structure for organisational purposes. So you have a dev, a test and production property with everything in them. Once you load app 1st thing that should the app do is load the correct settings. This is fast and doesn't require any additional knowledge. Everywhere you had something configurable hard coded you replace it with a variable that derives from that file. This should suffice for simple applications.
2.) POWERFULL - For bigger applications with loads of different dependencies and more formal and professional approach do what most people do, use NodeJs, leverage Grunt or Gulp to help you version dependencies and write scripts for different builds. It requires you to install and learn to use new stuff but offers you way more power.
Even better combine this two approaches, link the external dependencies dynamically with the build and internal via including the correct JS file with all the API information.
You can also use other npm modules to assist you with your development like precompiling CSS, lint your code, rearrange and organise files by types into folders, auto-name files or folders.
Basically, MOST of the REPETITIVE tasks you do while developing can be automated this way. This truly shines on bigger projects when all this is handled by someone who is proficient and experienced with the 2nd approach, it can save months of repetitive tasks across the team.

You could use gulp (or even npm) as a task runner to do this kind of work. Maybe this article would help? https://www.keithcirkel.co.uk/how-to-use-npm-as-a-build-tool/
The main point of a task runner is that you can set a specific variable ie prod or development, and the task runner can then switch out your config files with the present definitions for prod or dev config.

Related

On-demand in-memory bundling of Javascript files at runtime

I'm wondering whether there is a nice way to continuously bundle complex javascript files in a single, customized, JS file that is then directly served to clients, sort of a "smart" CDN.
My use case is really simple: serve JS files to different web applications from a microservice, like RUM scripts (or also Google AdSense scripts, or anything else that works by importing a JS file from a service in your web application).
Problem is, at every request the JS file will be different, based on several parameters (for example, IP address of the request, query params in the URI, back-end configuration, and so on).
Solution can be trivial, for example I could manually bundle JS files by concatenating strings, and then serve the resulting file, with minimal logic or with the help of a standard template engine that handles placeholders/pre-processing within the source JS files.
I was wondering if there is a better way to do this, like using JS bundlers as Webpack or Parcel.js.
My experience in using JS bundlers is limited to their standard usage, so that use them in the build process (or at application startup), and make them write to disk the compiled JS file.
Is there anything better to use, or a best practice to suggest for my use case?
Programming language makes no difference, I added the node.js tag because ideally the backend would be developed using Express.js, but also Java or other compiled languages would be ok.
Thanks in advance,
Sure, that's definitely possible.
Esbuild (a new, fast bundler) has a well-documented Node.js API: https://esbuild.github.io/api/#js-specific-details
The two other bundlers you mention are similarly available:
Webpack has a well-documented Node.js API: https://webpack.js.org/api/node/
Parcel has a well-documented Node.js API: https://parceljs.org/api.html
Then it's just (always "just" ;-) ) a matter of hooking those up to the web framework of your choice and going to town.
I'd recommend thinking about caching in advance, though – even if e.g. Esbuild and Parcel are pretty fast, not doing work is always faster than doing work.

Is it normal that a simple counter react app is more tham 100MB?

I am a newbie with React.js and just for practice i made a simple counter web app.
But i noticed that the project is more than 120MB.
Is it possible? do i need to do something to shrink it?
120mb can he huge or nothing at all depending on where you get that number. Remember, a modern web app (such as one built with React) needs build tools and often a development server and more. Also, if you are using typescript it will in itself add a compiler that is up towards 40mb.
So if we look at the source directory you'll have your own code plus some build configuration (probably in a webpack configuration file) which totals a few kilobytes. But then we have the node_modules folder which contains all the dependencies for both your own code and the build tools. This isn't a problem and since this folder won't be sent to the client and you shouldn't even commit it to your SCM since it can be restored from your packages.json file.
I did a quick check of the folder size in node_modules in a new dotnet-react project (because that was what I had handy) and this is what I got.
So here we can see that typescript is by far the largest dependency eating up almost 25% of my project and there are still quite a few other large dependencies as well. But this is till just for
If we on other hand look at what is actually delivered to the client that should be a completely different matter. This is what actually matters since this will directly impact the performance of your application. A large app here will be both more code to download and more code to parse for the client.
This same app looks like this when running the project for development and checking network traffic in Chrome Inspector.
So here we can see three script files, but even in development mode only about 520kb is sent to the client even though my node_modules was about 180mb.
If we then go one step further and build this for production we get an even better result.
Now we are down to just about 270kb for the scripts which is just a fraction of the size of the project folder.
So to summarize:
The size is very well possible and kinda expected when working with a modern client side framework such as React (or Angular, Vue, Ember, etc).
The development folder will be large due to all the dependencies needed to build your project.
The final output will be way smaller but in the end depends on what dependencies you decide to use in your own code.
You don't have to do anything to shrink, just make sure that you don't commit node_modules to your SCM.
Also remember that all modern frameworks comes with an overhead to set everything up and making it easy to work with. This is most of the 260kb that my test app is. So if you make a simple counter the overhead will be extreme in comparison and not all projects need a framework such as React.

Android and Web App sharing Kotlin code

One of the major “selling” points of Kotlin appears to be its ability to compile both to JVM or Android and to JavaScript for the web. To make use of this, it should be possible to have a code base where some files are shared between an Android App and a browser Web App.
However, so far I found little details on how such a thing would be set up, in particularly when working with Android Studio and its underlying Gradle setup, starting from a a run of the Android Studio New Project Wizard. I don't mind if I can only build the Web App on the command line, but I'd like to maintain the Android debugging hookups that Android Studio provides. So far I know very little about Gradle and typical idioms for its use.
I'm sure that I'm not the first person to have this idea, so I'd like to know some best practices on how to set this up. Questions that come to my mind include the following:
Do I mix the kotlin2js and the kotlin-android plugin in a single build file, or do I need to have multiple build files (perhaps I should say “modules” or “projects” except I don't know which)?
If I have multiple build files, should that be two (one Android one Web) or three (one more for shared things)?
If it is two build files, how do I reference the shared sources?
If it is three build files, which plugin(s) do I use for the shared one?
Do I need to split my sources over three different source trees? Are there any conventions how these should be called?
Do I need to split my classes into three groups of packages, or can code for different targets coexist in the same package?
What configuration settings do I need to tweak to make the IDE aware of the layout of my project?
I've read the following relevant documentation, among other:
https://kotlinlang.org/docs/reference/using-gradle.html
https://docs.gradle.org/current/userguide/intro_multi_project_builds.html
https://docs.gradle.org/current/userguide/composite_builds.html
https://kotlinlang.org/docs/tutorials/kotlin-android.html
I would recommend using IDEA wizard to create a simple multiplatfrom project for you (File -> New -> Project -> Kotlin -> Kotlin (Multiplatform - experimental) ). Community edition should suffice.
Answering your questions:
You don't mix plugins. You create a separate module for your common code and use 'kotlin-platform-common' plugin for it.
Three modules, special plugin 'kotlin-platform-common'
Use common sense for source splitting. Put whatever you want/able to reuse in the common code. Put platform-specific code in platform modules.
No package restrictions. You can put everything in the same package if you so desire =)
Pretty sure it should just work. If not, try re-importing.

Build system for JS applications - worth the effort?

In order to build static web pages to serve interactive news applications (mostly data visualizations scripted with something like D3 or lightweight apps built with Bootstrap.js), is it worth the effort to install and configure a build system like Middleman or Grunt.js?
The reason why I am asking is because I am not familiar with Ruby and Ruby Gems at all, and do not have the time and willingness at the moment to dwelve deeper into it, as I already know Python & Javascript pretty well.
Do I need to know Ruby in order to use Middleman productively? Or should I just use Grunt? I am asking because I want to reuse the same templates over and over again and heard that this is easy with Middleman.
There is a distinct difference between Middleman and Grunt.
Grunt is a generic task runner while Middleman is a static site generator.
Middleman for example would be used to create a site with multiple URLs. You put some files in a folder and Middleman takes care of arranging them, creating subfolders for URLs, rendering layouts, compressing assets and in the end you have a bunch of files that represent the site. All this is built in.
You don’t necessarily need to know a lot of Ruby to get started with Middleman, but to get the most out of it, understand how it works and change configurations to your needs, basic Ruby knowledge is key.
Grunt on the other hand works by using plugins and telling them exactly what to do. By default it does nothing. You could think of Grunt as "framework", ready for you to add tasks. Compress these two css files. Combine these JS files and move theme over here. Things like that.
For building a complete website I recommend Middleman. In order to be able to use the templates you create in another language like JS, you could use Jade as a templating language. By default Middleman uses ERB (part of the Ruby standard library). Another popular choice is HAML, but I’m not sure if there is a decent JS compiler for it.
If you want to have really fine grained control over the output of your JS files (you’re talking about JS client side apps in your question) you can even use Grunt and Middleman together. Grunt would take care of the assets (you can have really detailed configurations there) and Middleman would handle templating, URL generation and all the other "default website related" stuff.
If you're keen to use Grunt as a base for this sort of build, you may like to look at Assemble.io.
This is a static-site generator like Middleman, but one that is completely (currently) dependant upon Grunt tasks in order to do its thing.
I believe the learning curve for Assemble.io is rather higher than Middleman. It is based on Node, rather than Ruby. However I don't believe it's necessary to know Ruby in order to get a lot from Middleman.
You may have a look to http://wintersmith.io/ a static page generator like Jekill or MiddleMan (I don't really know this one)
With Grunt you have something at a lower level: Grunt provides you tasks to automate things so you'll have to find or write the task that fits your needs.

How do I configure paths to my javascript files in the Jasmine / Maven autogenerated ManualSpecRunner.html?

I think the question says most of it. I have an autogenerated ManualSpecRunner.html file as created by maven / jasmine plug-in and I've got it to put itself into the deployable .war by using:
<jasmineTargetDir>${basedir}/pathForMyWebapp</jasmineTargetDir>
However, all the links to js files within the ManualSpecRunner.html are hard coded file:/// references - this is a bit mental, I want them to just be the relative paths to the files that are also in the webapp i.e.
Currently it gives me this path:
file:///home/username/code/HEAD/pathForMyWebapp/js/yui.js
whereas I need it to have the far more simple
/pathForMyWebapp/js/yui.js
I have tried changing two other variables in the maven script, but neither seems to have the desired effect, neither of these configuration options do what I need, the second having seemingly no effect:
<jsSrcDir>/pathForMyWebapp</jsSrcDir>
nor
<jsTestSrcDir>/pathForMyWebapp</jsTestSrcDir>
I've looked through the documentation but think I must be missing something (also, more notes on various config params listed in https://github.com/searls/jasmine-maven-plugin/blob/master/src/main/java/com/github/searls/jasmine/AbstractJasmineMojo.java are meant to do would be helpful so I can work out if I'm doing it wrong or if it's not possible!)
Any suggestions?
[p.s. I've changed some of the path names as they've got sensitive info in them, so please ignore their oddness!]
I think I understand the source of your confusion. It looks like you're trying to direct the target of the jasmine-maven-plugin to a directory inside your project's packaged *.war file so that you can run your specs against the code after it's deployed to a server, is that correct?
Unfortunately, the plugin wasn't designed with that use in mind. The jasmineTargetDir directory is usually left at its default value of target/jasmine and wasn't intended to be bundled with your application (it's analogous to the target/surefire-reports generated by maven-surefire-plugin for Java unit tests). So the reason that the script tags in ManualSpecRunner.html point to invalid locations is because that file is generated in order to be run from the local filesystem in a browser from the workstation that's building the project (to facilitate TDD).
All of that to say, if I'm reading your intention right, I think it'd be a cool feature to build a third spec runner that could be deployed with the app and executed remotely. (Especially if the project's Jasmine specs are functional/integration as opposed to isolated unit tests.) Unfortunately that's not something the project does yet.
I'm afraid that for now, if you needed to bundle the jasmine tests and execute them on the deployed server, you would need to copy ManualSpecRunner.html and jasmine into your src/main/webapp, fix the script tag references, and then manually maintain it as files are added and removed.
Make sense?

Categories

Resources