Resolve src dir for imports in React Native - react-native

How can I configure React Native to import files relative to the src directory? In other words, I want to write import Foo from 'components/foo' rather than import Foo from '../../components/foo'.
When using webpack it can be configured like this. With React Native packager I haven't found a way to do this.

I haven't found a solution that let's you import exactly the way you want, but there are several suggestions of how to configure import locations in this thread.
My favorite solution
(Works in any JavaScript project, not just React Native, and let's you write very short paths to reference files.)
Create a package.json in your src/ directory with the contents:
{
"name": "src"
}
What this does is say: This folder is a package, named src. Then you can import any file/directory inside that package by simply adding it's position (relative to the directory the package.json is in) after the name of the package:
import Foo from 'src/components/foo';
Another solution
In any React Native Project, you can do:
import Foo from 'MyApp/src/components/foo';
where MyApp is whatever name you registered in your index.ios.js and index.android.js files.
The app name is registered using one of the AppRegistry methods, such as
AppRegistry.registerComponent('MyApp', () => AppRootComponent);

A good solution is to make your babel resolve all the logical paths before it transpile. You can accomplish this by adding babel-plugin-root-import to you're node dependencies and changing you're .babelrc, similar to the code bellow:
"plugins": [
["babel-plugin-root-import", {
"rootPathSuffix": "src"
}]
]
Now you can refer to all your components inside src like this
import Component from '~/business/ComponentExample'

Related

Publish custom vue component library npm package with friendly import alias for components

I have a vue 3 component library published in an internal nexus npm repo as a package.
It is normally a dependency for other vue projects that consume the *.vue ui components in the library, and have an entry like
"dependencies": {
"#namespace/package-name": "^3.1.1",
So far I consume the library components within the end project importing like:
import componentName from '#namespace/package-name/src/components/atoms/component-name';
But I am planning to set an index.js file in /src/components/ so I can use something simpler like
import componentName from '#namespace/package-name';
The index.js file is as follows:
export { default as ActionButton } from './atoms/action-button/index.vue';
export { default as Autocomplete } from './molecules/autocomplete/index.vue';
export { default as Avatar } from './atoms/avatar/index.vue';
...
Note that I split html, js and css in three different files and that's why I have an index.vue file calling them three, but it is like using a compo.vue file. Also, inside /src/components, I have folders like atoms, molecules, organisms... due to atomic design.
From the read docs, I am trying to set rules in the package.json file of the library, like:
"exports": {
".": "./src/components/index.js"
},
but without luck, having the mentioned import (import componentName from '#namespace/package-name') giving the error:
ERROR Failed to compile with 1 error 14:46:12
This dependency was not found:
* #namespace/package-name ...
I have no other special entries in the lib's package.json file, regarding publishing.
Am I using the exports entry correctly, or should I use other?
Whats the way to proxy or alias all my components (placed in different folders and so) under a simple, accesible path when importing them in the final projects?

How to include a (compiled) JS file in NuxtJS

I’ve a NuxtJS app and want to include a file called app.js (located in assets/js/app.js).
Contents of that file:
// imports from node_modules
import 'focus-visible';
import 'other-package';
…
What I am doing at the moment is to import that packages inside layouts/default.vue … but it doesn’t feel right.
How would you do it?
Importing the assets file is no different than importing any other JavaScript file from another src directory:
import '#/assets/js/app'
It's hard to say whether this usage is "right" without more context, but I don't see anything wrong with doing that.

What is a short way to import external React components?

In the docs directory (docusaurus project) I create markdown files and these MD files contain imports from external react project (it's a local project placed in other directory).
Everything works fine, but one tiny thing. Now I import files like this:
import Component from '../../../react-project/src/components/Component';
I don't know how to shorten the path. I'd like to write something like this:
import Component from '#components/Component';
How can I do this?
If you have your separate components within a git repository, you can reference that repository as an imported module.
npm install git+https://github.com/yourUser/yourRepositoryName
import {Component} from yourRepositoryName

Importing custom icons into React Native 0.62

I'm trying to import and use my own custom icons in my React Native 0.62.2 app.
I followed the steps outlined here https://github.com/oblador/react-native-vector-icons#custom-fonts but so far the icons are not showing up.
Here are the steps I followed:
Created my icon set and converted it to fonts on https://icomoon.io
Downloaded the zip file from IcoMoon and placed the ttf file into ./src/assets/fonts folder
I then created react-native-config.js file and placed in the root. The code in this file is down below
Under my components folder, I created CustomIcon.js -- see code below
I also placed the selection.json file that was included in the zip file I downloaded from IcoMoon in the same folder as CustomIcon.js
I then used the CustomIcon as shown below
So here what the codes look like:
The react-native-config.js file looks like this:
module.exports = {
project: {
ios: {},
android: {},
},
assets: ['./src/assets/fonts/']
};
The CustomIcon.js file looks like this:
import { createIconSetFromIcoMoon } from 'react-native-vector-icons';
import icoMoonConfig from './selection.json';
export default createIconSetFromIcoMoon(icoMoonConfig, 'StreamLine', '../../../assets/fonts/streamline-icon-set-1.ttf');
And here's how I use the icon:
import CustomIcon from '../common_components/fonts/CustomIcon';
<CustomIcon name="home-outline" />
When I run the app in Android Emulator, I see the missing icon symbol i.e. a box with an X in it.
Any idea what the issue is here?
There is a really good article which helped me with this problem.
Custom icon fonts with React Native
There is always issue with custom icons. When I personally bump into such condition I do these:
Rename the react-native-config.js to react-native.config.js
Re-run the app by restarting metro
Make sure I have correct path to my assets in react-native.config.js
react-native link and restart. It copies your assets to corresponding ios and android folders
If neither do not help I copy the assets manually to folder: Project/android/app/src/main/assets/fonts

Importing installed node modules vs importing css or other files in React

Could someone explain why this:
import React from '../node_modules/react';
is the same as:
import React from 'react';
and this:
import './App.css';
is NOT the same as:
import 'App.css'; or import 'App.css';
in the later example I get a message that the file App.css can not be found in the src directory but it is there.
It identifies the modules by name
But files it detects only by path
As you will see in the documentation
module-name
The module to import from. This is often a relative or absolute path name to the .js file containing the module. Certain bundlers may permit or require the use of the extension; check your environment. Only single quoted and double quoted Strings are allowed.
name
Name of the module object that will be used as a kind of namespace when referring to the imports.
Installed Node Modules can be imported without specifying the path.
App.css is not a node module and therefore the path needs to be specified
Since the release of create react app V3 you can also type out absolute paths instead of the sometimes confusing method './../file.js'