Common js modules in react native - javascript

Is it possible to make use of common js modules with react-native? The use case is sharing logic between a mobile and web version of a react project.

Ok, I'm new to this too but I think I've figured out how to include js code. I didn't have to add anything to the standard react native installation.
Create a Library of code:
//library.js
exports.foo = function() {
//Do stuff here
return "Here";
}
Import into another js file:
var lib = require("./library.js");
var myString = lib.foo();
I found the info from this blog post:
http://0fps.net/2013/01/22/commonjs-why-and-how/

Related

Using react component in a different application

What I'm trying to achieve is:
Building simple react app - the template is create react app
Copying output file (main.*.js)
Pasting it in another react app
Importing render function to render the first app into the second one
Simple react app code:
interface Props {
greeting: string;
}
export module AppModule {
export const sendGreetings = ({ greeting }: Props) => {
return `Hello ${greeting}`;
};
}
Builder file code:
!function(){"use strict";var n;(n||(n={})).sendGreetings=function(n){var e=n.greeting;return"Hello ".concat(e)}}();
Trying to import this file into another app I get this error:
File 'c:/vscode/test-react-app/test-sc-react/src/main.783e0281.js' is not a module.ts(2306)
Which is obvious. I changed the output file manually to:
export function initApp(){"use strict";var n;(n||(n={})).sendGreetings=function(n){var e=n.greeting;return"Hello ".concat(e)}};
It works but the only function that I'm able to access is initApp but not sendGreetings
I've been struggling with this for a while now and I would really appreciate any helpful suggestions
I used Bit.dev for my components that are used across multiple applications & there is an article regarding your issue
https://blog.bitsrc.io/sharing-react-components-across-multiple-applications-a407b5a15186
I think it would help.
🎯 Solution #1
You can use an iframe to inject your react app:
<iframe src='path-to-your-app.html'/>
🎯 Solution #2
Go with micro-frontend architecture approach. Where a front-end app is decomposed into individual, semi-independent "microapps" working loosely together.
As a starting point, you can try npx create-mf-app instead of the CRA.
You can include your js code directly on run time. You can use window.addEventListener to load js/css incoming from an outside source. You just have to append that js to your document on the load event.

How to use imported third-party js (not addon/npm package) in controller/component?

I have put my js files eva.min.js/feather.min.js and so on in vendor dir, then I imported them in ember-cli-build.js app.import('vendor/eva.min.js'). But how to use it?
I tried something like import eva from 'eva'/'eva.min'/'eva.min.js' or import Eva from 'eva'; and so on, but it doesn't work.
app.import('vendor/eva.min.js');
app.import('vendor/bootstrap.min.js');
app.import('vendor/feather.min.js');
app.import('vendor/popper.min.js');
app.import('vendor/jquery-slim.min.js');
app.import('vendor/swipe.js');
import Swipe from 'swipe';
Console usually gives me the could not find the module error.
And I don't have a deep background in programming, so I would highly appreciate if you explained the problem as simple as possible.
UPD: I found all js code as npm package (it happens that the js files weren't third-party)
https://www.npmjs.com/package/feather
https://www.npmjs.com/package/popper.js
https://www.npmjs.com/package/jquery-slim
https://www.npmjs.com/package/swipe
https://www.npmjs.com/package/bootstrap
https://www.npmjs.com/package/eva-icons
But all your responses were helpful. Anyway in the near future I expect to use third-party libraries.
A quick way is to use scriptjs and it allows you to load any javascript into your component in the following way: (I am using Yammer as an example)
import $scriptjs from 'scriptjs';
componentDidUpdate() {
//script loader
setTimeout(function(){
$scriptjs('https://c64.assets-yammer.com/assets/platform_embed.js',
() => {
window.yam.connect.embedFeed(YammerHelper.loadComments());
});
}, 1000);
}
You should get the idea how to consume it. Check their docs with lots of examples.
This is not the best solution. But one way of using the third party js is,
1) say you have a function in your js file vendor/third-party.js
someFunction = function (element) {
...
console.log("works")
};
2) Then import it in your ember-cli-build.js
...
app.import('vendor/third-party.js');
...
3) After importing restart your server.
Use the function directly in your controller/component as
window["someFunction"]
Unless the JavaScript library being used explicitly supports the import X from 'y' syntax then when you import in the build using the app.import syntax you just use it in your app just as the plugin documentation describes.
So for Swipe you would do the following.
Based on this documentation: https://github.com/thebird/Swipe
// ember-cli-build.js
app.import('myswipe.js`);
// component.js
/* global Swipe */ // This silences the linter from throwing errors...
classNames: ['swipe'],
didInsertElement() {
this._swipe = Swipe(this.element, {
option1: option1
});
}
// component.hbs
<div class='swipe-wrap'>
{{yield}}
</div>
This codes creates a component to control your swipe plugin.
This code would create a swipe object and isolate it to the component.
Again when you use the app.import you are just loading the library on boot. The library does whatever it says it will do in the docs. Sometimes they register a global object, sometimes they dont.

React Native imports not working after upgrade

Hi I've been in charge of an old React-Native iOS project and I need to upgrade its React-Native from 0.25.1 to 0.48.0 but I'm running into a lot of compiler issues and can't figure out how to update the code.
I have an index.ios.js file that looks like this:
var ReactNative = require('react-native');
var ResumeIns = require('./resume_ins_controller');
ReactNative.AppRegistry.registerComponent('ResumeInsController', () => ResumeIns.Navigation);
A resume_ins_controller.js in the root folder that looks like this:
var React = require('react');
var EntryManager = require('./entry_manager.js');
class ResumeInsNavigation extends React.Component {
//....
}
and an entry_manager.js in the root folder that looks like this:
class EntryManager {
//....
}
module.exports = EntryManager;
This code worked OK before the upgrade, but now I get this error:
Super expression must either be null or a function, not undefined
and the stack trace points to this line:
module.exports = EntryManager;
Does anyone know how to get this code working for React-Native 0.48?
There's been a ton of changes since 0.25.1. Knowing how painful updates can get, I'd suggest either:
In case of a very complex app: to update RN version by version with the help of release notes, and rn-diff if necessary.
In case of a fairly simple app: to start a new RN project from scratch, and move the app's logic over there.
Either way it would be a good idea to move to ES2015 imports for clarity on named vs default imports as the issue that you're describing is likely caused by the way things are imported, see v0.25.1 deprecations + a link to codemod that may help.
Good luck!

Building Flux/React application without NodeJs EventEmitter

Hi I'm trying to build a Flux/React application with a go-lang back-end. I have been following a tutorial I found here. But I have a problem when building the store. In the tutorial something like this is used to create a base for the store.
var ProductStore = _.extend({}, EventEmitter.prototype, {...});
The problem I have is I do not have access to the EventEmitter library which I understand is a Nodejs lib? Is there an alternative I can use?
You can use NodeJS libraries in the browser! Take a look at browserify.
First some code:
// index.js
var EventEmitter = require("events").EventEmitter;
var ProductStore = function() {};
ProductStore.prototype = new EventEmitter;
Then you run browserify on it:
browserify index.js > bundle.js
Also worth a look is WebPack which does the same thing. (but has some additional features)
Well if you are using the flux implementation given by Facebook (https://github.com/facebook/flux), you can actually extends their FluxStore class which comes with a build in eventEmitter.
The only thing if you want to do that is you must use es6 classes (and use babel to transpile to es5).
The good thing about it is that you don't have to implement the addListener removeListener and emitChange methods, and that's very DRY :)
With this solution, your stores will end up looking like that :
var FluxStore = require("flux/utils").Store,
thing;
class ThingStore extends FluxStore {
getThing() {
return thing;
}
__onDispatch(payload) {
//your code
}
}

Unit testing on "react + react-route" stack

I've read many recommendations of how it's possible to render routed via react-router components, but I still can't to make it work. I tried to find it using github codebase search, still no luck. And at this point all I need is one working example.
Here is my boilerplate project, but maybe it's not important. I just want to see some react-route unit-testing working example.
I got mine working after I found the super-secret hidden react-router testing guide.
Instead of using Object.assign to create a router stub, I used sinon.js so I could create better stub functions that return the appropriate values for my tests.
EDIT: Went back to look again at your boilerplate and saw that your stub router is borrowed from the same example. Sorry. So where exactly did you get stuck?
EDIT-AGAIN: I'm not using Jest, so here are the other pieces that I needed to solve the testing puzzle:
If you're using browserify, and want to test in plain mocha (without having to build), you'll need to hack require to compile your jsx for you:
var fs = require("fs");
var reactTools = require("react-tools");
require.extensions[".jsx"] = function(module, filename) {
var jsxContent = fs.readFileSync(filename).toString();
var jsContent = reactTools.transform(jsxContent);
return module._compile(jsContent, filename);
};
You need a fake DOM. JSDOM is just plain terrible. I got it working using domino instead.
var domino = require("domino");
global.window = domino.createWindow();
global.document = global.window.document;
//Set the NODE_ENV so we can call `render`.
//Otherwise we get an error from react about server rendering. :(
process.env.NODE_ENV = "test";
Then you can require your components in through the stub-router, and render your components into DOM nodes using React.render():
var MyComponent = fakeRouter(require("./MyComponent.jsx"));
var component = React.render(
< MyComponent / > ,
document.body
);
node = component.getDOMNode();
//I used `zepto-node` and `chai-jq` to assert against my components
The (possbily new in v4) way of doing this is to wrap the component you're testing in the MemoryRouter provided by react-router.
import {MemoryRouter} from 'react-router-dom';
import {render} from 'react-dom';
render(<MemoryRouter>
<YourComponent>
</MemoryRouter>, node, () => {});

Categories