Server-side rendering of CSS modules - reactjs

I am going to import styles with CSS Module and make it work with server-side rendering. I tried the following methods but each one has its own caveat. What is the best possible way to require('.style.scss') if any side effects?
Using the css-modules-require-hook:
Advantage: Easy to configure. You just need to call the hook at the beginning of server code. You don't need to modify components.
Caveat: It modifies the require.extensions global object, which is deprecated.
Using the isomorphic-style-loader:
Advantage: No more hooks to require.extensions.
Caveat: Wrapping components with HOCs that uses the React Context, which is an experimental API and likely to break in future releases of React.
Using the webpack-isomorphic-tools:
Advantage: No dependency on require.extensions or Context (AFAIK).
Caveat: Wrapping server inside webpack-isomorphic-tools instance. And can we please get rid of webpack-assets.json?
Bundling server with Webpack:
Advantage: No more hooks or injections.
Caveat: In development, it is very cumbersome to bundle everything whenever the code changes and even makes it harder to debug in a large bundled .js file. Not sure - you may need to pass a bundled .js to test runner.
Disclaimer:
The advantages and caveats below are just my two cents, and actually I love all the libraries, plugins and approaches they took to solve the problem and really appreciate their efforts.
I am not a native English speaker, please correct me if I misrepresent myself.

In the end, I decided to hook the require.extensions in development. Probably it is not the best way, showing warning messages on console, like checksum mismatch, but in development mode, I can ignore it.

Related

What are the pros and cons of using an HTML parsing package like html-react-parser vs dangerouslySetInnerHtml in React

We have a database containing HTML code and we are displaying that on a web page using React, but it needs to be parsed.
I initially used html-react-parser but after a code review was asked to use dangerouslySetInnerHtml instead because it doesn't have any dependencies.
I wasn't able to articulate any advantages of using html-react-parser other than it doesn't use dangerouslySetInnerHtml, but is that an advantage and if so why? Does it somehow avoid the dangers or are they just hidden?
Many thanks,
Katie
I've recently been studying this issue for a Headless CMS project I'm working on. From what I understand:
dangerouslySetInnerHtml creates DOM elements outside of ReactDOM.Render() method, so it's not dynamically maintained by the React library. This basically defeats the purpose of using React in the first place (displaying and maintaining virtual DOM).
More concerning, though, is that it's vulnerable to Cross-Site Scripting (XSS) attacks, which is where it gets its name. These are a very common form of attack on the web. You can read about that here: https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml
If you want the app to be less prone to attacks, you'll have to use a sanitization library like DOMPurify for dangerouslySetInnerHtml, so you're likely to have another dependency either way. Once you compile the app for production (npm build) the minimization process makes the codebase extremely compact, and you can do some optimization beforehand with techniques like code-splitting, which makes each section of your page load only if requested, instead of all at once: https://reactjs.org/docs/code-splitting.html
I wouldn't worry too much about a few dependencies, personally - they're a fact of life on the modern web. I've been leaning towards using html-react-parser, but I caveat that by saying I have not investigated whether it reduces XSS vulnerability. However, even if both are vulnerable to XSS attacks, at least html-react-parser introduces the elements through ReactDOM.render() so they don't make the DOM all catty-wompus - that sounds like a recipe for disaster down the road.

Micro-Frontends, Web Components, and Sharing Libraries

so I'm working on migrating my company's app to a micro-frontend approach. We are following the standard described in https://micro-frontends.org/. While under the hood everything is currently using React, we are wrapping things with Web Components so that we will have the freedom and flexibility to be framework-agnostic in the future. We've got a working architecture up and running and so far it is working beautifully. We even created a fancy compatibility layer on top of the Web Component spec which allows us to pass React-like props to the Web Components, including Objects, Arrays, and even Functions. This allows for much better interaction between them.
The main concern we have right now is duplication of libraries. We're a React shop, so even though we have this framework agnostic approach, everything is using React. While this new approach gives us the ability to individually upgrade pieces of our app to a newer React version (finally), we still don't like the idea of so much duplication of the React library.
To put it in perspective, even Gzipped, React/ReactDOM are over 40kb. That's super tiny individually, but scaled up it starts to take up more and more bandwidth. RAM-wise it's less of an issue, about 130kb for those libraries, and given the RAM capacity of most devices now it's not a huge deal.
But, of course, we want things to be as optimized and streamlined as possible. So I'm hoping someone can suggest a way for the micro-frontend apps (the ones wrapped in a Web Component) can get React and other libraries from the parent app.
You should know that the parent app JavaScript is loaded prior to the micro-frontends. Each micro-frontend is loaded via a <script> tag. Lastly, we are NOT using the Shadow DOM at the moment, a tradeoff we made to benefit how we are migrating our existing code into the new micro-frontend architecture.
The core idea is to tell module bundler on how to package your micro-frontends.
Assuming you are using Webpack to bundle your applications, here are the two things that you need to do.
Step 1:
Declare React as an External dependency like in your Webpack config:
externals: {
'react': 'React',
'react-dom': 'ReactDOM'
},
Step 2:
Before you load your parent application's JS, ensure that you are loading React and ReactDOM from CDN or other equivalent place:
<script crossorigin src="https://unpkg.com/react#16/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom#16/umd/react-dom.production.min.js"></script>
Put these script in your main index.html which is responsible for bootstrapping your entire SPA.
Explanation
When you declare certain package/library as external, Webpack does not include it as part of the bundle. It assumes that the outer environment will make that particular version available as a global variable. In case of React, it uses React and ReactDOM as global variables.
By doing this and including it via CDN, you will be left with exactly one copy of React and ReactDOM. When a user visits the application for the First time, it will be slower but once cached, it should not be a problem
Further, you can extend this idea and also declare them as external for your parent app or parent shell container.
Possible solution is to prepare library using Import Map but as it does not support IE11+ I recommend you using SystemJS?
https://github.com/systemjs/systemjs
especially this one seems to be close to your case:
https://github.com/systemjs/systemjs-examples/tree/master/loading-code/react-hello-world
At html you do:
<script type="systemjs-importmap">
{
"imports": {
"react": "https://cdn.jsdelivr.net/npm/react/umd/react.production.min.js",
"react-dom": "https://cdn.jsdelivr.net/npm/react-dom/umd/react-dom.production.min.js"
}
}
</script>
<script src="https://cdn.jsdelivr.net/npm/systemjs/dist/system.min.js"></script>
Then you could import ReactJS, as browser knows where to take it from.
Potentially there is a possibility to build some kind of library that looks into your micro front end's (MFE's) package.json, to get know which library needs to be in use and dynamically create imports object similar to example above.
We need to keep in mind that there is a need to cover versioning check. Mentioned library could potentially store some kind of map which connects dependency with version with place where it's accessible. Imagine that in case mentioned we need to deal with different react version on each MFE :).
Then while loading another MFE library could check if required dependencies has been already included, if some missing, download it, otherwise use what has been already fetched.
Another thing is use webpack 5, with module federation, which I not recommended yet, as it is not stable enough for production, but there is a possibility to start playing with it. Hard part will be covering version check, so most probably need another abstraction layer to deal with it.
https://indepth.dev/webpack-5-module-federation-a-game-changer-in-javascript-architecture/

Does using dependency injection in cucumber-jvm consider bad practise?

I am still very new in Cucumber-jvm/Selenium, so I am very sorry if the question sounds dumb.
Background: I'm an intern in a big company. I'm doing an automated software testing for a product. There is already an existing automated test steps. What we're going to do is to extend the project and add our own steps. The problem is almost all of the steps have kinda same hook methods. I asked a question before on how to avoid to run hook methods and a very good man said to use tags on the hook methods. That's before I found that almost all the hook methods in the previous project are kinda same. This made me think that it's not very fast/optimize because if hook methods are global then every time I run a feature file, it will just do all the hook methods that are same. After days of doing some more coding and research, I found dependency injection using picocontainer and I thought this is a good way of fixing the current issue, but I read some of articles that said dependency injection is consider a bad practice.
My question: Consider what I stated above, does using dependency injection with picocontainer in cucumber-jvm here consider bad practise? If it is, is there more good solution to this?
(Optional Background) I don't think this is important but I'm just going to include it, the hook methods that are almost 95% in every steps:
#Before
public void keepScenario(Scenario scenario){
this.scenario = scenario;
fWait = new FluentWait<WebDriver>(BrowserDriver.getCurrentDriver());
fWait.withTimeout(Duration.ofSeconds(10));
fWait.ignoring(WebDriverException.class);
}
#After
public void screenshotOnFailure(){
if (scenario.getStatus().equals("failed")) {
BrowserDriver.getScreenshot(scenario);
}
}
Dependency injection solves the problem of sharing state between multiple step definition files in a scenario. Injecting steps into other steps might be considered a bad practice, but on a whole DI itself isn't. But none of this appears to be your direct problem.
Your problem appears to be that you have multiple hooks that do the same thing. You can either remove these duplicate hooks or use a very strict way to select which features and glue you'll use (check the CucumberOptions on your runner or commandline arguments). If narrowed down to a single class, it will only use the steps and hooks in that class.
Alternatively you can just remove the duplicate hooks.

What are the disadvantages of using one big React component?

What are the disadvantages of using one big React component?
I have a deep experience using webpack, browserify, AngularJS, ES6, NPM and other similar web framework. I am new to React.
I want to create a single page app in React. I don't want or need testing. I don't need team friends to work on. I only need to make the product development as fast as possible. Make thing works. You can call it MVP. You can call it type lessm, or smart developement. If things work good in the future I can consider refactoring the project. I am the only developer who works on. I don't worry about perfromance issue (if it is just few ms)
The question is: All the articles said to make as much as possible many and small React components. In separate files. You can see the React-Starter-Kit. It is huge.
You can see that every component is a separate file.There is huge webpack.config.js file. Every component import many other things. If I also want Redux, I need to import the store, and make connect on every component.
I want to take different approach. I want to use React & Redux. But using only one component. Every inner element can Dispatch or execute events.
Is there is any problems in the future that I don't think about?
HTML:
<html><head><body></body></html>
JavaScript:
App=React.createClass(function(){
getInitialState:function(){
return {
openMore:'block'
}
},
openMore:function(){
this.setState({openMore:'visible'})
},
render:function(){
return (
<div>
I want to put all the HTML of the app
<span>
In one component that do everything.
<button onClick={this.openMore}>More Info</button>
<span> This way I beleive I will need to type less for development</span>
<b style={{display:this.getState().openMore}}>What are the disadvance of this?</b>
</span>
</div>
)
}
})
ReactDOM.render(App,document.getElementsByTagName('body')[0])
Well disadvantages are many. I will try listing them from what I have faced and observed:-
React was built on the concept to break page into components, so yeah the more you break the page into small components the more it is easier to use.
Its generally easy to track the code.
Its scalable
One component does not break other components.
Re-rendering is there only for specified components if they are isolated. If you have everything in a single component, the rendering would make your entire component load again, reducing efficiency.
Harder to test
Difficult to use with redux while passing actions and then connecting to store.
Your component should do only one job.
Cannot break the components into presentational and container components thus not utilising redux to full potential.
Not being able to use code spilt feature of webpack which increase speed of page due to partial code loading.
These are few things I personally faced. Next,coming to webpack configuration. I hardly have configured webpack file more than 100 lines and trust me those 100 lines make your life really easier. In fact basic configuration is just 10-15 lines which can generate your bundle.
Now,coming to problems in future, yes following would be problems:-
Difficult to scale up.
Difficult to test
Not utilising libraries to their potential
Difficult to manage component due to monolith behavior.
Hope it helps!!!
Having a single large file is fine. React was built on the maxims "No abstraction is better than the wrong abstraction" and having an API with a low surface area.
If you're not sure what problems your application is solving, then wait until you feel the pain of not having an abstractions before you create one.
If your application is likely to be in flux as its feature set isn't nailed down, then don't give yourself busy work by moving things around in different files.
If you don't have a website that is designed with reusable components that are intuitively separable, than don't separate it out into different components.
It is fine to use React just as a means of having a declarative syntax for what your html should look like in different states.
Having large components is bad due that you cannot simplify your code. Splitting your modules into smaller ones, will make it easier for you to maintain the code at a longer term, as well as finding out an error faster. Stack Trace is easier as well as it is more composeable, when having an implicit component.
FWIW, you can do a lot more separating your component into smaller ones, such as filtered props and an own state. The bad thing though, is that you can loose track of how the application is built up when you are looking at the build others have made.

pitfalls of IIFEs with AngularJS

I have an application made with angularJS, whole application is composed of IIFEs(Immediately Invoked Function Expression). Every module, directive, controller is itself an IIFE and they are around 100s.
I want to know what is the performance pitfall when an app has so many IIFEs.
It is OK to use IIFEs with AngularJS?
How good is using libs like browserify and requirejs with AngularJS for managing the dependencies?
Can you please throw some light on this?
The question you need to ask first is whether you've got some internal parts within the IIFE that you don't want to expose to the global scope.
The whole point of creating a closure in this manner is to mimic encapsulation and avoid polluting the global scope.
The performance pitfall is not so easy to measure; I think the performance issue is negligible when you create the IIFE (don't forget you're just creating a function). One performance issue that I might think of is that when you reference a function variable form an inner function, you need to travel through the scope chain and get it from the closure object.
I would recommend you to look at patterns like module pattern, revealing module pattern etc. I personally use the revealing module pattern.
Browserify and requireJS are two libraries that implement two different specs; the commonJS and AMD respectively. These two specifications try to accommodate a functionality that is not supported by ES3 or ES5; That is a way of defining module and then loading them in specified locations.
If you want to define modules and load them synchronously in a similar manner to hose nodeJS works, you can use Browserify. In addition, Browserify allows you to use the same modules both for client-side and server-side (as long as you're using nodeJS).
On the other hand if you want to asynchronously load your modules you can go with AMD and requireJS, but you won't be able to reuse them on the back-end.
Finally, bare in mind that everything you've mentioned is not directly connected to angularJS; those are some good JavaScript practises to overcome some issues of the language itself. It can be well used whether you're working with angular or not.
I would recommend that you use either browserify or requireJS; it will benefit you in the long run. Just imagine having 100 JS files; you would need to out the manually into your html in the correct order based on the dependency graph. You can easily come across issues like race conditions where one file should have been inserted before another one.
As for the performance overhead of IIFEs, you shouldn't have any serious issues.
As another answer said, IIFEs are a good general practice, independent of AngularJS.
If you're concerned about the performance of IIFEs, go ahead and check out these performance tests on JSPerf (or write your own):
http://jsperf.com/iife-antecedents-in-js
http://jsperf.com/immediate-anonymous-function-invocation
While some ways of IIFE creation are clearly much slower than others, I wouldn't worry about the performance of IIFEs unless you're in a large loop.

Resources