NPM + React + TypeScript with AMD modules - reactjs

I'm trying to setup dev environment for app written in typescript using react.
I alreally have existing typescript code that compiles to ES5 and AMD modules.
I would like to avoid any js transpilation in the browser. Please notice, that I don't need to use babel to transpile jsx, since typescript compiles tags into React.createElement in tsx files.
I've done the usual:
npm install react -save
npm install react-dom -save
npm install typescript -save-dev
npm install typings -save-dev
typings install react --ambient --save
typings install react-dom --ambient --save
now, I have two questions:
how to correctly import/require the react and react-dom in my tsx files which compiles to ES5/AMD?
currently I'm just doing this:
/// <reference path="../../typings/browser/ambient/react-dom/index.d.ts" />
/// <reference path="../../typings/browser/ambient/react/index.d.ts" />
export class MyComponent extends __React.Component<any, {}> {
public render() {
return (
<h1>MyCompoentnt</h1>
);
}
}
however the compilations fails with error TS2304: Cannot find name 'React'.
how to include react.js and react-dom.js in my app? I quess some transpilation or browserification will be needed. Or should I just and them to index.html?
<script src="scripts/react.js"></script>
<script src="scripts/react-dom.js"></script>
<script src="scripts/require.min.js" data-main="scripts/app"></script>
here is my package.json:
{
"name": "myhtmlapp",
"version": "1.0.0",
"description": "react test app",
"main": "index.js",
"dependencies": {
"jquery": "^2.2.3",
"react": "^15.0.0",
"react-dom": "^15.0.0"
},
"devDependencies": {
"browser-sync": "^2.11.2",
"typescript": "^1.8.9",
"typings": "^0.7.12"
},
"scripts": {
"watch:typescript": "tsc --p ./appscripts -w",
"watch:css": "browser-sync start --server --files .wwwroot/css/*.css",
"compile": "tsc --p ./appscripts",
"test": "echo \"Error: no test specified\" "
},
"keywords": [],
"author": "",
"license": "ISC"
}
here is entire app: https://onedrive.live.com/redir?resid=51A46BBA4E9EF07E!263323&authkey=!AKQ6FqjE2W2YVBo&ithint=file%2czip

I am pretty sure there a several ways to do this. Below I am posting my way of getting things you have mentioned play together:
To import react I use standard import, like this:
import * as React from 'react';
import * as ReactDOM from 'react-dom';
export class MyComponent extends React.Component<any, any>
{
//...
}
To 'inculde' react into the application I use systemjs as module loader (due to some reasons that goes beyong the question I cant use browserify, but pretty sure it can be used to do the same). You will need to install systemjs via npm. Then instruct it to know where to look for react. To do this put the following script in your index.html:
<script src="systemjs/dist/system.src.js"></script>
<script>
System.config({
baseURL: './lib',
paths: {
"react*": 'react/dist/react-with-addons'
}
});
System.defaultJSExtensions = true;
</script>
Where react/dist/react-with-addons is a path (without '.js' extension) to the dist of react-with-addons.js. And systemjs/dist/system.src.js - path to systemjs dist.
Hope this helps.

Related

React Native - Get an error when using a custom component that I made (Error: undefined Unable to resolve module <MyModule>)

I made a custom component called "react-native-weekly-calendar",
and I'm trying to publish it to open source community,
but I want to test it first. When I try to test it by npm install --save ../<component_name>, it throws an error.
My directory structure:
- react-native-weekly-calendar (folder)
- index.js
- package.json
- src (folder)
- Locale.js
- Style.js
index.js:
import React, { useState, useEffect, useRef } from 'react';
import { Text, View, ScrollView, TouchableOpacity, TouchableWithoutFeedback, Modal, Platform, ActivityIndicator } from 'react-native';
import PropTypes from 'prop-types';
import moment from 'moment/min/moment-with-locales';
import DateTimePicker from '#react-native-community/datetimepicker';
import { FontAwesome } from 'react-native-vector-icons';
import { applyLocale, displayTitleByLocale } from './src/Locale';
import styles from './src/Style';
const WeeklyCalendar = props => {
...
}
export default WeeklyCalendar;
package.json:
{
"name": "react-native-weekly-calendar",
"version": "0.1.0",
"description": "Weekly Calendar component for React Native",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/codeinjuice/react-native-weekly-calendar.git"
},
"keywords": [
"react",
"reactnative",
"react-native",
"react-native-component",
"calendar",
"weeklycalendar",
"weekly-calendar",
"scheduler",
"datepicker",
"date-picker"
],
"author": "codeinjuice",
"license": "MIT",
"bugs": {
"url": "https://github.com/codeinjuice/react-native-weekly-calendar/issues"
},
"homepage": "https://github.com/codeinjuice/react-native-weekly-calendar#readme",
"dependencies": {
"moment": "^2.24.0",
"prop-types": "^15.5.7",
"#react-native-community/datetimepicker": "~2.1.0",
"react-native-vector-icons": "~6.6.0"
},
"devDependencies": {
"#babel/core": "^7.0.0",
"metro-react-native-babel-preset": "^0.58.0",
"react": "~16.9.0",
"react-native": "0.61.4"
}
}
Here is how I tested with the files above:
$ npx react-native init sample
$ cd sample
$ npm install --save ../react-native-weekly-calendar
$ vim App.js
Then I added import WeeklyCalendar from 'react-native-weekly-calendar'; in App.js.
Finally I ran
$ npx react-native run-ios
In the simulator, I get this error:
Unable to resolve module 'react-native-weekly-calendar' from 'App.js':react-native-weekly-calendar could not be found within the project.
Did I set my dependency settings wrong in package.json???
I don't understand why it keeps saying the component is not found when it's clearly inside of node_modules folder.
Any suggestions are welcomed!
Edit: I upgraded react-native from 0.60.* to 0.61.4 and it worked with npm as well.
Original answer
I used $ yarn add ../react-native-weekly-calendar
instead of $ npm install --save ../react-native-weekly-calendar and it worked.

Yarn workspace, react, monorepo issue with conflict library version

I'm experimenting with yarn workspace monorepo. It is consisting of a TestProject created with create-react-app, and a SharedLib1 which is created with create-react-library. TestProject imports code from SharedLib1. The problem being, TestProject uses react-scripts 3.3.0 which is dependent on babel-jest ^24.9.0, while SharedLib1 uses react-scripts-ts ^2.16.0 which is dependent on babel-jest 22.4.4. When running yarn start in TestProject, it complains:
The react-scripts package provided by Create React App requires a dependency:
"babel-jest": "^24.9.0"
Don't try to install it manually: your package manager does it automatically.
However, a different version of babel-jest was detected higher up in the tree:
/monoRepo/node_modules/babel-jest (version: 22.4.4)
I could disable the error by setting SKIP_PREFLIGHT_CHECK=true in TestProject or manually upgrade the react-scripts inside SharedLib1, but I'd like to know if there's a better way of handling this.
myMonorepo
-web
-SharedLib1
-package.json
-TestProject
-package.json
-package.json
Package.json of myMonoRepo:
{
"name": "my-mono-repo",
"version": "0.1.0",
"private": true,
"workspaces": [
"web/*"
],
"nohoist": [
"**/babel-jest",
"**/babel-jest/**"
]
}
Package.json of myMonoRepo:
{
"name": "test-proj",
"version": "0.1.0",
"private": true,
"dependencies": {
...
"shared-lib-1": "^1.0.0"
}
}
And the test code App.tsx:
import React from 'react';
import TestComp from 'shared-lib-1';
import './App.css';
const App: React.FC = () => {
return (
<div className="App">
<TestComp text={'aaa'}/>
Learn React
</div>
);
}
export default App;
There is a babel-jest 24.9.0 inside the node_modules of TestProj and another 22.4.4 inside the node_modules of myMonoRepo
This is very similar, if not the same, to an issue opened on the GH repo for create-react-app and you may find additional information there.
That said, you might try moving babel-jest to a devDependency instead of a package dependency. If that does not work, you might try Selective dependency resolutions, where you can force your project to a specific version of babel-jest -
"resolutions": {
"babel-jest": "^24.9.0",
"shared-lib-1": "^1.0.0"
}

How to put FontAwesome icons in react?

I created one React project and I am trying to put FontAwesome icons in react project, but it is showing some syntax errors so help me to resolve this issue.
This is package.json file
{
"name": "icons",
"version": "0.1.0",
"private": true,
"dependencies": {
"#fortawesome/fontawesome-svg-core": "^1.2.25",
"#fortawesome/free-brands-svg-icons": "^5.11.2",
"#fortawesome/free-regular-svg-icons": "^5.11.2",
"#fortawesome/free-solid-svg-icons": "^5.11.2",
"#fortawesome/react-fontawesome": "^0.1.7",
"react": "^16.11.0",
"react-dom": "^16.11.0",
"react-scripts": "3.2.0"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
This is index.js file
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import { FontAwesomeIcon } from '#fortawesome/react-fontawesome'
import { faCoffee } from '#fortawesome/free-solid-svg-icons'
const element = <FontAwesomeIcon icon={faCoffee} />
ReactDOM.render(<App />, element, document.getElementById('root'));
serviceWorker.unregister();
I am getting error like this Error: Target container is not a DOM element.
You got a little confused with rendering your React code into the DOM.
React.render() takes 2 parameters, the first is your React element, and the second is the target in your index.html file, whereas you have added 3 parameters, hence the error.
You would need to create a React stateless functional component in this scenario, called App:
function App() {
return (
<div>
<FontAwesomeIcon icon={faCoffee} />
</div>
)
}
And now the jsx component is now available as per your existing code, so you can use:
ReactDOM.render(<App />, document.getElementById('root'));
Sources: https://reactjs.org/docs/components-and-props.html
If you're not rendering the icon in App, you can render it by itself directly:
const element = <FontAwesomeIcon icon={faCoffee} />
ReactDOM.render(<div>{element}</div>, document.getElementById('root'));
But as Kraylog pointed out you are not using the ReactDOM.render method correctly. You can read about it here.
As to your "I am getting error like this Error: Target container is not a DOM element." Error, you need to make sure that in your index.html file there is a div with an id of root like such <div id="root"></div>. ReactDOM (which is imported from import ReactDOM from "react-dom";) has a render method on it that converts your React code to plain JavaScript and then inserts it into the real DOM. The render method ONLY NEEDS TWO arguments to work, however a third argument can be used as a callback function like such ReactDOM.render(element, container, () => console.log("Application Mounted in DOM")), but I've never seen anyone use the callback function. You can read more about it here on the official document website ReactDOM.render, or you can watch a pretty decent video on it on YouTube here
Here are some further tips on using the icons in a reusable manner.
Follow these steps taken from the #fortawsome npmjs registry
Install the necessary packages for the cause
$ npm i --save #fortawesome/fontawesome-svg-core
$ npm i --save #fortawesome/free-solid-svg-icons
$ npm i --save #fortawesome/react-fontawesome
$ yarn add #fortawesome/fontawesome-svg-core
$ yarn add #fortawesome/free-solid-svg-icons
$ yarn add #fortawesome/react-fontawesome
Install some MORE of the free stuff in that they were nice enough to provide :)
$ npm i --save #fortawesome/pro-solid-svg-icons
$ npm i --save #fortawesome/pro-regular-svg-icons
$ npm i --save #fortawesome/pro-light-svg-icons
$ npm i --save #fortawesome/pro-duotone-svg-icons
Install even more if you are a paid pro member
$ npm i --save #fortawesome/pro-solid-svg-icons
$ npm i --save #fortawesome/pro-regular-svg-icons
$ npm i --save #fortawesome/pro-light-svg-icons
$ npm i --save #fortawesome/pro-duotone-svg-icons
Usage
Now, finally to the good part of actually using it in an application.
I'm going to create a wrapper component around it, so that it's easy to reuse the icon/component later on, and in order to do this start by creating a file called CoffeeIcon.js, and in that file put in something along the lines of the following:
import React from "react";
import { FontAwesomeIcon } from "#fortawesome/react-fontawesome";
import { faCoffee } from "#fortawesome/free-solid-svg-icons";
import PropTypes from "prop-types";
const CoffeeIcon = props => {
return (
<React.Fragment>
{props.labelText ? <label>{props.labelText}</label> : null}
<FontAwesomeIcon
icon={faCoffee}
style={props.styles}
id={props.id}
className={props.className}
/>
</React.Fragment>
);
};
CoffeeIcon.propTypes = {
labelText: PropTypes.string,
id: PropTypes.string,
className: PropTypes.string,
styles: PropTypes.object
};
export default CoffeeIcon;
If you plan on using PropTypes for type checking and validation then add it to your application like such:
yarn add prop-types or npm i prop-types
And Finally, back in your component where you desire to use it, just do the following:
import it and place it just below your other import statements:
import CoffeeIcon from "../Components/CoffeeIcon";
Drop in the component where you desire:
<CoffeeIcon
styles={{ color: "maroon" }} // optional
id={"coffee-wrapper-id" || null} // optional
className={"coffee-wrapper-class" || null} // optional
labelText={"Coffee Icon"} // optional
/>
You're done and can now EASILY reuse it!

Module not found: Can't resolve 'bootstrap/dist/css/bootstrap.css' in 'C:\Users\test\counter-app\src'

I'm new to react js. I'm trying to create a component. For that I've installed bootstrap (version 4.1.1) which is successfully installed.
Then I imported the same in index.js and while reloading the page (localhost:3000) I got the error msg:
Module not found:
Can't resolve 'bootstrap/dist/css/bootstrap.css' in 'C:\Users\test\counter-app\src'
My index.js:
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import * as serviceWorker from "./serviceWorker";
import "bootstrap/dist/css/bootstrap.css";
ReactDOM.render(<App />, document.getElementById("root"));
serviceWorker.unregister();
My package.json :
{
"name": "counter-app",
"version": "0.1.0",
"private": true,
"dependencies": {
"react": "^16.8.4",
"react-dom": "^16.8.4",
"react-scripts": "2.1.8"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": [
">0.2%",
"not dead",
"not ie <= 11",
"not op_mini all"
]
}
Please help me to fix this.
Change import path to bootstrap.min.css like this:
import 'bootstrap/dist/css/bootstrap.min.css';
This occurs either because the installation of a library wasn't successful, i.e. bootstrap had an issue installing within your node_modules directory, or your reference to the library within your code is incorrect. Can you verify that your bootstrap installation was correct by looking within your node_modules for a bootstrap folder?
This would be at <base_path>/node_modules/bootstrap where <base_path> is your project's root directory location. For you I believe the absolute path is the following:
C:\Users\test\counter-app\src\node_modules\bootstrap
If you don't see the bootstrap directory please do the following:
npm i -S bootstrap
as this will save bootstrap as dependency for your project. Your reference to bootstrap within index.js looks fine: import 'bootstrap/dist/css/boostrap.css'; With that being said, a lot of bootstrap's features depend on the following libraries: popper.js, and jquery. So once you get your installation issue resolved you have to install these modules as well and reference them appropriately within your index.js. Something along the lines of:
Install modules:
npm i -S popper.js
npm i -S jquery
index.js
import 'jquery/dist/jquery.js';
import 'popper.js/dist/umd/popper.js';
import 'boostrap/dist/js/bootstrap.js';
Hopefully that helps!
Using bootstrap like that is not really recommended. You should look into react-bootstrap. You would need to run:
npm install react-bootstrap bootstrap
and then:
import Button from 'react-bootstrap/Button';
// or less ideally
import { Button } from 'react-bootstrap';
Check out their documentation for more.
I had the same problem but managed to solve it using these steps:
Remove the node_modules folder
Install bootstrap by running npm install bootstrap
Install other packages by running npm install.
Beware of confusing 'boostrap' with 'bootsrap'
Theese, install different packages:
$ npm install boostrap
$ npm install bootstrap
I was requiring the second. Because of that, I've got question's error.

React Storybook Fails on Demo

I'm attempting to use React Storybook in a project that already has an extensive Webpack 2 config. I started the Storybook following the basic steps:
npm i -g #storybook/cli
getstorybook
When I run yarn storybook, it breaks on the JSX of the demo component:
ERROR in ./stories/index.jsx
Module parse failed: /Users/alexanderhadik/project/web/node_modules/#storybook/react/node_modules/babel-loader/lib/index.js??ref--0!/Users/alexanderhadik/project/web/stories/index.jsx Unexpected token (9:55)
You may need an appropriate loader to handle this file type.
| import { Button, Welcome } from '#storybook/react/demo';
|
| storiesOf('Welcome', module).add('to Storybook', () => <Welcome showApp={linkTo('Button')} />);
|
| storiesOf('Button', module)
# ./.storybook/config.js 4:2-23
# multi ./node_modules/#storybook/react/dist/server/config/polyfills.js ./node_modules/#storybook/react/dist/server/config/globals.js ./node_modules/webpack-hot-middleware/client.js?reload=true ./.storybook/config.js
Since I didn't start this project originally using create-react-app - do I need to modify the Storybook webpack config to enable JSX?
This might to be a problem with Storybook not replicating webpack babelrc behaviour exactly.
In my case, I had an empty (just {}) .babelrc file with all the important react/jsx plugins defined in webpack.config.js. Storybook read the .babelrc instead of using the babel settings in webpack.config.js.
Deleting the .babelrc solved that issue.
in my case, i didnt have a .babelrc at all -- i used the entry "babel" in the package.json. when running the storybook in this project, the babel entry wasnt there. i added it and things magically started working.
{
"name": "root",
"private": true,
"devDependencies": {
"#storybook/addon-actions": "^4.1.11",
"#storybook/addon-links": "^4.1.11",
"#storybook/addons": "^4.1.11",
"#storybook/react": "^4.1.11",
...
},
"dependencies": {},
"scripts": {
"storybook": "start-storybook -p 6006",
"build-storybook": "build-storybook"
},
"babel": {
"presets": [
"#babel/preset-env",
"#babel/preset-react"
]
}
}
i hope this helps someone.

Resources