Basic understanding - Location of public directory in React app - reactjs

I'm building a React app with webpack. I was curious about where to put my "public" folder. I know in create-react-apps, the public folder is outside the "src" folder.
I'm not sure I'm clear on why you would want your public assets outside of your source folder. Is index.html not part of src? Is that not a crucial part of your code? Why would you put the public folder outside on it's own?
I'm trying to find good reading on this topic, but it seems folder structures are very subjective. If anyone could explain this, I would appreciate it. I want to firmly understand why the public folder is outside the src folder in create-react-app.

You posted this quite a number of months ago and I am surprised that there have been no responses as you raise an interesting point.
I believe the answer to be somewhat historic. In the past, the public folder was, indeed, public, meaning it contained a well-structured and hand-crafted index.html file and perhaps some other artifacts. These were intended to be consumed "as-is" while other parts of the application (i.e., JavaScript) remained in their own folder to be transpiled, merged, etc.
But that was then and this is now.
With the advent of modern packaging/bundling tools (webpack, brunch, parcel, and so on), such a distinction is no longer relevant nor does anyone really give it much thought.
With these bundling tools, everything is "source code" (as you pointed out) with the tools transforming index.html to correctly reference bundled CSS and JavaScript code.
So, while I cannot speak directly for the create-react-app team, I would submit that the public folder concept is largely an anachronism harkening back to the days where it really was public.
These days, everything ends up in a dist folder, which is then served to the end user. The machinery that creates this dist folder is largely ambivalent on how you structured the tool's input to arrive at the final distribution. Basically, the tools do not care about a public/src folder distinction, so why should you?
I hope that helps. I personally have index.html right alongside index.js in the src folder. The process is src -> bundler -> dist (just like good old C programming: src -> compiler -> exe).

Related

React suddenly responding with index.html instead of javascript imports

Recently I've been unable to load javascript scripts to my webworkers in react for some reason. It always responds with index.html.
My config is simply a standard create-react-app app. The screenshots are from my actual project but I have confirmed that the problem persists if I create a new project and try to initialize a minimal example.
Each ffmpeg.* file is affected. This is also not specific to ffmpeg since another library had the same issue - thankfully the initialization of that library is simpler so I was able to simply put that libraries worker-file in the public folder - and that worked.
It might be a stupid question but I'm really at my wits end here and I can't figure out how to investigate further.
Thank you <3
EDIT:
It works if I put all the files it is trying to hit in the public folder - so it has to be some kind of context issue(??) This seems like a really stupid way to go about it. It's not in a worker at the point of loading - it's the worker loader that fails to access the stuff it needs in the node_modules folder, (core script, worker script and wasm code). Whet?

Is there a point to creating a folder inside the public folder?

I'm extremely new to React & recently found out about the %PUBLIC_URL% stuff.
Generally, what is the point of using the url?
Also, it seems kind of messy putting a lot of images/json/etc in one place, so I was wondering if there was any point to creating an img folder inside the public folder: ex. public/img and accessing it like: %PUBLIC_URL%/img/img1.jpeg.
Would that mess anything up?
I've done some research about it but I'm kind of dumb so I don't really see the point of using PUBLIC_URL over just accessing the public/ folder.
From https://create-react-app.dev/docs/using-the-public-folder, it says:
If you put a file into the public folder, it will not be processed by webpack. Instead it will be copied into the build folder untouched. To reference assets in the public folder, you need to use an environment variable called PUBLIC_URL.
Honestly I don't know what this means; could someone explain? Sorry for all the dumb questions <3
TL;DR: Put assets you use from javascript inside your source folder, either in a specific folder (src/img) or next to the javascript files that use them. Use public/ for files referenced in your html, with %PUBLIC_URL% to keep create-react-app happy.
Ideally you'll want all assets and files used in your javascript inside the src folder. This way you can import these files and create-react-app will make sure you have a valid url to them.
Files in your public folder can't be import'ed from javascript! You'll want the public folder for any assets that you need from html directly (favicon, manifest.json, robots.txt) or you just want to be able to link to them (I sometimes have a logo.png in there so I can use that url on other websites).
The PUBLIC_URL is required for assets in public/ because create-react-app needs to insert the path in case you serve your app in a nested path. for example, https://youdomain.com/myapp/v2/index.html, would have a public url /myapp/v2. This needs to be set in your package.json, but if you don't serve from a subpath you don't have to change anything.

Reduce size/number of files being downloaded from EXTJS app

I used Sencha CMD to build an app and want to ensure that I'm only downloading what is required for the app to run. I have read some places that the way to do this is by using the Required [] clause to only include the required classes, however I don't think I understand this clearly. For example I have a page that has an {xtype: 'grid'} within it, but I haven't put Requires : [ 'Ext.grid.Panel' ], yet it still displays properly. In my mind if I haven't included the requires, and CMD is doing what I think it should, this page should fail to load because Ext.grid.Panel wasn't included. The fact that it's working is making me think that CMD is automatically including it for me, but what else is it automatically including and potentially bloating the download? How can I ensure that I'm only downloading what's required for the app to run?
I found the answer to my problem. I was developing my app on the same server that I'm serving it from, and when I was running "sencha app build production", it's putting all of the "build" files into a separate directory. I was assuming the microloader/bootstrap process was then going to look in that directory but I guess that's not how it works. I had to then copy those "build" files to a new directory and include my index.html and bootstrap.js in the new directory and then it appears to work, only loading the required files. It's certainly not clear anywhere that this is what's required. Hopefully this will help anyone else having the same issue.

Loading a needed file, relative vs absolute paths

We have a program people can compile on their machines. It has an HTTP interface but can also be invoked by command line.
In order to provide some nice-looking error pages for HTTP clients, we want to provide error pages. We are using a very simple solution with go's html/template package.
So in order for the program to find the templates, we currently do:
func init() {
prefStr := "path/to/http/tmpl"
pathPrefix,err := filepath.Abs(prefStr)
if err != nil {
log.Warn("Template path %s is not available!", prefStr)
}
pathPrefix + "/err.html"
}
Now when debugging the app, this usually works well - we are in the package's root directory, so filepath.Abs() resolves correctly, like so:
$GOPATH/github.com/user/repo/path/to/http/tmpl (expanding $GOPATH correctly)
But when we invoke the app via executable from the command line, this doesn't work. The command line could of course be invoked from anywhere on the filesystem, for convenience for example to provide a file in the current directory as a parameter.
In short, running /some/other/path/on/fs/our-executable filename.txt results in the init() function above breaking due to wrong concatenation of the directory: it takes /some/other/path/on/fs/ to create the absolute path, which is wrong. Thus it crashes with
panic: open /some/other/path/on/fs/path/to/http/tmpl/err.html: no such file or directory
I've searched and so far only found this:
How can I open files using relative paths in Go?
But this exactly doesn't apply for us.
Another solution proposes to bundle compiled go resources, but this seems rather odd as the error pages are html text.
We've also tried
https://stackoverflow.com/a/31464648/169252
but it has the same effect.
How can we make sure that the paths are always resolved correctly? This seems rather something which shouldn't be too difficult to be done, but we haven't managed so far.
EDIT: This is not an exact duplicate of the question How can I open files using relative paths in Go?. As already mentioned in my question text, I already had looked it up myself. It suggests to use filepath.Abs(). But as laid out in my question, for us this doesn't work, as if our executable is called from different places, filepath.Abs() doesn't return the same value, and thus doesn't work for us.
I think your challenge here is that people can install the program anywhere on the disk and the program will have to be smart enough to know where it is later on.
One of the common approach that I have seen is that people typically use environment variables to anchor them to the application's installation path. I believe you may have seen environment variables with naming pattern of *_HOME like JAVA_HOME, MAVEN_HOME and their values are always filepath to the installation place.
I guess you can do the same here. Force your users to have MYAPP_HOME variable define and at the start of the application make sure that it is set or else throw an error saying MYAPP_HOME is not set.
Then all you need to do would be a simple lookup of the value for MYAPP_HOME + /http/tmpl to source for the template html files.
Example:
package main
import "os"
func main() {
// Assuming MYAPP_HOME has been verified that it is set
// Then:
tmlPath := os.Getenv("MYAPP_HOME") + "/http/tmpl/"
errTml := tmlPath + "err.html"
}
If you're not keen on using the current working directory, or passing the directory in, you can find the absolute executable path by calling os.Executable from the os package.
appPath, err := os.Executable()
The os package will generally contain os specific stuff like how to get the current working directory. It's worth looking through the pkg docs and list of packages at golang.org if your'e ever stuck, as they are pretty good typically you'll find an answer there.
https://golang.org/pkg/os
Another approach you can take here if users install with go get is to rely on the fact that your templates will be installed with the pkg under GOPATH, so you can always find them at $GOPATH/src/your/project/path/templates (or ~/go the default gopath now that it is not strictly required).
The safest way is probably to bundle them with the binary in a virtual file system as this means you depend on nothing external and don't care where your app is hosted or even if it has access to files at all.
I recommend using a relative path in this case.
According to your description, it seems like you are developing a web application. While it works fine on individual developer's machine, you need to be mindful that your application can be deployed under any directory on your production server. You cannot determine where you app is going to be deployed, but you can always determine where static files are relative to the root directory of your app.
When you invoke your app in the command line, you should have all the required static files copied to the same relative path exactly the same with your development environment. My typical structure is:
project/
|- config.json
|- main.go
|- package1/
|- package2/
|- static/
|- templates/
| |- index.html
| |- base.html
|- css/
|- javascript/
|- image/
When you are ready to run your application from command line, be sure to copy your config.json and the static/ directory to the same level as your executable binary. Then all you need to do is to use relative paths in your code without any nightmares.
For the records: as we just have two templates, we resorted to store them as strings in a go file so that they get compiled. Our html templates are very simple, so this is a reasonable way to do it.

How do you physical download and start using Backbone

This is a must-answer question that needs answered for a generation of coders.
I know to go to the website, but how do you actually download Backbone and start coding.
Most tutorials leave out this stage.
Thanks for helping!
Most Backbone code I see on stackoverflow is a real mess lacking structure which is a shame. But the flexibility in the right hands is also a very strong point that is why larger companies still use frequently choose Backbone whilst newbies would go for something with a little more magic out the box like Angular or Ember.
This is what I recommend in a general sense:
Grunt or gulp for tasks - grunt might be easier as it is more widely used still. Main tasks would be:
- build (compile and minify your code and css) and bundle into a build folder
- server (runs local server or a server from a build folder)
- test (if you have unit or functional tests)
Next you have an index.html file which contains an app wrapper and a single RequireJS call the the entry point of your code.
My folder structure would look something like this:
server/
server/server.js
public/
public/app/app.js
public/app/modules/
public/app/extensions/
public/assets/
public/assets/css/
public/assets/images/
public/packages/
public/index.html
dist/
dist/<env>/public/assets/
dist/<env>/public/app/app.min.js (or app.js depending on env)
package.json
Gruntfile.js
A colleague's boilerplate is probably the closest to my ideal setup in the public domain: https://github.com/mderrick/backbone-boilerplate
There is also marionette: http://marionettejs.com/

Resources