Is it possible to import one React app(built using create-react-app) into another completely different React app. We all have imported components in our SPA, but is it possible to import a different app entirely? If so how?
Furthermore, both these react apps MIGHT share a few similar dependencies/files/libraries.. such as bootstrap/css/Redux stores/etc. Also, with a possibility of a few common reducers. These common reducers, might need to interact/listen to actions in-between these two react app.
Lets say we have:
ReactDOM.render(<Provider store={store}><MainApp /></Provider>, document.getElementById('root'));
Could i add another app like this(that was NOT built in this), and target another nod in the dom???
ReactDOM.render(<Provider store={store}><ExternalAPP /></Provider>, document.getElementById('root22'));
Has this ever been done before? React compresses all our components into "chunks" which are basically js files.
Thank you, for any tips/suggestions/hints
You can use npm pack command.
It creates a tarball (.tgz) file from your current app. Then move this file your other app folder then run:
npm install app1 (assuming app1 is your first app name).
After it is installed, you can see your app1 files inside the node_modules/App1/. Now your can import the files or components you want and use it in other apps.
Hope this helps.
Also Checkout this: https://docs.npmjs.com/cli-commands/pack.html
One way that worked for me is to bring the CRA to Github and npm install it as a dependency. I highly encourage you to check out this resource which explains in detail how to prepare a React component for this process. Follow the steps in the linked tutorial up to #3, then bring everything (including the /dist folder) to Github. Then, do npm install org_name/repo_nameand install it as a dependency in your second React app. Then, to import a specific component, you can do something like import { Button } from 'repo_name/dist/index' or reference whatever file you used to export your components.
In case the link doesn't work, here are the steps in the article:
Create a folder called lib that stores all the components you want to bring to the other react app. Also define a file called index.js in this folder that exports these components.
Create a repo for the components on Github
Install Babel and build the dist folder.(npm install --save-dev #babel/core #babel/cli #babel/preset-env and npm install -save #babel/polyfill)
Add the following config file to the top-level folder of your project:
{
"presets": [
[
"#babel/env",
{
"targets": {
"edge": "17",
"firefox": "60",
"chrome": "67",
"safari": "11.1"
},
"useBuiltIns": "usage",
"corejs": "3.6.5"
}
],
"#babel/preset-react"
]
}
In package.json, replace the build script with the following: "build": "rm -rf dist && NODE_ENV=production babel src/lib --out-dir dist --copy-files";
Run the command npm run build
So this question is a follow up to my previous question:
How can different apps import from a shared components folder? react / react-native
So I've created my own npm module which I store all my components in. These components can be used by as many apps as I like. Because I will be making those components highly reusable.
But I still have stumbled upon a problem.
I have created a loading component which uses this library: #react-native-community/masked-view. This library needs to install a dependency inside /ios/Podfile. First I created this component inside one of the react-native projects.
yarn add #react-native-community/masked-view
..
success Saved 1 new dependency.
cd ios/
pod install
..
Installing RNCMaskedView (0.1.6)
Pod installation complete! There are 33 dependencies from the Podfile and 31 total pods installed.
'
So then I ran my code, and the Loading component works. Now I want to add this to the NPM module (that, again, I created myself) which will contain all my components.
So I go into /my-awesome-99-components/ which has its own package.json since it is a module which I will import in each project I'm working on.
In /my-awesome-99-components/
yarn add react react-native #react-native-community/masked-view
..
success Saved 1 new dependency.
// Created Loading.js - this is the loading component
yarn publish
..
In /react-native-project-1/
yarn add my-awesome-99-components
..
Done in 3.17s.
cd ios/
Pod install
..
This is where the problem comes up. Now the Podfile won't install the RNCMaskedView because apparently my module doesn't let the project know that it should install some packages inside the ios/Podfile.
Does anyone know why this happens, and what would be the best solution for this?
I appreciate all the help!
Have you tried adding a podspec file to your repo?
You can modify the podspec file from the masked-view package like
require 'json'
package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
Pod::Spec.new do |s|
s.name = "RNCMaskedView"
s.version = package['version']
s.summary = package['description']
s.authors = package['author']
s.platforms = { :ios => "9.0", :tvos => "9.0" }
s.source = { :git => "https://github.com/react-native-community/react-native-masked-view.git", :tag => "v#{s.version}" }
s.source_files = "node_modules/#react-native-community/masked-view/ios/**/*.{h,m}"
s.dependency 'React'
end
only change here would be the path of the source files
This is a typical issue with Podfile and overall React Native linking from dependencies with dependencies. react-navigation-stack had the same issue with #react-native-community/masked-view.
The only solution is to mark as #react-native-community/masked-view a peerDependency, so the user using your library knows that there might be another dependency needed, and install it separately. Your problem might be better answered by this answer.
I have a vue project with multiple clients. The clients all have similar components which I keep in a "common" folder:
clients
-- client1
---- ...
-- client2
---- ...
-- client3
---- ...
-- common
---- imports.js
---- ...
Right now each project has it's own package.json and node_modules, If I need a common dependency installed I just install it in "common" and import it in "common\imports.js" which is used by my clients.
I also have an alias in webpack "common": "../common" to import the common files.
It all works good but the problem is that some packages (like "vue", "vuex") exist in node_modules of "common" and in the clients and it's being loaded twice.
How can I add the common folder to my clients' node_modules so they won't duplicate versions of the same library?
I wrote how I linked all my clients to my common library in this question:
Webpack using wrong node_modules folder
And as for the duplicate library error, I wrote how I overcame it in the answer.
I am attempting to find a good way to use local modules in npm, or a way of structuring a large application so it can be bundled off into modules which may or may not be in a separate repository.
Each local module has it's own package.json and dependencies which are installed.
My requirements are that the modules are written in ES6 and only compiled as part of the main project being built (so I don't have lots of dependencies being indiependently built constantly).
Project structure
/root
/main-module
... main js files <- entry point
webpack.config.js
package.json
/module-1
... module 1 js files
package.json
/module-2
... module 2 js files
package.json
/module-3
... module 3 js files
package.json
I'm currently investigating using local modules via specifying a local file in my package.json like so:
...
"dependencies": {
"lodash": "^4.17.10",
"module-1": "../module-1",
"module-2": "../module-2",
"module-3": "../module-3",
"normalize.css": "^8.0.0"
}
...
You can see the whole project here: https://github.com/SamStonehouse/webpack-local-modules-test
I'm using webpack with the babel-loader which doesn't need any extra setup in order to use this form and even watches the module file for changes and rebuilds when they're complete which is amazing.
Issue: once this has built lodash is included in the built bundle 4 times over, one for each module which requires it, even though they all require the same version and all the sources are compiled at the same time.
I've tried using the splitChunkPlugin but to no avail
I've tried setting lodash as a devDependency in the local modules (this was something I didn't want to do but it didn't work anyway)
Does anyone have a solution for this?
Or an alternative way of bundling local modules in a similar fashion
Change each of the modules to have lodash as a peer dependency instead of a direct dependency. So in the package.json file, change this:
"dependencies": {
"lodash": "^4.17.5"
}
To:
"peerDependencies": {
"lodash": "^4.17.5"
}
I have done quite some search already. However, still having doubts about the 'main' parameter in the package.json of a Node project.
How would filling in this field help? Asking in another way, can I start the module in a different style if this field presents?
Can I have more than one script filled into the main parameter? If yes, would they be started as two threads? If no, how can I start two scripts in a module and having them run in parallel?
I know that the second question is quite weird. It is because I have hosted a Node.js application on OpenShift but the application consists of two main components. One being a REST API and one being a notification delivering service.
I am afraid that the notification delivering process would block the REST API if they were implemented as a single thread. However, they have to connect to the same MongoDB cartridge. Moreover, I would like to save one gear if both the components could be serving in the same gear if possible.
Any suggestions are welcome.
From the npm documentation:
The main field is a module ID that is the primary entry point to your
program. That is, if your package is named foo, and a user installs
it, and then does require("foo"), then your main module's exports
object will be returned.
This should be a module ID relative to the root of your package
folder.
For most modules, it makes the most sense to have a main script and
often not much else.
To put it short:
You only need a main parameter in your package.json if the entry point to your package differs from index.js in its root folder. For example, people often put the entry point to lib/index.js or lib/<packagename>.js, in this case the corresponding script must be described as main in package.json.
You can't have two scripts as main, simply because the entry point require('yourpackagename') must be defined unambiguously.
To answer your first question, the way you load a module is depending on the module entry point and the main parameter of the package.json.
Let's say you have the following file structure:
my-npm-module
|-- lib
| |-- module.js
|-- package.json
Without main parameter in the package.json, you have to load the module by giving the module entry point: require('my-npm-module/lib/module.js').
If you set the package.json main parameter as follows "main": "lib/module.js", you will be able to load the module this way: require('my-npm-module').
If you have for instance in your package.json file:
{
"name": "zig-zag",
"main": "lib/entry.js",
...
}
lib/entry.js will be the main entry point to your package.
When calling
require('zig-zag');
in node, lib/entry.js will be the actual file that is required.
As far as I know, it's the main entry point to your node package (library) for npm. It's needed if your npm project becomes a node package (library) which can be installed via npm by others.
Let's say you have a library with a build/, dist/, or lib/ folder. In this folder, you got the following compiled file for your library:
-lib/
--bundle.js
Then in your package.json, you tell npm how to access the library (node package):
{
"name": "my-library-name",
"main": "lib/bundle.js",
...
}
After installing the node package with npm to your JS project, you can import functionalities from your bundled bundle.js file:
import { add, subtract } from 'my-library-name';
This holds also true when using Code Splitting (e.g. Webpack) for your library. For instance, this webpack.config.js makes use of code splitting the project into multiple bundles instead of one.
module.exports = {
entry: {
main: './src/index.js',
add: './src/add.js',
subtract: './src/subtract.js',
},
output: {
path: `${__dirname}/lib`,
filename: '[name].js',
library: 'my-library-name',
libraryTarget: 'umd',
},
...
}
Still, you would define one main entry point to your library in your package.json:
{
"name": "my-library-name",
"main": "lib/main.js",
...
}
Then when using the library, you can import your files from your main entry point:
import { add, subtract } from 'my-library-name';
However, you can also bypass the main entry point from the package.json and import the code splitted bundles:
import add from 'my-library-name/lib/add';
import subtract from 'my-library-name/lib/subtract';
After all, the main property in your package.json only points to your main entry point file of your library.
One important function of the main key is that it provides the path for your entry point. This is very helpful when working with nodemon. If you work with nodemon and you define the main key in your package.json as let say "main": "./src/server/app.js", then you can simply crank up the server with typing nodemon in the CLI with root as pwd instead of nodemon ./src/server/app.js.
From the Node.js getting started documentation, it states;
An extra note: if the filename passed to require is actually a directory, it will first look for package.json in the directory and load the file referenced in the main property. Otherwise, it will look for an index.js.
For OpenShift, you only get one PORT and IP pair to bind to (per application). It sounds like you should be able to serve both services from a single nodejs instance by adding internal routes for each service endpoint.
I have some info on how OpenShift uses your project's package.json to start your application here: https://www.openshift.com/blogs/run-your-nodejs-projects-on-openshift-in-two-simple-steps#package_json