NestJS: Drawbacks of dynamic modules? - javascript

Background
NestJS comes with a feature called dynamic modules which gives the caller (=importer) of a module the chance to configure a module and thereby its providers.
Using dynamic module features, we can make our configuration module dynamic so that the consuming module can use an API to control how the configuration module is customized at the time it is imported.
(https://docs.nestjs.com/fundamentals/dynamic-modules)
Question
Does this flexibility come at any cost, meaning, are there any negative effects involved with this "dynamic modules" in the sense that it negatively impacts performance or the compilation result? Or is the only drawback of dynamic modules the little bit of extra code that is required to create them, in contrast to non-dynamic (=static) modules?

The only drawbacks that I have found with Dynamic Modules is that they can sometimes be a headache to debug if things go sideways during development. Otherwise, I haven't noticed anything changing in compilation or runtime.
I will say I am having a bit of a problem with configuring a dynamic module once and importing the then configured module without using a middle-man module to manage it, but otherwise they work great.
Edit 10/18/19
Wanted to come back and say that the issue I've been facing has been solved. It's a bit of an interesting solution, but I think overall it's a pretty cool one to see. Here is a high level context of it, hopefully there will be a blog post about it in the near future.

Related

JavaScript Code-Splitting with hiding the code-endpoints

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).

What Does Eject do in Create React App?

I think it has something to do with using webpack directly and therefore gives more flexibility. But I'm not completely sure if someone can explain what "ejecting" means. Also what are the ramifications of ejecting a create react app? Is it bad to do this, or?
To bootstrap a react project it will require for you to know about things like Webpack or Babel which might be a sticking point for people who do not want to learn about these.
create-react-app provides a fully configured environment with reasonable defaults (and possible to extend). Most infrastructure-related work is hidden from you, and whenever there are changes in one of the dependent packages this is taken care of for you -- it will only be required to update react-scripts.
I highly recommend this presentation by one of CRA authors it will give you a better idea of the project.
Now eject means that all of the configuration will be exposed to you. You will see every package which runs your project. Now you are responsible for maintaining all of that configuration.
This is not necessarily a bad thing; you are then left with more code to maintain, but you get full control in return.

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.

How to organize build, server, client and shared JavaScript code with NodeJS

One big benefit I've always perceived with using NodeJS on the server is the potential for sharing bits of code between the server and client side (ex. input validation). Now that I'm actually developing using NodeJS one difficulty that I've found is determining the responsibility and context in which each body of code is executed. Below I'll list a few of the difficulties I've had in hopes gain some enlightenment on conventions or guidance that I may be overlooking that could help elevate these issues.
Build-Time Code
Build time code for projects that use Gulp, Grunt, or vanilla NPM in a way that follow the basic documentation are generally pretty easy to follow. Most smaller projects tend to keep all of the code within a single file and the file tends to be named a conventional name like gulpfile.js, however with bigger projects I've seen these scripts begin to be split out. I've seen some cases where the gulp file is split into multiple files and placed under a separate directory. Even worse I've found cases where the gulpfile.js file isn't even named as such causing new developers to hunt around to find where the gulpfile is located and once it is located the gulp command always has to be run with the specific --gulpfile option.
Run-Time Server-Side Code
The entry point for basic node applications appear to simply require pointing out a specific JavaScript file when running the node command (ex. node script.js). For web server applications, such as those using Express, I've noticed that by convention the entry point file is often called server.js and can usually be found in the root directory of the application. In some other cases however such as when running the web server in a developer environment I've seen gulp tasks take on the responsibility of launching Node. In these cases there seems to be multiple ways to include the entry point but one example I've found is just starting up the webpack complier followed by a require statement for the entry point script. Figuring out how to incorporate normal guidance on how to accomplish a typical node debug command is non-trivial in this type of setup. Besides the entry point of the application, there doesn't seem to be any general guidance on directory structure for NodeJS/Express applications that keeps server-side specific code in it's place to help locate it and to keep it separate from build-time and client-side code.
The server-side story becomes even more complex in cases where the server side code is used both for the purpose for serving up static content, server-side generated views (such as with MVC), as well as for providing an API to the client side. My preference is to separate API from the application project but I get the feeling from others that there is a sense of overcomplexity involved in doing so where I see it as a reasonable separation of concerns.
Run-Time Client-Side Code
Since client-side code can often have various entry points based on the first page that is requested this can be tricky. However because of the general transparency of URLs with how they map to resources for typical cases it as well as how powerful the debugging tools have become in modern browsers, it isn't too much trouble following the follow of the scripts. The difficult instead for the client side code comes more for typical build processes which generally end up copying the files around and placing them into a production like structure under a different name. An example would be a project that has a folder called src or js that holds client-side and server-side code intermingled except for that only a portion of the files happen to be included in a build task which transforms and often concatenates the files and places them in a distribution folder. Common names of these distribution folders that I've seen are dist, public, www, and wwwroot. Often if not always these directories are at the root of the project which at least makes it a bit easier to locate without having to interrogate the build scripts.
My hope is that there is some general guidance on how to put all of this together in a sane way perhaps by an authoritative source mainly to give guidance to those like myself who may want start off on the right foot. As a side effect perhaps being able to reference some sort of standard even if it is a loose one may also reduce the amount of boilerplate a team has to invent and discuss as they get started. Within each of the contexts listed above there will obviously be some technology specific conventions such as those followed for AngularJS, Meteor, or ReactJS on the client-side. The conventions I'm looking for are more specific to separating the main highlevel contexts in end-to-end JavaScript applications where the language and platform no longer become obvious way to differentiate between each.
Build-Time Code
IMHO if you have so much build-time code that it's more than say 1000 lines and requires more than a handful of files, something has gone off the rails. Either you don't know how to make good use of existing packages from npm or you don't understand how to refactor generic code and publish as independent npm packages. If you feel like you need guidance about a project's build-time code because it is so large and complex, my suggestion is to modularize and split out into separate projects - each published independently to npm. Also just check your overall approach. What are you doing that is so custom and requires so much machinery?
Run-Time Server Side Code
Please see my other answer to ExpressJS How to structure an application?
Generally I'd rather see client side code and server side code either completely separate npm packages (separate git repos, separate package.json files, published independently) (if they are large enough) or otherwise co-mingled in the same module and grouped by coupling (all the code relating to a feature kept together including front and back end code), especially if your code base has a substantial amount of code that works in both environments.
I have an open-source full-stack node/JS application called mjournal that keeps browser code and node code alongside each other. You can have a look and see if it feels logical to you and easy to understand where code lives. It is by no means a popular approach, so many folks will dislike it, but it feels good to me personally since I've embraced "group by coupling" as a general principle.
Figuring out how to incorporate normal guidance on how to accomplish a typical node debug command is non-trivial in this type of setup
Yeah, that's nonsense. Your app should start with npm start or something like node server.js. Elaborate gulp/grunt setups that confuse new developers are unnecessary complexity you should just eliminate.
The server-side story becomes even more complex in cases where the server side code is used both for the purpose for serving up static content
In my experience, the code to serve up static content boils down to 5 lines or less, so no big deal. If you have a non-microscopic amount of code dealing with serving static content, again something has gone way off the rails.
Run-Time Client Side Code
My hope is that there is that there is some general guidance on how to put all of this together in a sane way perhaps by an authoritative source mainly to give guidance to those like myself who may want start off on the right foot.
There are some people in the node community that have adopted the "convention over configuration" approach in use by Ruby on Rails, EmberJS, and some other large projects. If you like that approach, check out tools that use it like SailsJS, EmberJS, Yeoman generators, etc.
But in general, looking for a "standard" is not how the node.js/javascript/web community rolls. Small npm packages. File layouts that are forced into obviousness due to smallness. I feel your frustration here as front-end toolchains are so complex, but ultimately it's because JavaScript in the browser took too many decades to create a reasonable module system. Things may start to standardize in the next few years now that ES6 modules are an official spec, but with so much code already written in CommonJS and it's terrible precursors like RequireJS/AMD, we'll be dealing with them probably for the foreseeable future.

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

Categories

Resources