In a React-Native project, I found that if your local package has a valid package.json file, you can import that like a module in node_modules without a relative path .
For example,
app/ # a React-Native project
|- any_folder_for_packages/
| |- foo/
| |- package.json
| |- index.js
|- src/
| |- bar/
| |- bar.js
|- ...
In this case, you can import the package foo in the bar.js using either:
// with a relative path
import foo from '../../any_folder_for_packages/foo';
or
// like a module (without a relative path)
import foo from 'foo';
The packager will try to find and use any local module which contains a package.json matching the requirement.
The question
I have a local package which is not in the React-Native project, how can I import it
projects/
|- app/ # a React-Native project
| |- src/
| | |- bar/
| | |- bar.js # need to import the package foo as a module which is not in this project
| |- ...
|- other_paths/
|- foo/
|- package.json
|- index.js
I tried to use
// like a module (without a relative path)
import foo from 'foo';
but it failed to find the module.
How can I use react-native to find the package when packing for development or bundling for the production?
Answer given by #Plague doesn't work in react native. You have to configure your metro.config.js file to use a local package.
If Using Expo
In expo, metro.config.js file may not be visible, so in the root directory of your project, run this command;
npx expo customize metro.config.js
This will generate the file for you with some default configuration. Now to import any package, you have to modify two things here;
config.resolver.nodeModulesPaths, to include the package, and ;
config.watchFolders to keep a watch on the package.
In nutshell, metro.config.js file should be like this;
// Learn more https://docs.expo.io/guides/customizing-metro
const { getDefaultConfig } = require("expo/metro-config");
const config = getDefaultConfig(__dirname);
const packagePath = "/full/path/to/package";
// here i added the packagePath to the list in the configuration to include it
config.resolver.nodeModulesPaths.push(packagePath);
// here i added the package again to another configuration key, to keep a watch on it if we make any changes.
config.watchFolders.push(packagePath);
module.exports = config;
That is it, but your code editor may report that module is not found, for that warning to remove, you can just run the command below;
npm install /path/to/package
BUT there is a problem with this
The dependencies in our package conflicts with that of main project.
So here is another way of installing a local package.
Using install-local
For this we don't need to make any changes to any file. We just need to install this package;
npm install install-local
And then install the local package using this;
npx install-local --save path/to/package
You will need to make your application aware of it through your root package.json files.
Confirm the new local module has a basic package.json configured.
For example:
{
"name": "foo",
"version": "0.0.1"
}
Ensure the package has an index.js and that it has something exported or export default.
For example, at the bottom of the index.js:
export default foo;
Then, simply save the package as a project dependency in your root module to via NPM. To do this and install it automatically into your node_modules you can use this command.
npm install --save file:other_paths/foo
note make sure you have the correct relative path from your general project package.json to your new module package.json.
Example, in this case it would be:
app/ # a React-Native project root
|- other_paths/
| |- foo/
| |- package.json # new module package json
| |- index.js
|- src/
| |- bar/
| |- bar.js
|- package.json # project package json
If set up correctly you should then be able reference the module anywhere in your project without relative path.
import Foo from 'foo';
Related
I am trying to build an NPM module that will allow an SCSS file to be exported and used across a number of applications.
The SCSS file imports another SCSS in another seperate node module.
My package structure is:
package-name
|--src
| |- overwrite.scss
|
|--package.json
|
|--webpack.config.js
|
|--node_modules
The issue I am facing is that currently I have the paths hardcoded for the import value. For example
$background-color: red;
#import '../node_module/fake_name/dist/core.scss'
I have a dependency in package.json file to ensure that fake_name module will always be in the node_modules folder of any project that will use my npm package.
What I am trying to achieve is set it that the path of #import will always look in the node_modules folder in the root of whatever project it is installed in. I have tired using ~ but I keep getting 'Error: File to import not found or unreadable'
Any help is appreciated.
I have a monorepo using Yarn workspaces. I have one package based on create-react-app which should import from a common module (sibling package in the repo).
This common package doesn't contain any React components. Just business logic. Its source is transpiled from Typescript. The common package works fine with my backend code in other packages.
Out of the box this doesn't work with CRA and gives me an error:
./src/App.tsx
Module not found: Can't resolve '#gemini/common'
What do I need to do to configure CRA to find the module?
I found this open issue on CRA monorepo support, but I'm unsure how it relates and there's a lot of information in there.
Lets assume your structure is similar to
|- monorepo
|- package.json
|- packages
|- cra
| |- package.json
|
|- common
|- package.json
make sure workspaces are registered
// monorepo/packages.json
{
"workspaces": {
"packages": [
"packages/*"
]
},
}
the gemini package name need to match to required path
// monorepo/packages/gemini/package.json
{
"name": "#gemini/common"
}
and last, use it as dependency in cra
// monorepo/packages/cra/package.json
{
"dependencies": {
"#gemini/common": "*"
}
}
run yarn to link gemini in cra
First I will give some context to the problem.
I am developing an npm library. Inside the project folder, I have another folder called "example", for testing the library. The structure looks like below.
|- node_modules/
|- src/
|- example/
| |- node_modules/
| |- src/
| |- package.json
|- package.json
The root package.json has the dependency babel-jest. The example/package.json has the dependency react-scripts. When running react-scripts start inside example directory, it gives the following error,
As far as I can understand, this is because, the package.json inside the example/ directory inherits (not sure if this is the right term) the dependencies of the root package.json.
That is, I can use a dependency installed in the root package.json, inside the src/ of the example/
This is convenient in some cases. But this is a blocker for my use case.
How can I prevent this behaviour? (without changing the directory structure)
Thank you.
From what I understand, Dan Abramov suggests to use SKIP_PREFLIGHT_CHECK=true to work around this problem as there is no real fix.
I have an npm project that builds multiple files to the public folder: an index.js file as well as several sub-files that I want to be conveniently accessible to the implementer.
My file structure on my machine looks like this:
|-public/
|--- index.js
|--- component1.js
|--- component2.js
My package.json is set up to include everything in the public folder in its tarball:
{
...
"main": "public/index.js",
"files": [ "public" ]
...
}
When I run the npm pack command, the resulting structure of the tarball looks like this:
|- package/
|--- public/
|------ index.js
|------ component1.js
|------ component2.js
|--- package.json
But in my package folder, I'd like everything to be on the same root level so that my implementer can just type import Component1 from "my-package-name/component1"; to get the sub-component. Is there a way to configure my package.json or npm to pack my project into the following structure?
|- package/
|--- index.js
|--- component1.js
|--- component2.js
|--- package.json
I ended up accomplishing this by moving my package.json file to my /public folder, then packing and publishing from that folder instead, then moving package.jsonback. If you can automate this process with a script, it is not too much of an inconvenience.
I have an electron app with the following structure
- dist
| - index.html
| - node_modules
| - nm (is an exact copy of node_modules)
- package.json
| ...
if I refer to the node modules in my index.html as node_modules/module the app won't find the module if built with the build command from electron-builder. But if I change that line in my index.html to nm/module it is perfectly willing to load it.
It seems to me that electron-builder isn't copying node_modules into the application, but I can't see why it would do that. Is it excluding all folders named node_modules and how can I fix this?