Asked  6 Months ago    Answers:  5   Viewed   359 times

I am using create-react-app. I am trying to call an image from my public folder from a file inside my src/components. I am receiving this error message.

./src/components/website_index.js Module not found: You attempted to import ../../public/images/logo/WC-BlackonWhite.jpg which falls outside of the project src/ directory. Relative imports outside of src/ are not supported. You can either move it inside src/, or add a symlink to it from project's node_modules/.

import logo from '../../public/images/logo_2016.png'; <img className="Header-logo" src={logo} alt="Logo" />

I have read many things saying you can do an import to the path but that is still not working for me. Any help would be greatly appreciated. I know there are many questions like this but they are all telling me to import logo or image so clearly I am missing something in the big picture.

 Answers

66

This is special restriction added by developers of create-react-app. It is implemented in ModuleScopePlugin to ensure files reside in src/. That plugin ensures that relative imports from app's source directory don't reach outside of it.

You can disable this feature (one of the ways) by eject operation of create-react-app project.

Most features and its updates are hidden into the internals of create-react-app system. If you make eject you will no more have some features and its update. So if you are not ready to manage and configure application included to configure webpack and so on - do not do eject operation.

Play by the existing rules (move to src). But now you can know how to remove restriction: do eject and remove ModuleScopePlugin from webpack configuration file.


Instead of eject there are intermediate solutions, like rewire which allows you to programmatically modify the webpack config without eject. But removing the ModuleScopePlugin plugin is not good - this loses some protection and does not adds some features available in src.

The better way is to add fully working additional directories similar to src. This can be done using react-app-rewire-alias


Do not import from public folder - that will be duplicated in the build folder and will be available by two different url (or with different ways to load), which ultimately worsen the package download size.

Importing from the src folder is preferable and has advantages. Everything will be packed by webpack to the bundle with chunks optimal size and for best loading efficiency.

Tuesday, June 1, 2021
 
ajreal
answered 6 Months ago
97

Set HTTPS=true before you run the start command.

Documentation

The implementation uses the HTTPS Environment Variable to determine which protocol to use when starting the server.

Thursday, July 15, 2021
 
Shobit
answered 5 Months ago
94

You need to install next npm-packages in your project:

  • stylus
  • stylus-loader
  • css-loader

In webpack.config, in section module you need to add next points:

{
  test: /.styl$/,
  use: [
    'style-loader',
    'css-loader?modules&camelCase&localIdentName=[path]__[name]__[local]--[hash:base64:5]',
    'stylus-loader',
  ],
},
{
  test: /.css$/,
  use: [
    'style-loader',
    'css-loader',
  ],
},

Then you can import your styles from .styl files in your React components like this:

import style from './СomponentStyle.styl'; 

and you can use style by CSS name for example:

className={style.container} 

where container - it is name of CSS but without dot. For complicated names like: .container-btn-green you need write next code: style.containerBtnGreen or style['container-btn-green']

Wednesday, August 4, 2021
 
user2725742
answered 4 Months ago
19

TLDR Answer: Nowhere!

-- Nuanced Answer --

What I'm trying to do is extend pure JavaScript classes, like String class, which is a very common task in javascript

Is it even "OK" to extend object prototype in React (or in JavaScript) at all?

Extending/modifying native prototypes in JavaScript is a controversial topic, and, contrary to what you said, not something most professional developers do very often. The general consensus is that extending the native JS prototypes is a programming anti-pattern to be avoided, because it breaks the principle of encapsulation and modifies global state. However, as with many rules, there may be rare exceptions to it. For instance: you're working on a toy project that doesn't need to be production quality, you're the only dev who will ever touch that code base, or your code will never be a dependency for anyone else.

If you have a really good reason and really know what you're doing and are fully aware of the potential consequences of your modifications to the native data types/behaviors for your run-time environment and dependencies, then perhaps you will find some valid use case for this practice. But most likely not, or at least not very often. Like almost never.

If you're just after convenience / syntactic sugar, you're better off pulling in utility functions (from the likes of lodash, underscore, or ramda) and learning to practice functional composition. But if you're really committed to the Object Oriented paradigm, then you should probably just be "subclassing" the native data types rather than modifying them.

So rather than mutating a class's prototype like this:

String.prototype.somethingStupid = function () {
  return [].map.call(this, function(letter) {
    if ((Math.random() * 1) > .5) return letter.toUpperCase()
    else return letter.toLowerCase()
  }).join('')
}

console.log('This is a silly string'.somethingStupid())

You would create a sub-class (only works with ES6 class syntax), like so:

class MyString extends String {
  constructor(x = '') {
    super(x)
    this.otherInstanceProp = ':)'
  }
  
  somethingStupid() {
    return [].map.call(this, function(letter) {
      if ((Math.random() * 1) > .5) return letter.toUpperCase()
      else return letter.toLowerCase()
    }).join('')
  }
}

const myStr = new MyString('This is a silly string')
console.log(myStr)
console.log(myStr.valueOf())
console.log(myStr.somethingStupid() + ', don't you think?')

This subclass would work like a built-in String in every way, except of course that you wouldn't be able to write MyString literals like String literals.

I created a pure React application using create-react-app. I would like to extend the String class and use it in one or more components ... Yes I can define it beside a component and use it within. But what is the best and cleanest way? ... Should I write it as a class method or inside componentDidMount or something else?

Because modifying built-in prototypes (by mutating things like String.prototype) alters the global state of your application, it is something that you will want to execute only once and almost certainly before any other code executes (because you're setting the global state of how Strings behave for all code that executes after). So altering built-in prototypes from within a React component instance method wouldn't make much sense.

If you're going to do the dirty deed, I'd recommend creating a separate module for each native type you want to modify, and keep those modules somewhere like src/lib/extend-built-ins/ or something, and then import them as the very first thing in src/index.js. You wouldn't need to export anything. Doing import src/lib/extend-built-ins/String.js will execute the code, which will mutate your global state. That would provide at least decent organization and ensure that your application environment is fully modified before the rest of your app's code runs. That way you can just use your extended types throughout your application without thinking about importing them from somewhere.

If you're going to go the subclassing route (class MyThing extends NativeThing), then I would recommend you similarly define your custom classes in separate modules somewhere like src/lib/native-subclasses/. But in this case, you would have to import your class constructors into any/every module where you want to use them.

However, if you want to develop clean, testable, refactorable code that will be easy for others and your future self to understand, you shouldn't do this sort of thing. Instead, think about adopting the functional programming principles of React and its ecosystem. Anyone can quickly read and understand a pure function, so use them to accomplish your data and state transformations rather than relying on hard-to-track hacks like modifying global objects. It may be cute and trivial to understand this one little hack, but doing it even once in a project promotes and encourages yourself and others to use additional shortcuts and anti-patterns.

Sunday, September 19, 2021
 
mpen
answered 3 Months ago
65

The answer is found in this thread React-router and nginx

What I had to do was modify default configuration file in /etc/nginx/sites-available/default to:

    location / {
            # First attempt to serve request as file, then
            # as directory, then fall back to displaying a 404.
            try_files $uri /index.html;
    }
Tuesday, November 2, 2021
 
Nate
answered 4 Weeks ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :  
Share