how to include webpack in in-browser Babel? - reactjs

I am newbie to React.js. For learning purpose just I created the login page which you can find here.
In my local project also, I used the CDN for babel and react, like below.
<script src="https://unpkg.com/react#latest/dist/react.js"></script>
<script src="https://unpkg.com/react-dom#latest/dist/react-dom.js"></script>
<script src="https://unpkg.com/babel-standalone#6.15.0/babel.min.js"></script>
I want to use one of the form validation plugin into this example. But when I tried to include this (as per the document)
import ValidateableForm from 'react-form-validate';
I am getting the following error.
Uncaught ReferenceError: require is not defined
I went through few posts and they said that I have to use webpack or Rollup or Browsify .I am not sure how to include this in to my current local project setup. Since I am not using npm (in learing I dont want to use npm)
I dont know how to include that plugin into my project
If it is already coming with external site , I cant able to figure
it out what is the issue.
Please help me to resolve the issue.

This is an old question, but at least currently, this is completely possible with conventional script tags. This article is very helpful for understanding development setup alternatives for React
In that article it details bringing in React, React-Dom, and Babel via script tags for development, like this (I'm linking to npm downloaded packages, but that isn't necessary):
<script src="/node_modules/react/umd/react.development.js"></script>
<script src="/node_modules/react-dom/umd/react-dom.development.js"></script>
<script src="/node_modules/#babel/standalone/babel.min.js"></script>
In my case, I needed to bring in the react-notification-system plugin:
<script src="/node_modules/react-notification-system/dist/react-notification-system.min.js"></script>
(Note the use of the compiled 'dist' version)
Once that was included I was able use it like this:
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.notificationSystem = new ReactNotificationSystem();
}
addNotification = event => {
event.preventDefault();
const notification = this.notificationSystem.current;
notification.addNotification({
message: 'Notification message',
level: 'success'
});
};
render() {
return (
<div>
<button onClick={this.addNotification}>Add notification</button>
<ReactNotificationSystem ref={this.notificationSystem} />
</div>
);
}
}
I had to look in the plugin's code to know that the name: ReactNotificationSystem would be available, much of the plugin documentation that you find is not written with this type of dev setup in mind, but it does work.

Related

How to import redux to angularjs 1.x app?

I was trying to use redux in an angular 1.x app. I added the scripts
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.8.3/angular.js"></script>
<script src="https://unpkg.com/ng-redux/umd/ng-redux.min.js"></script>
to my html head. Then I created a file just to test if things are working correctly:
angular.module("app", ["ngRedux"]).config(function ($ngReduxProvider) {
$ngReduxProvider.createStoreWith(
{
counterStateReducer: function (state, action) {},
},
[]
);
});
But when I run I get an error:
TypeError: Cannot read properties of undefined (reading 'combineReducers')
at Object.$get (ngRedux.js:92:18)
at Object.invoke (angular.js:5208:19)
...(other lines ommited by me)
I know that the error is from the file ngRedux.js specifically at this line _reducer = combineReducers(reducersObj); but I am new to JS and the docs don't say how to import this library other than by adding the scripts, so how can I fix it?
Turns out the dependencies scripts were wrong, these ones worked for me:
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.8.3/angular.js"></script>
<!-- Redux -->
<script src="https://unpkg.com/redux#latest/dist/redux.js"></script>
<!-- NgRedux -->
<script src="https://unpkg.com/ng-redux/umd/ng-redux.js"></script>
I got them from the examples page on the official github repos of ngRedux and redux.
Note: you may also need to declare type=module on these scripts if you get that import is not defined.

How do I get JSX supported in my application?

I have the following in my index.js file
class PersonProfileBadge extends React.Component {
constructor(props) {
super(props);
this.alias = this.props.alias;
}
render() {
return e(
'img',
{
src: `https://internal-cdn.foo.com/somepath/?uid=${this.alias}`,
className: 'profile_photo'
}
);
}
}
and it works when I render it like so
ReactDOM.render(
e(PersonProfileBadge, {'alias': 'stupidfatcat'}),
navProfilePicture
);
But I'm trying to get JSX support since it makes the code look generally much more readable
ReactDOM.render(
<PersonProfileBadge alias='stupidfatcat' />,
navProfilePicture
);
But I'm getting this error:
Uncaught SyntaxError: Unexpected token '<'
In my index.html I have the following imports
<script src="internalcdnpathto/static/react/react.production.min.js"></script>
<script src="internalcdnpathto/static/react-dom/react-dom.production.min.js"></script>
<script src="https://unpkg.com/#babel/standalone/babel.min.js"></script>
<script src="/static/index.js"></script>
Not entirely sure what I'm doing wrong or where to even get started.
You generally want to add a preprocessor in order to use JSX. The quickest way to try JSX in your project is to add this tag to your page:
<script src="https://unpkg.com/babel-standalone#6/babel.min.js"></script>
Now you can use JSX in any tag by adding type="text/babel" attribute to it. This approach is fine for learning and creating simple demos. However, it makes your website slow and isn’t suitable for production.
Read more in the official React docs.
You need babel to compile your code from JSX to javascript from this:
ReactDOM.render(
<PersonProfileBadge alias='stupidfatcat' />,
navProfilePicture
);
to that:
ReactDOM.render(
e(PersonProfileBadge, {'alias': 'stupidfatcat'}),
navProfilePicture
);
You should utilize a bundler like webpack so you parse your code everytime you change something, i'd suggest creating a project via create-react-app
or take a look at Babel Standalone

React onClick not working in any of my browsers, but for colleagues it does

I've created an onClick handler in a very simple React function component:
export default function MyButton() {
return (
<button
onClick={() => {
console.log('test');
}}
>
Button
</button>
);
}
Now the weird part: no matter what browser I use, the event is not firing. I've created such a component hundreds of times and everything was good, until now.
For everyone else this code works, as it was intended.
I cannot share the whole project or an example repository. It's really nothing but a simple React app you see everywhere.
What could be the reason for why it's not working on my system?
EDIT:
The error was somehow within yarn. I called webpack-dev-server -d source-map --mode=development for development and I am using "webpack-dev-server": "^4.0.0-beta.0". I think the cache could've gotten corrupted somehow.
To fix it, I removed my output directory and started the script with npm instead of yarn. This way it worked, even when I use yarn again.
I really don't know why this happened. Would be happy to know why.
I also faced the same issue and the reason of the issue (in my case , probably yours ) is HtmlWebpackPlugin, HtmlWebpack Plugin is adding a addition script tag of bundle in head tag of index.html.
my html
<html>
<head>
<title>my-react-app</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
htmlwebpackplugin generated html
<html>
<head>
<title>my-react-app</title>
<script defer src="bundle.js"></script></head>
<body>
<div id="root"></div>
<script src="bundle.js"></script>
</body>
</html>
because of this additional script tag, there was a problem in react (i read a post on reddit regarding to this problem and he also have multiple script of same bundle and he was having the same problem), i solved it by deleting my script tag, but we can use copywebpack plugin to just copy html. Or other solution is to configure htmlwebpackplugin suck a way that it will not inject any addition tags
...
new HtmlWebpackPlugin({
name: "index.html",
inject: false,
template: path.resolve(__dirname, "public/index.html"),
}),
...
Use named function instead of anonymous function. Named functions are very useful for identifying what functions caused errors during development as well as when retrieving logs from your users.
import React from "react";
export default function MyButton() {
const handleChange = () => {
console.log("test");
};
return <button onClick={handleChange}>Button</button>;
}
It is a good practice to name-all-functions for a better developer debugging (and development) experience which anonymous function does not provide.
For more clarification between Named and Anonymous function Learn the benefits of Named vs Anonymous function here
Try typing your function as React.FC.
Create a typescript (tsx) file and use the upcoming code:
import React from "react";
export const MyButton: React.FC = () => {
return (
<button
onClick={() => {
console.log("test");
}}
>
Button
</button>
);
};
Note that using this code, you are typing the component making sure that your function is typed as React.FunctionComponent.
Did you import this in your file, if not then add this tine on top
import React from 'react';

Gatsby with CDN reference

I'm trying to get bootstrap.css and Google fonts CDNs working in my Gatsby project.
There is no HTML file; just JavaScript files.
For bootstrap, I can npm install bootstrap and then import the min.css from that.
Trying to figure out how to get Amatic SC font from Google fonts; I have npm installed google-fonts-webpack-plugin.
I am using gatsby-node.js by adding:
const GoogleFontsPlugin = require("google-fonts-webpack-plugin")
exports.modifyWebpackConfig = ({ config, stage }) => {
config.plugin("google-fonts-webpack-plugin",new GoogleFontsPlugin(
{
fonts: [
{ family: "Amatic SC" }
]
}
),null)
};
However, I get the error below;
Invalid 'constructor' parameter. You must provide either a function or null
What am I doing wrong and how can I fix it?
Is there a way of referencing a CDN directly so rather than npm installing bootstrap, I could just reference its latest version?
You can include the font using typeface-amatic-sm from NPM, and in your JS do:
import 'typeface-amatic-sc'
Otherwise, can include scripts it in your </head> using helmet like:
<Helmet>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js"></script>
</Helmet>

referencing an amd module(arcgis) in webpack app

I'm building a react app with webpack and i need to incorporate arcgis maps into a react component. I have know idea how to bring this into my project. I've tried creating an arcgis directory with an index.js of the built javascript and trying to reference that:
import {Map} from 'arcgis/index'
That doesn't work. I then just tried to include the css/js script tags directly into my index.html but when I try to require them, like in the example, webpack obviously can't find them. Is there some way to tell webpack to ignore require calls in my src file so it gets handled by the browser? I'm trying and failing at doing the following:
import React from 'react'
export default class EsriMap extends React.Component {
componentDidMount() {
const _this = this
require(["esri/map", "dojo/domReady!"], function(Map) {
var map = new Map(_this.refs.map, {
center: [-118, 34.5],
zoom: 8,
basemap: "topo"
});
});
}
render() {
return (
<div ref="map"></div>
)
}
}
You may want to try this https://github.com/tomwayson/esri-webpack-babel .
This method is nice because it doesn't bog down the build. You pull in the ESRI Api from the CDN, and tell webpack that it's an external.
//Add this...
externals: [
// Excludes any esri or dojo modules from the bundle.
// These are included in the ArcGIS API for JavaScript,
// and its Dojo loader will pull them from its own build output
function (context, request, callback) {
if (/^dojo/.test(request) ||
/^dojox/.test(request) ||
/^dijit/.test(request) ||
/^esri/.test(request)
) {
return callback(null, "amd " + request);
}
callback();
}
],
//And this to you output config
output: {
libraryTarget: "amd"
},
When your app loads you bootstrap you webpack modules using Dojo in a script tag.
<!-- 1. Configure and load ESRI libraries -->
<script>
window.dojoConfig = {
async: true
};
</script>
<script src="https://js.arcgis.com/4.1/"></script>
<!-- Load webpack bundles-->
<script>
require(["Angular/dist/polyfills.bundle.js", "Angular/dist/vendor.bundle.js", "Angular/dist/app.bundle.js"], function (polyfills, vendor, main) { });
</script>
I've got it working with an Angular 2 App I'm working on. The only downside is I haven't yet got the unit tests to run right using Karma. I've only been working on that a few hours now.. Hope to have a solution to the testing issue soon.
#getfuzzy's answer will work well as long as you don't need to lazy load the ArcGIS API (say for example only on a /map route).
For that you will want to take the approach I describe in this answer
This blog post explains why you need to use one of these two approaches and explains how they work as well as the pros/cons of each.
I think you can try using bower version of esrijsapi. Doc link

Resources