Structuring React App for beginner - javascript

I am not new to React philosophy, and have been reading and paying attention to the community for quite some time now, but would still consider myself a beginner when it comes to actually building something. Therefore, I have decided as a little hobby project I need to actually just start building something instead of reading countless articles on how it's done.
I have no clue what the actual application is going to do yet, but what I have built now is good enough to ask my pressing questions on how to structure it with best current practices in mind.
Current app structure
Right now, this is the current layout structure of my application.
As of right now, I downloaded a starter template that already had a webpack config written for me, so for now, I would ignore the assets folder within the "src" folder, since I am not even using it to serve my css and images. Those are being served from the dist folder, which I know is not the right way to do it, but hey I can only do so much at once.
The Important Stuff
What I need most help with from you guys is the actual structuring of my components. I have been reading that CSS Modules is a good way to go, so I was looking to do something like that.
How The App Currently Works
Index.js contains the routing information. I am using React Router.
App.js is the main component for the application.
As you can see, my navbar component sits alongside the App.js file, as I plan to add a footer component there as well. Those two components are global across the entire app, and will always be in the same place in the browser. (Not sure if that's good practice.)
Inside of App.js, I render the navbar component, and include {this.props.children} which just renders content from React Router.
From there, I basically have created two other folders within the components folder, titled "landing" & "login". Those folders contain a main component, and then render other child components within them. I was thinking that each folder should get its own css file.
As I continue to build out app features and components, is this a good format to follow? Logistically speaking, I have no clue how to configure the css files to be served for each of these modules yet, but was hoping my theory of how it works is correct.
Wrap Up
Just to make sure I am being crystal clear, say for example I decide I want to build a dashboard component now. From what I just explained, my thought process would be to create a subfolder within the main components folder titled "dashboard", create a parent component for it, and then create several other child components. Then I would plop a .css file in there as well.
Here is a link to the github repo so you can see exactly how it's layed out.
Github Repo
Working version of the app
Apologize for the lengthy question, but I wanted to ensure I covered all of my concerns properly. Any other suggestions are very welcome.

There is no right or wrong answer or this one. You'll have to adapt to your project needs and notice what works best and what not.
In practice, some structures have proven to be quite useful:
Splitting by subject:
This generally means to have a folder for each 'type' or subject in your app. For example: components, utils, media and so on.
The components folder could contain other folders to group components together with their .css files, tests and other complementary code.
This structure especially fits a state handling framework like redux where you would probably want a folder for actions and action creators, a folder for reducers, a folder for store configuration and creating and so on..
Splitting by app-part
This means that you split your code in respect to logical parts of your app. Say you have a login form with a splash screen animation, all of those would be in a 'login' folder. If you have a user profile page with some dashboards then all of those and the components that they use will go into a 'user_profile' folder.
Do not torture yourself too much about are you doing this in the perfect way, because there is no perfect way. Just choose a reasonable structure the fits your project needs and go with it.
The important thing is to watch for the cases when your structure is breaking down. For example if you see that you are making changes in your application and you see that your current structure is making it difficult to refactor or to add features, or maybe it became too messy, then consider making changes to the way you structure your project.

Related

Split an existing react application to ship only a selected part of features

I have a react application which is capable to create and manage 4 different type of config files.
Each with their on set of keys and possible values.
in my App.jsx I have a custom layout component with header, side navigation, footer and a <Switch> defined from react-router-dom with different Routes to the corresponding overview and editor pages for the different config files. As well as some routes to more general pages like /home or /404. The <Switch> defines which content gets rendered in the body of the layout component.
A potential client wants to use the application but needs only to manage 2 config files of the 4 available.
I'm looking for an elegant way to introduce some sort of properties file into the application in which I can configure which sites are available and which are not.
I want to avoid copying the existing codebase and deleting everything I don't need for the client, resulting in me being forced to apply bugfixes or patches on two repos/codebases.
One approach would be to introduce conditional rendering to the different navigation links and introduce a custom hook which redirects to /404 when trying to access a disabled site. But I feel this approach can get messy quick and scales bad.
I'm looking for guides, tutorials, experiences or ideas on how to split up and ship parts of an existing react application.
Thanks in advance :)
If this is not the right place to ask, please redirect me in the right direction

Gatsby's Client Side Routing - What Gatsby features do my client-rendered pages still benefit from?

I built a small site that uses gatsby for static content, but then for some content that needs to be rendered on the client-side, I'm using client-only routes in gatsby.
I am not sure I fully understand how this works though - Say I have a Header, Footer & a font that I am using in my static site. On my client-only routes, I am using the same Header, Footer & font. Will I benefit at all from having used these elements in my statically components previously? Is the font being loaded anew, for example?
Basically, I would like to know what Gatsby-features my client-site content is losing out on now, and what I should maybe attend to a bit more, since Gatsby won't be handling this for me anymore. Especially in terms of pagespeed.
Yes you should benefit from having used those components and fonts already.
The React components that are being re-used will already be in a JS bundle that you have shipped to the user and shouldn't need to be fetched again. Likewise with the font files - but these will be asset files - not in a JS bundle.
The best way to see what is being fetched will be to test it out in a browser.
Load a static page
Open the Network tab in dev tools
Navigate to a client-only page and check for network activity
While those assets shouldn't be fetched twice I can imagine some instances where an incorrect setup would fetch them twice - so best to just double check.
Will I benefit at all from having used these elements in my statically
components previously?
The answer is yes. Gatsby works with #reach/router under the hood so you will have all benefits of it no matter if you use client-only routes or not.
In other words, the trickiest part of using client-only routes is the internal routing, for your site, in that scenario, Gatsby will handle the routing internally since it extends from #reach/router, so the shared components (header, footer, etc) will only be rendered on-demand and will be shared across your site, no matter if it's a client-only route or a static page.
I would like to know what Gatsby-features my client-site content is
losing out on now, and what I should maybe attend to a bit more, since
Gatsby won't be handling this for me anymore. Especially in terms of
pagespeed.
Summarizing a lot, when a page loads, #reach/router looks at the path prop of each component nested under <Router />, and chooses one to render that best matches window.location. So you will only render the needed code on-demand.
In terms of page speed, your site won't be affected because the site keeps being "static" and pre-mounted once the build is done. The only "negative" part of using client-only routes (if you want to say that) is the SEO part since they won't be intercepted by Google, but, that's the reason why you are using client-only paths, in most of the cases you don't want to index those pages.

Bundling react components based on per-component permission control before they are transpiled and shipped to client

I am developing an involved web app with asp.net core.
I am developing React components, writing all of my components with ES and JSX syntax.
I run webpack to transpile all of my code (so now I have pre-transpiled files ready to be served)
When a request comes in, I just serve my pre-transpiled bundles.
I wanted to have a way of only bundling and sending user-specific components (based on a list of features they have access to) to the client.
The only way I could figure doing this is to do "on-the-fly permission-controlled component bundling combined with on-the-fly jsx compilation" to serve my components.
I gather that webpack shouldn't be used as an on-the-fly bundler like this, so that is out of the picture...
Partial scrappy solution I came up with:
Using no importing or export mechanism in my js, I use Razor to cycle through my feature list, adding the appropriate (mostly modular) components in what I call "Dependency First Order" to the page, and at the end of each components' code, I write
class ComponentA extends React.Component { //Component Code Here }
window.ComponentA = ComponentA;
So all components are global and can be rendered.
This way, I am able to select what Components get sent to the client with Razor.
NOW, remember when I said "mostly modular"? Well if I am rendering a component within another component that the user doesn't have access to, this partial solution would leave the render statement embedded in main component that is rendering the sub-component itself, without the component code it's supposed to render actually being there. This being a dirty partial solution, I would just suppress the error if the component was non-existent and move on.
Bottom line is I am having a real difficult time making my react components 100% modular and being able to control the granularity of my 'component dependencies' so that no code is on the client that a user shouldn't have access to.
Ridiculous solution someone offered me:
It is also certainly out of the question that I would generate a set of bundles for every user and whenever an admin changes what a user has access to, I would re-render that bundle with webpack. (especially since I am dealing with thousands of users here).
As I am writing all of this, the more and more I feel like I am just being a perfectionist and should just go with the above paragraph.
The solution I should probably go with:
There is the ideology out there to just send all of your js to the browser and then selectively render them based on the permission of the user. Any security loopholes here would just be handled by server-side access control to lock down endpoints if a specific user did try to forge requests to parts of the application they don't have access to (which would be implemented regardless).
I am under the gun here and feel like I am overthinking most of this. I would be greatly appreciative of any feedback. Thank you.
It is possible to ship permission based JS bundle to client. You can leverage webpack dynamic import logic to load only required features JS bundles.
You need to create directory structure based on features and load them based on user permissions. Basically what webpack does is, it creates separate bundle for each feature and load it via dynamic import when requested.
Solution here 👇
Note: You might not see lazy bundles in codesandbox.io network panel, but, you can download project and run server locally to see bundles being lazy loaded.

Import Vue Component only when added to blade pages

i'm starting to develop an app using Laravel, Vuejs, and blade for template engine.
Firstly, i'm new in Vuejs's world, and maybe is a simple task, but i didn't find an answer in any discussion.
The core idea is to use .blade page, and, when i need vuejs components, add them in the page passing server's data with props array. Everything's working fine, but after playing around for a bit, i've noticed one probably furure problem.
In the laravel's documentation, we register the component, or whatever Vue setting in app.js: then, using laravel mix, we boundle in a single file all the code(e.g imports, requires, different js pages...), and finally we load "app.[hash].js" in our page with a script tag. I've noticed that even only using a few vue components, app.js growing very fast(of course, we import every components in one file), even dinamically importing components and not setting them globally.
My question is: is normal to boundle all js code in a single file(having a large file), or is there a way to import vue component only when they are added in the .blade files, maybe with some sort of webpack(laravel mix) setting?
Thanks in advance for any support.
Found the solution after post the question:
Marcin and GoogleMac's answer might be both right, but i found an interesting topic about that, and i 'd want to share for anyone could have my problem. I suggest to check out this link https://alexjoverm.github.io/2017/07/16/Lazy-load-in-Vue-using-Webpack-s-code-splitting/, where they talk about code splitting.
I think this could be the best approach, mostly because even in vue's documentation talks about(detail here https://v2.vuejs.org/v2/guide/components.html#Async-Components).
My bad for haven't checked in detail documentations.
It's good to bundle js code in a single file because it's going to be downloaded only one time by the browser and cached.
JavaScript code is not that that big so don't bother yourself with it.
I agree with Marcin's answer, but if you are wanting a workaround, comment out Laravel's built in Vue registration in app.js and just use a cdn in your blade files.
You may add multiple app.js (including multiple router, vuex if needed).
Entry them separately on webpack.mix.js.
And then include suitable app.js file as needed in the blade file.
It's much easier I think if you don't want share some .js code with any user who will not use those component ever.
NB: Of course lazy loading is a solution, but that this is more convenient solution to me as I'll not deliver any component to the user who don't need it.

Reverse Engineering / Customizing Meteor LocalMarket example app

I want to reverse engineer the Meteor example app "LocalMarket" and make something with a similar design for a different niche. The problem I'm having is I almost don't even know where to begin, for changing the navigation.
According to the official Meteor tutorial, when we create our meteor app it creates a folder with a .js file, an .html file, a .css file, and a .meteor folder.
But the LocalMarket app has the .meteor folder and then several other folders:
client, cordova-build-override, lib, public, resources, server.
There's also a mobile-config javascript file and a readme doc.
I (sort of) don't understand why there are separate folders for client and server and so many different style sheets. But that's kind of beside the point.
Long story short (and you have to run the app with Meteor to see what I mean for this question): I want to change the navigation text, icons, and links: Home, What's Cooking, Recipes, Bookmarks, About, while keeping that awesome menu style and probably just modifying the existing pages to avoid having to rename everything. Though if you have suggestions for easily renaming the pages I'm all for it.
In templates\app-body.html it looks like the menu structure is defined. For example
<a href="{{pathFor 'about'}}" class="{{activePage 'about'}}">
<span class="wrapper-menu-item">
<span class="icon-question"></span>
<span class="title-menu">About</span>
</span>
</a>
links to the Bookmarks page.
But I am not finding the styling for any of the classes listed, except in a "merged-stylesheets.css" document in .meteor\local\build\programs.
Is it okay to modify merged-stylesheets.css though? I thought the .meteor folder was not for app developers to modify. Am I wrong about that?
I do see the classes in there, i.e.:
icon-question:before {
content: "\e613";
but I am not finding that "e613" reference anywhere.
Any insight on changing out the navigation icons, text, and links for the different pages in the LocalMarket example app based on the specific issues I've mentioned, would be appreciated.
Any ways to change the page titles, and change everything app-wide to reflect that, without fatally destroying the new app, would be super appreciated.
I see how to modify the content on the pages. That looks pretty straightforward.
A way to change the displayed titles of the pages without changing their classes/ functional references to them in other app files, would help too.
Thanks very much!
There are many questions in there, hopefully we can answer most of them.
Stuff in /server is only visible server-side.
Stuff in /client is only visible on the client.
Stuff in other top level directories (and their subdirectories) is visible to both server and client
Stuff under .meteor should not be changed. That's where all your packages end up
It sounds like the style sheet for the example is part of a package. That means you shouldn't edit it directly but should instead override the styles you need to change in your own .css file that you create under /client. Your style sheet(s) will load after any package style sheets which means your styles will win.
It also sounds like one of the packages installs its own icons, hence the "\e613" You can install your own icons too using (for example) fontello
I don't know where the page titles are set in that example. There's probably a head.html file with a <title> tag or it could be set in the router.

Categories