React - importing files from outside src directory - javascript

I am trying to follow along with this Medium tutorial: https://medium.com/#bryantheastronaut/react-getting-started-the-mern-stack-tutorial-feat-es6-de1a2886be50
Others who have tried to follow this have commented that they have the same problem as me, although solutions to this problem are yet to be discovered in that tutorial, and similar problems on SO relate to image files, where the answer is to move the specific file to the src directory.
The problem is referencing the data.js file, which sits at the top level (the same level as the src directory.
When I try to incorporate it in a file, like so:
/CommentBox.js
import React, { Component } from 'react';
import CommentList from './CommentList';
import CommentForm from './CommentForm';
import DATA from '../data';
import style from './style';
class CommentBox extends Component {
constructor(props) {
super(props);
this.state = { data: [] };
}
render() {
return (
<div style={ style.commentBox }>
<h2>Comments:</h2>
<CommentList data={ DATA }/>
<CommentForm />
</div>
)
}
}
export default CommentBox;
an error that says the following results:
Failed to compile.
./src/CommentBox.js
Module not found: You attempted to import ../data 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/.
This SO post has a similar problem: The create-react-app imports restriction outside of src directory, however the solution is to move an image file to the src directory.
Has anyone figured out how to link to a file at the same level as the src directory in a react file? I don't understand what a symlink in the node_modules directory means, and I can't find a tutorial for how to make one.

I recommend you simply put the data.js file inside your src/ directory. It's just mock data, right? It should be part of src for your development. Just do it and get through the tutorial. That's all. If you really were dealing with a production app, you would have ejected the app to have more flexibility over its whole configuration and thus would be able to eliminate that restriction.

Related

Better way to import files for webpack bundle size

hooks/index.js
export { default as useDialog } from './useDialog'
export { default as useCurrencies } from './useCurrencies'
export { default as useUser } from './useUser'
Let's imagine that I have 3 files in hooks folder (useDialog, useCurrencies, useUser) . I want to make the correct imports from this folder. Now I do imports like this :
import {useDialog} from 'hooks'
Is it correct way to import this file , or it is better to import it like import useDialog from 'hooks/useDialog' ? What is better for my bundle size ?
You can try yourself and compare the bundle sizes on production from before and after. I'm gonna explain how to do it if anyone needs it.
First do these steps with the code importing from the index: import {useDialog} from 'hooks'
yarn build
serve -s build
Open the local address (http://localhost:5000/) on incognito mode. Then open Inspect -> Coverage.
At the bottom you can see the size. e.g: 1.2MB of 2.1MB (55%) used so far 964kB unused
Then change your code and import directly from the file: import useDialog from 'hooks/useDialog', and repeat the build and check the size.
Maybe if the files are too small you are not going to notice a difference, but you will if there are any big files or files that imports a big external library.
I tried this comparison on my project and there was one file importing and using moment. I was not even using this component, but the bundle size was increased because I was importing another component from the same index.
Before I was always importing from a folder like 'hooks', but from now on I will always import directly from the file 'hooks/useDialog'.
I'm just sharing my experience! Please, compare the bundles on your own projects!

How to import file from public folder in react application?

I have a javascript file in the public folder and I want to import that file to components in the folder src/components.
projectFolder
publicFolder
index.html
recorder.js
srcFolder
componentsFolder
Speech.js
Speech.css
But I can't do something like this in my component:
import Recorder from '../../public/recorder'
Because I get the following error:
Module not found: You attempted to import ../../public/recorder 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/.
As I've understood it's not allowed to import outside of /src directory, so I was wondering how I could "add a symlink" or if you know other ways to fix it.
I believe you are using create-react-app ... this is a feature included in the ModuleScopePlugin, and you can disable it by ejecting the app and editing your webpack configuration (as described in this answer).
But beware, the feature exists for a reason. The create-react-app build tool only processes the src/ directory, so for example your JavaScript outside of here will not be transpiled by Babel. Furthermore, you're typically trying to avoid polluting the global scope if you're using a bundler like Webpack. So unless you've got a really specific reason why you'd need to do this, I'd say try and move it.
You can modify the react-scripts config with the rescripts library
Create a file called .rescriptsrc.js in your root folder:
module.exports = config => {
const scopePluginIndex = config.resolve.plugins.findIndex(
({ constructor }) => constructor && constructor.name === "ModuleScopePlugin"
);
config.resolve.plugins.splice(scopePluginIndex, 1);
return config;
};
If you're ok not using the actual file in public and having a duplicate js file in the src directory there's a hacky but cool solution if you use vscode. This vscode extension https://marketplace.visualstudio.com/items?itemName=emeraldwalk.RunOnSave allows you to trigger a command on save (you can use regex to specify which file saves should trigger which commands) and you can specify a command to run on save as such:
{
"match": "public\\\\recorder.js$",
"cmd": "copy ${file} ${workspaceFolder}\\src\\recorder.js"
}
Now you can import from that duplicated file.
As i can see you want to import parent component in child component.
While defining path './' represents the current directory in which you are working so you can go one level up by following '../' for one level up and the same goes for the upper level directory.
So if you want to import from public folder inside Speech.js component you could do something like this.
// In Speech.js
import Recorder from './../../public/recorder';
Hope this will be useful to you.

React - files import

I have a question about importing files in React.js (create react app).
For example, I have two components firstComponent.js and secondCmponent.js
In both files I import the same file with CSS styles:
import 'some.css';
Does this mean that after building the application I will have code from some.css x2?
If I call the components side by side (at the same time)
example:
<div>
<FirstComponent />
<SecondComponent />
</div>
In the browser memory, some.css will be x2?
create-react-app under the hood uses Webpack which is a module bundler that takes all your files and output them in one file so when you use a file for example .css file in many places webpack will only include that file only one in your output file > so you don't have to worry . that's also works for other assets like images , fonts , js files
learn more about webpack
webpack tutorial
But why do you include the same file twice? Why cant you split your css into three files:
Main.css (contains standard styling)
FirstComponent.css (contains specific styling for FirstComponent.js)
SecondComponent.css (contains specific styling for SecondComponent.js)
and then in your files:
App.js
import './Main.css';
class App extends React.Component {
render () {
<div>
<FirstComponent />
<SecondComponent />
</div>
}
}
FirstComponent
import './FirstComponent.css';
class FirstComponent extends React.Component {}
SecondComponent
import './SecondComponent.css';
class SecondComponent extends React.Component {}
this wont give you the double file import like you experience.
Another use by ejecting
dont use this if you dont know what your'e doing..
You can with the help of webpack plugins, manage your chunks that if a thing gets imported N times, it will be moved into a commons.js file, before webpack 4 this was called commonChunksPlugin, now at webpack 4, i dont have this in my head, but i do think this is more or less included by default nowadays (need source).
When I was doing export file I use this is correct way
Import named exports from the file Mamatha.js:
import { name, age } from "./Mamatha.js";

Importing JavaScript files with the same name as directory they're inside

In my React and Webpack project, I have the following project structure of React components:
Component/
├── Component.jsx
├── index.jsx
└── styles.css
The index.jsx file simply imports and exports Component.jsx; the reason being that in files that require it, it allows the usage of the following:
import Component from '../Component'
as opposed to
import Component from '../Component/Component'
However this seems like it may be an unnecessary extra step which requires all new components to follow suit.
With this in mind, my question is: Can I have the best of both worlds? I want to be able to only have Component.jsx and styles.css in my directory, but not have to use the name twice in my import declaration.
Let me suggest you the following structure I personally like:
Your component tree structure (As an example every component has a different folder structure. It is up to you to keep it clean and tidy. Index.jsx in components folder just normalizes access to those components whoever needs them):
src/components/
Butter/
Butter.jsx
index.jsx
Beets/
Beets.jsx
Cabbage/
index.jsx
Meat.jsx
index.jsx
Content of components/index.jsx
export Butter from './Butter/index.jsx';
export Beets from './Beets/Beets.jsx';
export Cabbage from './Cabbage/index.jsx';
export Meat from './Meat.jsx';
Some container Borscht.jsx somewhere else in your project which uses those components
import {
Beets,
Cabbage,
} from 'src/components';
If your folder already tells you which is the component name, you don't need to put it again in the file name inside it. I use this approach.
All modern editors already solves the trouble with two equal names (ComponentA/index.jsx and ComponentB/index.jsx) for us, by adding the folder name in the tabs.
Note that this is an Vue component, but it's the same thing for React.
One option for webpack users is to install directory-named-webpack-plugin
Install, and then add the following to Webpack's config file:
var DirectoryNamedWebpackPlugin = require("directory-named-webpack-plugin");
resolve: {
plugins: [
new DirectoryNamedWebpackPlugin()
]
}
When using require("component/foo") and the path "component/foo" is resolved to a directory, Webpack will try to look for component/foo/foo.js as the entry point.
Caution: While this approach does allow webpack to resolve filenames when building and bundling, your intellisense / tooling options are a different beast altogether. Unless they also have similar functionality, you may lose Go To Definition and Intellisense support by not providing the full reference statically.

Import files from parent directory into React Native app

I have a file hierarchy as follows:
-native
-app
-components
login.js
-redux
-modules
-users.js
In my login.js file, I attempt to import the users.js redux into my code as such:
import { actions as usersActions} from "../../../redux/modules/users";
It is shared code and I cannot put the redux code in native/
The error I get is:
Unable to resolve module ../../../redux/modules/users. ... Unable to find this module in its module map or any of the node_modules directories.
I've looked at the other questions, such as: React import from parent directory but in the comments it states it to be impossible. I've also tried the fixes in https://github.com/facebook/react-native/issues/4968 but that seems to be mostly for node-modules.
Try creating a symbolic link inside the native directory that references the parent directory

Categories

Resources