Serving static files in React


Some context

I’m building a React application. You can see the code in this Github repository: Rankit Github repository.

The live application is here: Rankit Application.

To create the environment from scratch I used the tool Create React App.

It’s easier and you don’t have to tamper with configuration files to make it work.

It works out of the box.

What I want to do

I need to load the content of a text file into a variable.

The text file contains a dictionary of words.

Restrictions

I want a solution that is as much in line with React as possible. The solution shouldn’t use tricks that don’t involve React.

The web server configuration shouldn’t change.

In my case the web server, nginx, just passes all http queries to the React application server running on port 3000. It doesn’t intercept any http query and doesn’t serve static files.

Everything happens through React. I would like to keep it that way.

I don’t want to copy and paste the file’s content into the code. I want to load the file dynamically when the program runs.

I don’t want to change any configuration file Webpack uses. When you create a React application by using Create React App, it does the job for you.

It configures Webpack and you are not supposed to touch the configuration. I don’t even know where it is and I don’t want to know.

Additionally, it would be great to avoid having to install an additional server process to do the job.

An additional tool that needs another server process to run may do the job, but it would definitely be overshot.

Why can’t I just import the file?

I discovered that I can install a loader. Webpack uses it to load a file directly into a variable.

You would say that the problem is solved.

I installed the loader using this command:

  1. root@FREEDOMANDCOURAGE:/srv/sites/rankit.emanuelesantanche.com/rankitapp# npm install --save-dev raw-loader

Then I added this instruction to my application:

javascript

  1. import txt from 'raw-loader!./file.txt';

I got this error message as well:

  1. Line 10:  Unexpected '!' in 'raw-loader!./file.txt'. Do not use import syntax to configure webpack loaders  import/no-webpack-loader-syntax

This error message comes from one of the components Create React App installs when it creates the application for you.

The component is ESLint. It parses your code to find patterns that may cause problems or that don’t comply to given guidelines.

In this case ESLint is configured with a rule that forbids the use of webpack loaders in import statements.

I can’t disable this rule because I should change ESLint configuration, which is part of the configuration that comes when you use the tool Create React App.

Among the restrictions described above there is this one as well.

What about importing the file without using webpack loaders?

The idea is to use this statement:

javascript

  1. import txt from 'file.txt';

After the import above runs, the variable txt won’t contain the file ‘file.txt’.

It will contain a string that is actually a JavaScript statement like this one:

javascript

  1. module.exports = __webpack_public_path__ + "2c2ae068be3b089e0a5b59abb1831550.eot"

I could use this statement in my code if the variable __webpack_public_path__ was defined.

It looks like it isn’t and to have it defined I should change Webpack configuration, which thing I can’t do.

Can I use Node Express?

Express is a framework I can use as backend to perform many useful tasks.

How to use it to serve static files is described here

Just I don’t want to add another server process if I can avoid it.

It would consume a lot of resources.

Can I tell Webpack to use a specific loader when a file has a given extension?

It looks like this command:

  1. webpack --module-bind 'txt=raw-loader'

would just associate text files with the raw loader.

This means that I could just use this statement:

javascript

  1. import txt from 'file.txt';

and Webpack would use the raw loader bypassing the syntax:

javascript

  1. import txt from 'raw-loader!./file.txt';

which we know ESLint forbids.

The problem is that the command ‘webpack’ is not installed and to install it we would have again to tamper with the configuration Create React App uses.

Let’s use the public folder!

Webpack treats a folder in a special way.

It’s the public folder.

If you put a file there, it’s not going to be transformed or moved.

You can access it with a fetch statement and load it into a variable.

The file dictionary.txt is in the public folder, which in our case is this folder: /srv/sites/rankit.emanuelesantanche.com/rankitapp/public

The following fetch statement loads that file and its full content is passed to a function, t9init, as parameter.

javascript

  1. fetch("dictionary.txt")
  2.             .then((response) => response.text())
  3.             .then(function(data) {
  4.  
  5.                 t9init(data);
  6.            
  7.         })

There is no need to specify the full url of the file because Webpack will prepend the url of the public folder.

Actually, if you try to use a url in your fetch statement that you think may be correct, it won’t work.

If you use these urls:

  • /public/dictionary.txt
  • /reactapp/public/dictionary.txt
  • public/dictionary.txt
  • reactapp/public/dictionary.txt

it won’t work. If the file is in the public folder, just give its url relative to the public folder.

This Webpack peculiarity may have misled you when you were trying to fetch the file by giving its url.

Leave a comment

Your email address will not be published. Required fields are marked *