JavaScript Code-Splitting with hiding the code-endpoints - javascript

hey im not really familar with JavaScript or react.
So i hope i dont a too easy question:
i want to have a "one-page"-website, and want to change this page dynamically with ajax-request.
I have coded for example code for four visibility-levels (guest-user, normal user, moderator, administrator)
if you log in into my page and you are an admin, you get the JS-Code from all levels. For example in the json-response there is a list with URLs to the Javascriptcode destination.
If you log in as a normal user you should get only the normal-user js-code. The guest-user-js-code you already have; you got that at the time you entered the page.
So i guess the thing is clear, what i want.
But how i should implement this?
Are there some ready solutions out there?
https://reactjs.org/docs/code-splitting.html
maybe i have to adjust this here?
and maybe there are some good bundlers out there, that i can use, doing that splitting with hiding the endpoint urls (which i get if i have the rights from an ajax-request)?
lg knotenpunkt

As I said in the comments, I think that the question is very, very broad. Each one of the requests is a full standalone argument.
Generally speaking, I hope that this will led you to the right way.
You can split your code by using CommonJS or ES6 modules (read more here). That is to keep it "modular". Then, during the bundling process, other splitting techniques may be applied, but this will depend on your development environment and used tools.
Your best option for bundling would be Webpack without any doubt. However, directly dealing with Webpack or setting up a custom development environment is not an easy task. You'll certainly want to read about Create React App, which is a good place to start for a Single Page Application. It will allow you to write your code in a "modular" fashion and will bundle, split and process it automatically (uses Webpack under the hood).
Finally securing access must be done server-side (there is another world of available options there).

Related

Migrating Javascript from the database

I am working on an old enterprise solution with these properties:
The solution has a MVC web application
The solution has a WCF service layer
The solution has javascript in the database, in the form of functions in a database column
The web application retrieves said javascript through the service layer and plugs it into certain pages
My team cannot modify the web application, nor the service layer
My team must write javascript by inserting functions into said database columns
This architecture leads to:
A very inefficient development loop
Very poor source control
I'd like to propose a solution for them, how to upgrade this, but here's where I fall a bit short on experience. My suggestion would be:
Migrate the javascript from the database to javascript files
Make some sort of hook in the web application for other teams' javascript files
My questions are:
Has anyone had this kind of problem and how did they solve it?
Is there an effective way to do this kind of javascript migration into files? My idea would be to write a small console program to do the migration
How would they make a hook to import our javascript files? My idea is to make a script bundle with some naming convention, so we can add scripts without them needing to change their code. Are there problems with this approach?
Any kind of input would be invaluable.
Edit:
Additional explanation:
The mechanism maps the javascript function names to a certain DOM elements' event attributes and inlines the code right after the element
The functions are standalone functions, depending only on libraries already in the web application
The functions are grouped by a common form
So I suppose it would be better to group them into files bearing the form names.
If these are just simple, static function definitions being inlined into the web page, then I suppose it might be possible to serialize/aggregate them all into a giant file and run something like prettier on it to make it readable.
That wouldn't be ideal to gain traction in your proposed migration, though. If the code has any volume to it at all, it would be nice to give some structure and order to maintain it.
It's already kind of a huge assumption that this javascript is just pure functions without any complex dependencies on each other, but it's possible that these pieces of Javascript work in isolation already if they are being pulled out of a database. It's hard to know without knowing more context. It seems unlikely that your life will be that easy.
If you managed to extract this monolithic Javascript file, the easiest thing to do would be include it in a script tag for the entire site and be done with it. This could be a bad idea if the file is getting to the ~MB size and slows your initial page load time.
Then again, the point at which you have a bunch of functions in one file, you could probably do a lot there to optimize and reduce duplication of code.
This is still all conjecture because I don't know the mechanism by which your web application imports the javascript once it retrieves it from the database.

Webpack HMR vs Skewer mode in emacs

I have recently started looking into webpack, because of cool features that enable writing true CSS modules, and smart bundling and stuff, and there is HMR, thats why I am here. I have seen examples of React Redux projects that made it possible to update javascript code without reloading browser. WOW, I thought it is impossible.
I wanted to know more, especially how it works under the hood, to make it work with my current project which is Vanilla JS.
In the mean time, my interest in functional programming languages brought me to Emacs. I have found out that there is a skewer-mode available in emacs editor that do update javascript and HTML! in real-time without realoding browser.
I know that they both use local server to push the changes to the browser and some script on client that somehow updates the code. But how do they preserve the state of application. In terms of React projects its kind of imaginable, because of component based nature of apps, you can just replace component with new one, but I am not sure how do they search for variables and reassign new values to them. Maybe they do use some eval magic. But I am not sure.
So how do they exactly work? Maybe I am looking from the wrong angle, I just don't have a clear picture.
Emacs has live update of HTML too, can webpack HMR do that?
(I don't care much about HTML because I do it in JS. But I think it can explain difference between these two.)
Which is better in doing so?
What is the pros and cons of each or are they just different parts of the world and can be integrated to become something even better?
Maybe there is a even better options without the need of middleware like local webserver, but just editor plugin communicating with some browser extension?
P.S.: I don't mind learning tools that can optimize my work, because it always pays off.
So how do they exactly work?
From the Webpack HMR documentation,
In general the module developer writes handlers that are called when a dependency of this module is updated. He can also write a handler that are called when this module is updated.
Each module type needs update logic written for it.
From the skewer-mode repository,
Expressions are sent on-the-fly from an editing buffer to be evaluated in the browser, just like Emacs does with an inferior Lisp process in Lisp modes.
Your code is sent to the browser as a string, and runs through a global eval.
Which is better in doing so? What is the pros and cons of each?
If you use libraries that have HMR plugins written for them, it might be worth using this feature. Libraries without HMR hooks will not benefit from it. Webpack's HMR seems extremely complex, and its documentation and its plugins warn about HMR's "experimental" state. Therefore, it is probably not reliable, and thus could be counter-productive to your development. For instance, the reloading modules need to correctly clean up the non-reloading ones. What if some script adds listeners to window or document and doesn't provide a way to remove them?
If you want your text editor to serve as an additional REPL for your browser, then you can use skewer-mode. To effect any change in your application, some part of it must be exposed via a global variable. Maybe you export one global object with a bunch of submodules attached to it, e.g. window.APP = {}, APP.Dialog, APP.Form... or, maybe you just release hundreds of implicit global variables and functions into your environment. You can see changes in your application by evaluating the definitions of these modules / functions / variables, and then evaluating some code that uses them, e.g. by calling a function APP.initialize() which bootstraps your app, or by triggering a redraw in a view library you use (usually by performing a user action like clicking an element).
If your application is not written such that it can be modified in a browser console (e.g. if you use a module compiler like Browserify or Webpack, which wraps your code in one big closure), then you won't be able to do much with skewer-mode. Also, consider whether it would be faster to manually eval code snippets / files and re-run initialization code (and potentially create impossible application state that you will waste time debugging), or to just refresh the page and recreate your previous state.
The benefit you gain from either of these tools is heavily reliant on the way your application is structured. I can see them creating pleasant development workflows under exactly the right conditions (what I describe above). Otherwise, they seem too likely to cause harm to be worthwhile.

Aurelia: Isomorphic?

As far as I know, Aurelia does not support server-side rendering as mentioned here.
But the question is: is it possible to do this with some hacks/workarounds?
The most obvious idea would be to use Phantom, Nightmare.js or whatever to simply render that page in Chrome on server and serve that to client, but this is very likely to cause big productivity issues.
Thanks!
UPD
According to Rob Eisenberg's response on FDConf today (16 Apr 2016), server-side rendering will be implemented in 2016, there's one core team member working on that and there's a deadline for this feature.
There is an open issue for Universal/Isomorphic Aurelia which you can monitor. In particular EisenbergEffect (who is Rob Eisenberg, the creator of Aurelia) states that they are gradually working towards providing Universal support for Aurelia. This post from him provides most of the detail:
EisenbergEffect commented on Aug 25
We are trying to lock things down within the next month. That doesn't
mean we won't add anything after that, but we need to work towards
stabilization, performance and solid documentation without
distractions of lots of new features for a little bit.
Primarily, "isomorphism" isn't a use case we want to tackle for the
initial v1 release. Again, that doesn't mean we won't do it later.
But, we want to have a solid framework for browser-based apps as well
as phone gap and electron/nwjs desktop apps first. That was our
original goal and we want to make sure we handle those scenarios
better than any other framework or library.
After that, we've got some other features we want to do, which are
valuable in their own right, but will also take us closer to
isomorphism.
Enable all aurelia libraries to run on the server. This enables some
new testing scenarios, so it's valuable if only from that perspective.
Once code can run on the server, we can then implement server view
compilation. This isn't isomorphic rendering, but rather the ability
to run Aurelia's view compiler as part of your build and bundle
process. This enables more work to be done ahead of time, as part of
your build, and then it doesn't need to be done in the browser at
runtime. So, this will improve the startup time for all apps and
reduce initial render times for all components. It also will make it
possible to store compiled views in browser local cache to improve
performance of successive runs of the application.
After both of those
things are in place, then we can look at doing a full server render
for each route. This isn't quite isomorphic in the truest sense, but
it solves the SEO problem without needing 3rd party libraries. So,
it's nice to have a solution there.
Finally, we can then "sync" a
server pre-rendered app with a stateful Aurelia app running in
browser, giving us 100% isomorphic support. So, those are the stages.
The first two would be beneficial to all developers, even those who
are not interested in isomorphic apps. The 3rd stage can be done today
with 3rd party libraries, so this is a nice to have for us, for those
who don't want an extra dependency. All of that leads into 4 which
adds the final pieces.
We have already begun some of the work on 1. That might get into our
first release. We aren't going to push it, but it's already in
progress and we're looking for the problem areas so we can make it
work. Steps 2-4 involve significant work. Really, we are talking about
a collection of features here, each one being rather complex. So,
those will probably come in stages after v1, as point releases.
We really don't want to do what Angular 2 has done. They have
massively complicated their architecture...to the point that very few
people will be able to understand it and developing applications with
it has become much more complicated, with many nuances. We really
don't want that, so we're focusing on the developer experience we want
first, then we'll come back and see about isomorphic support (yes, we
already have ideas how to do this cleanly, but want to give those
ideas some time to mature). In all of this, our goal is to be modular.
So, if you don't care about isomorphism, you don't have to think or
worry about it. If you do, you would install the necessary packages,
agree to the "constraints" of the system and be on your way.
So, to all who are interested in this topic, I would just ask you
kindly to be patient. For those who aren't interested in isomorphism,
don't worry, we aren't going to brake the developer experience on you.
For those of you who want it badly, you will have to wait longer and
it will come in stages and in modular pieces so as not to disrupt
others.
Just for now
The only way I can propose: render pages with phantomjs + use redis to speedup that process.
But you will have lots of trouble restoring the state at client side.
.......
Dirty solution
Load rendered page from server and at the client side render new one in the usual way, than switch UI's.
It won't be a truly isomorphic, but something like https://github.com/rails/turbolinks on first page load.
.....
I hope soon Aurelia team will provide simpler stuff for that case.
In the current Aurelia there is the possibility to enhance existing html.
The document says
So far you've seen Aurelia replacing a portion of the DOM with a root component. However, that's not the only way to render with Aurelia. Aurelia can also progressively enhance existing HTML.
Check out enhancement section # http://aurelia.io/docs.html#/aurelia/framework/1.0.0-beta.1.0.8/doc/article/app-configuration-and-startup
I'm looking forward to get a better documentation of this feature.
It seems to me like rendering the html on the Server and inject aurelia will work with it and google will like it as well.
a hack i just came up with is to put a static copy of the initial rendering into the index.html file:
<html>
<body aurelia-app="main">
<h1>static copy of the website here</h1>
<script src="scripts/vendor-bundle.js" data-main="aurelia-bootstrapper"></script>
</body>
</html>
this is of course completely manual and if the initial rendering contains any content from a database then the static copy may need to be updated
every time the database content changes. (which is of course what isomorphic rendering is supposed to solve)
however for my needs, which is a simple website with some information that is rarely updated, this solution is good enough. it will at least suffice until i am able to implement proper isomorphic rendering.

AngularJS - Grunt: Does a solution exist to build a running application with only desired modules

I'm currenlty doing the refactoring of an application and I want to follow the John Papa's guidelines as I found them very interesting and usefull in my case: John Papa Guidelines - Application Structure
So I arrive at the part where I decided to split my application into different modules corresponding to the features. Let's say one module for the accounts feature, one for the transfer feature and one for the user settings feature.
I can do it well according to the John Papa recommendations: one app module and three other modules (account-module.js, transfer-module.js and user-settings-module.js) and their corresponding navigation (states-config.js, etc.).
I hope I have been enough clear because now the tricky part comes :D
The idea I have is that I would like to build two (or more) different applications depending on what I want. I would like for example to build an application without the transfer module and doing this during my grunt process (by configuration).
Currently I am using the include_source grunt and grunt_war later on but there is no way to be more in an "angular module" context rather than using regular expression to specify which files I would like.
Those tasks don't allow us to say like "Okay, I would like to package this, this, and this module" for example (that would be fantastic!)
I think that big applications should have encountered this problematic as when they don't provide all business modules to every customer but make it configurable (at least I hope that's how they do).
The question is how? Do they do it? Is it manually (non sense), or do they have written some custom grunt (gulp) task or some custom scripts for this purpose?
Bonus question: Let's imagine we are living in a dream world and a grunt task exist for this. My next question will be, how to manage it within my application to configure my navigation for example (no more transfer button in the menu). I think that if the grunt task and the app use the same configuration file, that won't be a problem and I will be able to use grunt-angular-settings task to have a constant within my app.
Thanks for your attention and I'm very curious to read you :)
Regards, Yassine GAYL
interesting. take a look at how angular.js itself builds the artifacts. in src code, it has bunch of modules scattered in different folders. it introduces lib/grunt/utils and lib/grunt/plugins to handle the build process, say which modules should go into which destination file. you might have interests to try the same, good luck with it.
https://github.com/angular/angular.js/blob/master/Gruntfile.js#L166

What is the suggested way to use template in Chrome content scripts?

I use several templates in a Chrome content script for elements I'm adding to matched pages.
Currently I'm storing these templates as string in the script, but I wonder if there are better ways to do this.
tl;dr answer - Yes, you can store them in a <script type="text/html"> tags or load them dynamically through ajax. Examples here (from KnockoutJS) and here. Store them in a file with the proper extension and use an empty tag with an id X, then $("#X").load("/path/to/template", function() { renderX(); })
Long answer with insightful thoughts, keep reading...
Please make sure templates/views or related GUI components of your system are in separate files (Keep reading to know why)
As a front end engineer, I learned to keep layers as separate as possible; this helps your team to understand better your code and make it more maintainable. Separating your layers in modules and then assembling them through an "assembly" mechanism is probably one of the best practices in software engineering. Some of the benefits of this practice include:
Maintainability: Multiple developers can browse and edit single parts of your code in order to create a more robust piece of software.
Readability: With the amount of languages around, you can't expect everyone to understand all the syntax of these X or Y language; mixing languages in a single file is just one step to confusing your code reviewer and make him spend more time than needed.
Accessibility: Take for instance, html, jade, haml, smarty, twig, erb or other template files. Those files should always be named with the proper extension in order to help code editors and IDE's to syntax highlight. A developer should only need to glance a folder to know what those files are supposed to do. A script or bot can come up with important information from just an extension.
By keeping views in separate files, other coders can view them and understand an important layer of the system without needing to understand the entire application; even collaboration gets easier when the developer just need to review those specifics files. Through bashing or scripting, even large architectural systems with thousand of "views" like files can be filtered in order to output just what needs to be reviewed.
(By now I hope I convinced you into removing your string from your code and create a new file and it there, otherwise I really need to improve my writing skills)
So, after we have moved our template to an external file, what do we do next?
A word on Javascript and Chrome-Extensions
Javascript doesn't have a default templating feature (heck, it doesn't even have a modular one, although some smart people are working on it for the ECMAScript Ed. 6, yay!), which means that we need to use a templating library for that. Let's assume you are using Mustache, Underscore template of something alike and thus using its library to render it.
Most of those templating engines use the infamous eval, which can provide a vulnerability to your code, which Chrome Extensions dislike, a lot. The Chrome Extension Dev Team even enforced a new version of the manifest.json file in order to forbid eval, and gave developers the choice to use Sandboxing Pages in order to do so. Luckily for us, they decided to relax the policies a little bit and we can continue use it with a proper CSP definition in our manifest.json.
This means that we need to tackle two problems instead of only one: the "load the template" one and the "render the template in a way won't freak out the new incoming versions of CSP in case the Chrome Extension Dev team change their mind".
Load the template
Load the template, luckily, can be done through an XML HTTP Request through AJAX. Just point the url with the name of the file and you can receive the template as a string, which was probably your original set up. Here's an example that I do with KnokcoutJS:
$("#aiesecTemplate").load('js/libs/aiesec/aiesecTemplate.html', function() {
ko.applyBindings(AIESECViewModel);
});
The #aiesecTemplate is a <script type="text/html"> tag that the browser won't render as part of the DOM. You can use that with other template mechanisms in order to actually assemble your DOM. If you have already a solution for this, this is probably the end of the answer and you can move on with your life. If you are wondering how do we render the code from there, keep reading.
Render the template
The Chrome Dev team suggest us to Sandbox our rendering process due most templating engine libraries being non-CSP compliant (AngularJS being an exception). Here'an excerpt of the code from the Sandbox page.
iframe.contentWindow.postMessage(message, '*');
Where iframe is a specific DOM Iframe Element from the sandbox page with a src attribute of a page that has the templating engine; message has the string template previously loaded, so after posting the message a window.addEventListener for message inside the iframe can render it without a problem. More information about sandboxing eval can be read here
Conclusion
If you made it to here, awesome! My answers might not be that boring. As a last note, you might be thinking "What about AMD or RequireJS?"; to be honest I haven't tried them, but really smart people think that AMD is not the best approach. Loading through a XML HTTP Request might not be better, but in case you think it hits your performance (I have used it in my application and it doesn't) you can always use some Event Pages and Web Workers with that.

Categories

Resources