Using React in only one part of a multi-page application - javascript

I already have a multi-page website which currently has two tools built with Node.js, Express, MongoDB, vanilla JS. Each tool has its own web page. I want to add a third tool on my website. This new tool will be built using React.
The main "App" component should have a "Top", "Body" and "Bottom" component. However, when I try to import these components into the App file, the content does not show.
App component:
import React from 'react';
import Top from './Top/Top.js';
import Body from './Body/Body.js';
import Bottom from './Bottom/Bottom.js';
class App extends React.Component {
render() {
return (
<div>
<Top />
<Body />
<Bottom />
</div>
);
}
}
ReactDOM.render(
<App />,
document.getElementById('app')
);
Top component:
import React from 'react';
class Top extends React.Component {
render() {
return (
<div>
<div>Top goes here</div>
</div>
);
}
}
export default Top;
Body component and Bottom component are similar to Top.
When I import the components into the App, the content does not show. However, if I do not import and write all the components in one file, the content shows.
I would like to separate the components into separate files as shown above for easier readibility and navigation.
Furthermore, when I try to import the components into the main App component, I also get this error in the Chrome web developer console:
How can I separate my components into separate files and import them correctly where needed without errors?
Thanks!
Edit: this is my webpack configuration
const path = require('path');
const autoprefixer = require('autoprefixer');
module.exports = {
entry: './public/js/birdApp/birdApp.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
chunkFilename: '[id].js',
publicPath: ''
},
resolve: {
extensions: ['.js', '.jsx']
},
module: {
rules: [
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/
},
{
test: /\.css$/,
exclude: /node_modules/,
use: [
{ loader: 'style-loader' },
{
loader: 'css-loader',
options: {
modules: {
localIdentName: "[name]__[local]___[hash:base64:5]",
},
sourceMap: true
}
},
{
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: () => [
autoprefixer({})
]
}
}
]
},
{
test: /\.(png|jpe?g|gif)$/,
loader: 'url-loader?limit=10000&name=img/[name].[ext]'
}
]
}
};
Edit2: my package.json file
"name": "rstools",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "env-cmd -f ./config/dev.env nodemon src/app.js --ext js,hbs,css"
},
"author": "",
"license": "ISC",
"dependencies": {
"babel-cli": "^6.26.0",
"babel-preset-react-app": "^3.1.2",
"body-parser": "^1.19.0",
"env-cmd": "^10.1.0",
"express": "^4.17.1",
"hbs": "^4.1.1",
"mongodb": "^3.5.7",
"mongoose": "^5.9.11",
"osrs-json-api": "^1.4.1",
"react": "^16.13.1",
"react-dom": "^16.13.1"
},
"devDependencies": {
"#babel/core": "^7.10.4",
"#babel/preset-env": "^7.10.4",
"#babel/preset-react": "^7.10.4",
"autoprefixer": "^9.8.4",
"babel-loader": "^8.1.0",
"css-loader": "^3.6.0",
"html-loader": "^1.1.0",
"html-webpack-plugin": "^4.3.0",
"postcss-loader": "^3.0.0",
"style-loader": "^1.2.1",
"webpack": "^4.43.0",
"webpack-cli": "^3.3.12",
"webpack-node-externals": "^2.3.0"
}
}

Related

Vue-router only loading the base path in an application created without using vue cli [duplicate]

This question already has answers here:
Vue Router return 404 when revisit to the url
(20 answers)
Closed 2 years ago.
I am creating a vue application from scratch without using vue cli. Problem is I'm unable to load any other route aside from the base '/' route. Please inspect the code and help where it might have gone wrong.
routes.js file
import Vue from 'vue'
import Router from 'vue-router'
import Home from './HomePage.vue'
import ErrorPageComponent from './ErrorPage.vue'
import AccountsPage from './AccountsPage.vue'
Vue.use(Router);
export default new Router({
mode: 'history',
routes: [
{
path: '/',
name: 'home',
component: Home,
},
{
path: '/accounts',
name: 'accounts',
component: AccountsPage,
},
{
path: '/error',
name: 'error',
component: ErrorPageComponent,
},
{
path: '*',
redirect: '/error'
}
]
})
App.vue file.
<template>
<div id="app">
<router-view />
</div>
</template>
main.js file code.
import Vue from 'vue'
import App from './App.vue'
import router from './pages/routes'
new Vue({
router,
render: h => h(App),
}).$mount('#app')
Code for package.json
{
"name": "vue_without_cli",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"clean": "rimraf dist",
"build": "npm run clean && webpack --mode production",
"serve": "webpack-dev-server --mode development"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"file-loader": "^6.0.0",
"i": "^0.3.6",
"style-loader": "^1.2.1"
},
"devDependencies": {
"#babel/core": "^7.11.1",
"#babel/preset-env": "^7.11.0",
"animate": "^1.0.0",
"axios": "^0.19.2",
"babel-loader": "^8.1.0",
"bootstrap": "^4.5.2",
"css-loader": "^4.2.1",
"html-webpack-plugin": "^4.3.0",
"rimraf": "^3.0.2",
"vue": "^2.6.11",
"vue-loader": "^15.9.3",
"vue-router": "^3.4.2",
"vue-style-loader": "^4.1.2",
"vue-template-compiler": "^2.6.11",
"vuex": "^3.5.1",
"webpack": "^4.44.1",
"webpack-cli": "^3.3.12",
"webpack-dev-server": "^3.11.0"
}
}
Webpack config file.
const HtmlWebpackPlugin = require('html-webpack-plugin');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
module.exports = {
entry: './src/main.js',
module: {
rules: [
{ test: /\.js$/, use: 'babel-loader' },
{ test: /\.vue$/, use: 'vue-loader' },
{ test: /\.css$/, use: [ 'style-loader', 'css-loader' ] },
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
}),
new VueLoaderPlugin(),
]
};
Babel.config.js
module.exports = {
presets: ['#babel/preset-env'],
}
Same routing configuration in my other Vue projects which I created using vue-cli seem to work with ease.
I reckon I might have missed something related to routing while setting up my project from scratch instead of using vue-cli. Please help me with this.
In comment, I notice that you are already find a solution which are remove the history mode.
Anthor solution is add a simple catch-all fallback route to your server.For example, both of http://example.com and http://example.com/accounts and the all of route path should return the same index.html page.I think the HTML5 History Mode chapter of offical document will help you to config server properly.

React component error: expected a string or a class/function but got undefined

I am getting the following error in a create-react-app. Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
The app is currently a super-basic - it just imports and renders one single component:
import './App.css';
import { PasswordInput } from 'gg-react-test-lib';
function App() {
return (
<div className="App">
<PasswordInput />
</div>
);
}
export default App;
I am therefore assuming that the problem is with my component library that I am importing the PasswordInput component from. I am installing it from NPM.
It has an index.js file like:
import Radio from './Radio/Radio';
export { PasswordInput, Radio }```
Those component files themselves do a default export at the bottom of the file e.g.:
`export default PasswordInput;`
I have a pretty minimal webpack.config.js file in my component library repo:
```const TerserPlugin = require('terser-webpack-plugin');
const path = require('path');
module.exports = {
mode: 'production',
entry: './src/index.js',
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /(node_modules|bower_components)/,
loader: "babel-loader"
}
]
},
output: {
path: path.resolve(__dirname, "dist/"),
filename: 'bundle.js'
},
optimization: {
minimizer: [new TerserPlugin()]
},
};
My package.json:
{
"name": "gg-react-test-lib",
"version": "1.0.7",
"description": "",
"main": "dist/bundle.js",
"module": "src/index.js",
"author": "",
"license": "ISC",
"dependencies": {
"clsx": "^1.0.4",
"node-sass": "^4.13.0",
"react": "^16.12.0",
"react-dom": "^16.12.0"
},
"scripts": {
"build": "webpack"
},
"devDependencies": {
"#babel/cli": "^7.7.5",
"#babel/core": "^7.7.5",
"#babel/preset-react": "^7.7.4",
"babel-loader": "^8.0.6",
"webpack": "^4.41.3",
"webpack-cli": "^3.3.10"
}
}
.babelrc file:
{
"presets": [
"#babel/preset-react"
]
}

Module not found: Can't resolve 'ReactDOM'

I have two react projects:
A React Component (built with webpack)
A React test project (create-react-app)
When importing 1 into 2 compilation fails with
Module not found: Can't resolve 'ReactDOM'
Webpack config for the component project:
var path = require('path');
module.exports = {
entry: './src/index.tsx',
output: {
path: path.resolve(__dirname, 'build'),
filename: 'index.js'
},
devtool: "source-map",
resolve: {
extensions: [".ts", ".tsx", ".js", ".json"]
},
module: {
rules: [
{ test: /\.tsx?$/, loader: "awesome-typescript-loader" },
{ test: /(\.css$)/, loaders: ['style-loader', 'css-loader'] },
{ test: /\.(png|woff|woff2|eot|ttf|svg)$/, loader: 'url-loader?limit=100000' },
{ enforce: "pre", test: /\.js$/, loader: "source-map-loader" }
]
},
externals: {
'react': 'commonjs react',
'react-dom': 'ReactDOM'
}
};
I have tried removing the externals section above so that ReactDOM is bundled but that doesn't seem to solve the issue either. Ideally React shouldn't need to be bundled. ReactDOM isn't an import in the component project.
package.json for the component project:
{
"name": "component",
"version": "0.1.0",
"main": "build/index.js",
"dependencies": {
"react-grid-layout": "^0.16.0",
"react-redux": "^5.0.6",
"redux": "^3.7.2",
"semantic-ui-css": "^2.2.12",
"semantic-ui-react": "^0.75.1"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "webpack --watch",
"build": "webpack"
},
"devDependencies": {
"#types/react": "^16.0.20",
"#types/react-dom": "^16.0.2",
"#types/react-grid-layout": "^0.16.0",
"#types/react-redux": "^5.0.12",
"awesome-typescript-loader": "^3.3.0",
"react-dom": "^16.0.0",
"react": "^16.0.0",
"babel-cli": "^6.24.1",
"babel-core": "^6.24.1",
"babel-loader": "^7.0.0",
"babel-plugin-transform-object-rest-spread": "^6.23.0",
"babel-plugin-transform-react-jsx": "^6.24.1",
"babel-preset-env": "^1.5.1",
"css-loader": "^0.28.7",
"file-loader": "^1.1.5",
"source-map-loader": "^0.2.3",
"style-loader": "^0.19.0",
"typescript": "^2.6.1",
"webpack": "^2.6.1",
"url-loader": "^0.6.2"
}
}
In my test project I have
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import Component from 'component'
The test project builds fine if I remove the dependency on Component. As soon as I import Component the full error message is:
./node_modules/component/build/index.js
Module not found: Can't resolve 'ReactDOM' in '/mnt/c/Users/a8345/ws/test/node_modules/component/build'
As I am using typescript I have #types/react-dom installed. If I have import ReactDOM from 'react-dom' I get ./src/index.tsx (2,8): error TS1192: Module '"/mnt/c/Users/a8345/ws/test/node_modules/#types/react-dom/i‌​ndex"' has no default export.. import * as ReactDOM from 'react-dom' works fine in the test project unless I try and import my own component.
I suspect this is a build issue as opposed to an import issue, how should I best configure this to ensure that the component uses ReactDOM from the host project rather than bundling it into the component?
Thanks in advance
Try
externals: {
'react': {commonjs: 'react'},
'react-dom': {commonjs: 'react-dom'}
}
https://webpack.js.org/configuration/externals/#object
Webpack is not resolving .js files. Add this to your webpack.config.js.
resolve: {
extensions: [".ts", ".tsx", ".js", ".jsx"]
},
Via this answer.

React router page rendering issue

Learning React right now tried to use react-router for page routing, but because of some reasons I always see the blank page instead of rendered component.
I'm using webpack-dev-server as dev server.
Looking for your help and advices
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link href="dist/css/app.css">
</head>
<body>
<div id="root"></div>
<script src="dist/js/app.js"></script>
</body>
</html>
app.js
import React from 'react';
import ReactDOM from 'react-dom';
import {Router, Route, IndexRoute, hashHistory } from "react-router";
import App from './Pages/App';
import Archives from './Pages/Archives';
import Features from './Pages/Features';
import Settings from './Pages/Settings';
const app = document.getElementById('root');
// ReactDOM.render(<Layout/>, app);
ReactDOM.render(
<Router history={hashHistory}>
<Route path="/" component={App}>
<IndexRoute component={Features}/>
<Route path='archives' component={Archives}/>
<Route path='settings' component={Settings}/>
</Route>
</Router>
, app);
App component
import React from 'react';
import { Link } from 'react-router'
export default class App extends React.Component{
render(){
return (
<div>
<h1>App</h1>
<Link to="/archives">Archives</Link>
<Link to="/settings">Settings</Link>
{this.props.children}
</div>
);
}
}
package.json
{
"name": "Planner",
"version": "1.0.0",
"description": "",
"main": "webpack.config.js",
"dependencies": {
"babel-core": "^6.24.1",
"babel-loader": "^7.0.0",
"babel-plugin-add-module-exports": "^0.2.1",
"babel-plugin-react-html-attrs": "^2.0.0",
"babel-plugin-transform-class-properties": "^6.24.1",
"babel-plugin-transform-decorators-legacy": "^1.3.4",
"babel-preset-es2015": "^6.24.1",
"babel-preset-react": "^6.24.1",
"babel-preset-stage-0": "^6.24.1",
"history": "^4.6.1",
"react": "^15.5.4",
"react-dom": "^15.5.4",
"react-router": "^4.1.1",
"webpack": "^2.4.1",
"webpack-dev-server": "^2.4.4"
},
"devDependencies": {},
"scripts": {
"dev": "webpack-dev-server --content-base --inline --hot",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
UPDATED:
Webpack config
var debug = process.env.NODE_ENV !== "production";
var webpack = require('webpack');
var path = require('path');
module.exports = {
context: path.join(__dirname, "src"),
devtool: debug ? "inline-sourcemap" : null,
entry: "./js/app.js",
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
loader: 'babel-loader',
query: {
presets: ['react', 'es2015', 'stage-0'],
plugins: ['react-html-attrs', 'transform-decorators-legacy', 'transform-class-properties'],
}
}
]
},
output: {
path: path.resolve(__dirname, 'dist/js'),
filename: "app.js",
publicPath: '/dist/js/'
},
plugins: debug ? [] : [
new webpack.optimize.DedupePlugin(),
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.optimize.UglifyJsPlugin({ mangle: false, sourcemap: false }),
],
};

after add component link error: Uncaught SyntaxError: Unexpected token export

i create test react project. Add modules and my packege.json look like:
{
"name": "untitled",
"version": "0.1.0",
"private": true,
"devDependencies": {
"babel-preset-node5": "^12.0.1",
"react-scripts": "0.9.5"
},
"dependencies": {
"babel-preset-stage-0": "^6.22.0",
"history": "^4.6.1",
"react": "^15.4.2",
"react-dom": "^15.4.2",
"react-native": "^0.42.3",
"react-router": "^4.0.0",
"react-router-config": "^1.0.0-beta.1",
"react-router-dom": "^4.0.0",
"react-router-native": "^4.0.0",
"webpack": "^2.2.1",
"webpack-dev-server": "^2.4.2"
},
"scripts": {
"start": "react-scripts start",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject",
"build": "babel input.js -o compiled.js"
}
}
and webpack.config.js
var config = {
entry: './index.js',
output: {
path:'/',
filename: 'index.js',
},
devServer: {
inline: true,
port: 8080
},
module: {
loaders: [
{
test: /\.js?$/,
exclude: /node_modules/,
loader: 'babel',
query: {
presets: ['es2015', "node5", "stage-1", 'react', "stage-0"]
}
}
]
}
};
module.exports = config;
in my component i import component Link from react-router-native and after this adding react show error 'Uncaught SyntaxError: Unexpected token export' but if i delete this string project work well. it's not the only component in the module, i can add any components like Promt, Route or Router. Why it's not work with Link?
This is code where error reproduced
import React from 'react';
import { Route, Router } from 'react-router';
import { Promt } from 'react-router';
import { Link } from 'react-router-native';
import logo from '../../logo.svg';
import './App.css';
class App extends React.Component {
render() {
return (
<div className="App">
<div className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h2>Welcome to React</h2>
</div>
<p className="App-intro">
To get started, edit <code>src/App.js</code> and save to reload.
</p>
</div>
);
}
}
export default App;
You need to update the regular expression for the test value in your web pack config to be test: /(\.js|\.jsx)$/
Right now you are telling webpack to only run .js files through babel loader, but you aren't telling it to also run .jsx files through babel loader.

Categories