webpack babel and react simple example fails - reactjs

I am trying webpack with React and Babel. I created a simple example:
components.jsx:
import React from 'react';
import ReactDOM from 'react-dom';
import { render } from 'react-dom'
class Hello extends React.Component {
render() {
return <h1>Hello</h1>
}
}
ReactDOM.render(<Hello/>, document.getElementById('test'));
export default Hello;
index.js:
import Hello from "components.jsx";
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Webpack, React and Babel example</title>
</head>
<body>
<div> </div>
<div id="test"> </div>
<script src="bundle.js"> </script>
</body>
</html>
webpack.config.js:
var path = require('path');
var webpack = require('webpack');
module.exports = {
entry: './index.js',
output: { path: __dirname, filename: 'bundle.js' },
module: {
loaders: [
{
test: /\.jsx?$/,
loader: 'babel',
exclude: /node_modules/,
query: {
presets: ['es2015', 'react']
}
}
]
}
};
I also installed all the necessary modules: babel-loader, babel-core babel-preset-es2015 babel-preset-react, react, react-dom.
However, when I typed "webpack" in this current folder, I always got error message:
ERROR in ./index.js Module not found: Error: Cannot resolve module
'components.jsx' in
It is such a simple example and I must make a huge dumb mistake. But I just cannot find it.
Thanks
Derek

When you try to import a module by name, it's expected to be found under node_modules. That's probably not where you want it to be though, so you should import it via (a relative) path instead.
import Hello from "./components.jsx";
If the index.js and components.jsx files share a folder, the above will work. If they don't then you need to change ./ to point to the correct location.

As I understood, index.js and components.jsx are located in the same folder, if it is true, path should be the following
import Hello from "./components.jsx";

Related

Loading react component from url

I want to import the react component that I have bundled using web pack.
I am able to complete the task by copying it locally to that folder and then importing it like
import Any from '.dist/index'
and it is working fine.
But what I want to do is uploading this index.js file to somewhere for example Amazon s3. Now I am not able to import the component in the same way as mentioned above.
My webpack.config.js file, I have used to export my bundled component generated by webpack that I am using in another project by copying the index.js and index.css file is
var path = require("path");
var HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
entry: "./src/index.js",
output: {
path: path.resolve(__dirname, "dist"),
filename: "index_bundle.js",
libraryTarget: "commonjs2"
},
module: {
rules: [
{ test: /\.(js)$/, use: "babel-loader" },
{ test: /\.css$/, use: ["style-loader", "css-loader"] }
]
},
externals: {
react: "commonjs react"
},
mode: "production",
plugins: [
new HtmlWebpackPlugin({
template: "./src/index.html"
})
]
};
I want to import the component from file url uploaded to s3.
you can do what you are describing with micro apps. A micro app is basically nothing more than a component that is lazy loaded into the host application from a url at runtime. There is no need to install or import the component at design time. There is a library available that lets you do this with a HOC component.
import React from 'react';
import ReactDOM from 'react-dom';
import MicroApp from '#schalltech/honeycomb-react-microapp';
const App = () => {
return (
<MicroApp
config={{
View: {
Name: 'redbox-demo',
Scope: 'beekeeper',
Version: 'latest'
}
}}
/>
);
});
export default App;
You can find more information on how it works here.
https://github.com/Schalltech/honeycomb-marketplace
This is not the way you should package and deploy your React components. AWS S3 is a bucket for storage of files to serve on the web. It's purpose is not to share code files through projects.
You should publish your React components to a registry such as NPM. After you publish your package to the registry, you should be able to install the package into your app as a dependency by doing something like npm install my_package.

Module not found: Error: Can't resolve './components/PropTest1' - React JS

I have the following directory structure for my REACTJS app
/ReactJs
-dist
--app
-node_modules
-src
--app
--app/Hello.jsx
----components
----components/PropTest1.jsx
-src/main.html
package.json
webpack.config.js
My Hello.jsx code is:
import React, { Component } from 'react';
import ReactDOM, { render } from 'react-dom';
import PropTest1 from "./components/PropTest1"
var dest = document.querySelector('#container');
class Hello extends Component {
render() {
return (
<div>
<h1>Hello World</h1>
<PropTest1 />
</div>
);
}
}
render(<div><Hello /></div>, dest);
and PropTest1.jsx code is
import React, { Component } from 'react';
class PropTest1 extends Component {
render() {
return (
<div>
<p> My name is no one</p>
</div>
);
}
}
export default PropTest1;
and my webpack.config.js is
var webpack = require('webpack');
var path = require('path')
module.exports = {
mode: "development",
entry: path.resolve(__dirname, 'src') + "/app/Hello.jsx",
output: {
path: path.resolve(__dirname, 'dist') + "/app",
filename: 'bundle.js',
publicPath: '/app/'
},
module: {
rules: [{
test: /\.jsx?/,
include: path.resolve(__dirname,'src'),
loader:'babel-loader'
}]
},
resolve: {
extensions: ['*', '.js', '*.jsx']
}
};
When I am doing
npm run build
I am getting
Module not found: Error: Can't resolve './components/PropTest1'
What looks wrong with the above project, please check.
EDIT: I have added the resolve configuration in my webpack.config.js
The issue here is that you didn't specify the file extension (.jsx) while importing your component (import PropTest1 from "./components/PropTest1")
To solve this, you need to update Webpack config and add a resolve property, which will make Webpack look for files named (in your example) PropTest1.js, PropTest1.jsx until it finds the right one ...
module.exports = {
mode: "development",
entry: path.resolve(__dirname, 'src') + "/app/Hello.jsx",
...,
resolve: {
extensions: ['', '.js', '.jsx']
}
};
Currently,it is looking for components directory within app directory so, you need to use ..
import PropTest1 from "../components/PropTest1"
I found the issue with name of the file. While doing import I had
import Login from "./login";
While name of the file was Login.js
Running on the local machine was not giving error but when I was running on linux, it was giving me a similar error as above.

React is undefined (Cannot read property 'createElement' of undefined)

I'm trying to convert a working ReactJS application into TypeScript, and I've had some issues getting anything to work properly.
import React from "react";
import * as ReactDOM from "react-dom";
import Application from "./Application";
console.log(React); // undefined
ReactDOM.render(
<Application/>, window.document.getElementById("application-wrapper")
);
The console throws an error at <Application />
When I import react like this, react loads:
import * as React from "react";
However, I want to use the import statement using the default export, because I import React using this import syntax in all the existing components:
import React, {Component} from "react";
export default class Whatever extends Component<Props, State> {
...
}
My tsconfig.json file contains this line allowing synthetic defaults:
"allowSyntheticDefaultImports": true
My webpack.config.js file:
let path = require("path");
let config = {
entry: "./src/main.tsx",
output: {
path: path.resolve(__dirname, "build"),
filename: "bundle.js"
},
devtool: "source-map",
resolve: {
extensions: [".ts", ".tsx", ".js", ".jsx"]
},
module: {
loaders: [
{
test: /\.tsx?$/,
loader: "ts-loader",
exclude: /node_modules/
}
]
}
};
module.exports = config;
Not sure what I'm missing here....
Set "esModuleInterop": true instead.
In your typescript configuration i.e tsconfig.json "esModuleInterop": true and "allowSyntheticDefaultImports": true. this will allow you to import CommonJS modules in compliance with es6 modules spec.
Module resolution is a little complicated because Typescript does it different than Babel and Webpack. If you want to know more you can check this comment: https://github.com/Microsoft/TypeScript/issues/5565#issuecomment-155216760
Going back to your problem, allowSyntheticDefaultImports tells Typescript to allow default imports from modules with no default export but the emitted code doesn't change. Because of that, you need to move the responsibility of resolving modules to Webpack or Babel.
To achieve that set moduleResolution module to ES6es2015 in the Typescript config file.
The pipeline will look like this:
TS Code => (TypescriptCompiler) => JS Code with ES6 modules => (Webpack modules resolver) => JS Code

Webpack not bundling node modules imported in dependency JS files

I'm using Webpack to bundle my ReactJS application.
helloworld.js
import React from 'react';
export default class HelloWorld extends React.Component {
render() {
return <h2>Hello {this.props.name}!</h2>;
}
}
index.js
import ReactDOM from 'react-dom';
import HelloWorld from './helloworld';
ReactDOM.render(<HelloWorld name="World" />,
document.getElementById('container'));
webpack.config.js
module.exports = {
entry: './index.js',
output: 'bundle.js',
module: {
loaders: [
{
test: /(\.js|\.jsx)/,
loader: 'babel-loader',
exclude: /node_modules/,
query: {
presets: ['es2015', 'react']
}
}
]
}
};
When I run webpack-dev-server --progress --colors I'm getting an error in the browser "React is not defined" but if I import React directly in the index.js then the error not comes. Why Webpack is not including React in the bundle if it is referenced in the helloworld.js file?
Well webpack only tries to bundle up the individual modules by reading the dependencies in it and resolving them to render a particular element. Now while bundling
ReactDOM.render(<HelloWorld name="World" />,
document.getElementById('container'));
ReactDOM tries to execute React.createElement(_Helloworld2.default, { name: 'World' }), document.getElementById('app') function which requires React as a dependency that is not present in your index.js file so it gives an error and solve the issue when you import React in your index.js file. I hope I was able to explain and my answer helps you.
You are missing import React from 'react'; statement.
You will need it every time You write some JSX in a file, because it is transformed into React.createElement(..) function calls.

ReactDOM.unmountComponentAtNode: Uncaught ReferenceError: ReactDOM is not defined

I practice react
I met this error : Uncaught ReferenceError: ReactDOM is not defined
when type ReactDOM.unmountComponentAtNode(document.body) on chrome console
Please help me check the problem
I try the code on JSbin and works well,so I think it's webpack problem,but I have no idea .
And I notice there are many way write React.render part when I google ,what's the difference?? which one is correct??
React.render(<App name='Vipul' />,document.body);
ReactDOM.render(<App name='Vipul' />,document.body);
React.renderComponents(<App name='Vipul' />,document.body);
Here is my code:
main.jsx
import React from 'react';
import ReactDOM from 'react-dom';
console.log('Start')
var App = React.createClass({
render: function(){
console.log('render');
return <h1 onClick={this.toggleState}>Hello</h1>
},
componentWillUnmount: function(){
//在console執行 ReactDOM.unmountComponentAtNode(document.body)
console.log('componentWillUnmount');
},
toggleState: function(){
this.setState({status: !this.state.status})
}
});
ReactDOM.render(<App name='Vipul' />,document.body);
webpack.config.js
var WebpackNotifierPlugin = require('webpack-notifier');
module.exports = {
entry: "./src/main.js",
output: {
filename: "./dist/bundle.js"
// filename: "./public/dist/bundle.js"
},
plugins: [
new WebpackNotifierPlugin()
],
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: "babel-loader",
query: {
presets: ['es2015', 'react']
}
}
]
},devtool: 'source-map'
};
ReactDOM available since 0.14.0, so
ReactDOM.render(<App name='Vipul' />,document.body);
should be fine. If you are using lower version of React then React.render
Secondly it is recommended not to render on document.body, rather create a div inside the body and render there.
I met this error : Uncaught ReferenceError: ReactDOM is not defined
when type ReactDOM.unmountComponentAtNode(document.body) on chrome console
when you use Webpack the React and ReactDOM will not be available globally. So, this code will only work inside the file/module where you have imported React & ReactDOM.
There is only one way to render React component in browser and it's this one:
ReactDOM.render(<App />, target);
All other are deprecated - renderComponent is renamed to render and moved from react package to react-dom package.
Also, do you need to call unmountComponentAtNode in your componentWillUnmount lifecycle method? In your particular case it does not make sense. React will unmount component for you - for free.
componentWillUnmount usually serves for clearing timeouts/intervals and/or canceling async operations (Promises, closing connections, ...);
Removing that call won't harm you, try it out.

Resources