So here is what my code looks like
---------index.js-----
var React =require('react');
var ReactDOM =require('react-dom');
var App=require('../components/App');
ReactDOM.render(<App />, document.getElementById('app'));
---------App.js-----
var React = require('react');
class App extends React.Component {
render() {
return(
<div>
<h1>HI wassup</h1>
</div>
);
}
}
export default App;
---------package.json-----
{
"name": "views",
"version": "1.0.0",
"description": "learning",
"main": "index.js",
"scripts": {
"start": "webpack-dev-server --mode development --hot && webpack"
},
"author": "vinayak",
"license": "ISC",
"dependencies": {
"react": "^16.4.2",
"react-dom": "^16.4.2"
},
"devDependencies": {
"babel-core": "^6.26.3",
"babel-loader": "^7.1.5",
"babel-preset-react": "^6.24.1",
"html-webpack-plugin": "^3.2.0",
"unminified-webpack-plugin": "^2.0.0",
"webpack": "^4.16.5",
"webpack-cli": "^3.1.0",
"webpack-dev-server": "^3.1.5"
}
}
---------webpackconfig-----
const HTMLWebpackPlugin=require('html-webpack-plugin');
const webpack=require('webpack');
const UnminifiedWebpackPlugin = require('unminified-webpack-plugin');
const HTMLWebpackPluginConfig=new HTMLWebpackPlugin({
template: '../../views/index.hbs',
filename:'index.hbs'
});
module.exports={
entry:__dirname + '/app/index.js',
module:{
rules:[
{
test:/\.js$/,
exclude:/node_modules/,
loader:'babel-loader'
}
]
},
plugins: [
new UnminifiedWebpackPlugin(),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify('development')
}
})
],
devtool: 'source-map',
output:{
filename:'app.js',
path:__dirname + '../../public/javascripts/'
},
devServer:{
inline:false
}
};
------------------folder structure-------------
|react
|node modules
|components
|App.js
|app
|index.js
Everything works fine but when I am execting the app in browser I get the react error and gives a link which displays the following.
"Element type is invalid: expected a string (for built-in components)
or a class/function (for composite components) but got: object."
You're mixing up require, and import / export.
Since you're running webpack, all of your React code (and anything that gets transpiled by babel via webpack) should stick to using import/export. require should only be used in places like js that's directly run by node.
In your index.js, change all the requires to imports and see if that helps.
In the file index.js, you should change your code like this:
var App = require('../components/App').default;
or use import
import App from '../components/App';
I recommend using a unified usage. You can import/export or module.exports/require.
Related
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.
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"
]
}
Trying to learn React Router, get blocker when try to route the login page.
I guess it might be:
Problem in Webpack config
Skipped some meta tag
Need to change domain in Windows Host file
Dependencies problem in package.json
General info: All actions are performed locally. No server or custom domain. Just classic localhost:3000.
Steps to reproduce:
Adding manually /login to http://localhost:3000
Error:
Refused to execute inline script because it violates the following Content Security Policy directive: "default-src 'self'". Either the 'unsafe-inline' keyword, a hash ('sha256-GBZpdGedoBaq6YBC2+5oO7Dc8WC1XJ5EUI5Md05Lls8='), or a nonce ('nonce-...') is required to enable inline execution. Note also that 'script-src' was not explicitly set, so 'default-src' is used as a fallback.
Screen:
login page error
For more visibility here is the github repository - Project link
Webpack.config.js:
var webpack = require('webpack');
var path = require('path');
const BrowserSyncPlugin = require('browser-sync-webpack-plugin');
module.exports = {
entry: './src/index.js',
output: {
path: path.join(__dirname, 'dist'),
filename: 'bundle.js'
},
watch: true,
module: {
rules: [
{
use: 'babel-loader',
test: /\.js$/,
exclude: /node_modules/
},
{
test: /\.scss$/,
use: [
"style-loader",
"css-loader",
"sass-loader"
]
},
{
test: /\.(png|jp?g|gif|svg)$/,
use: [
{
loader: "url-loader",
options: { limit: 40000}
},
'image-webpack-loader'
]
}]
},
plugins: [
new BrowserSyncPlugin({
host: 'localhost',
port: 3000,
historyApiFallback: true,
files: ['./dist/*.html'],
server: { baseDir: ['dist'] }
})
]
};
App.js
import React from "react";
import { BrowserRouter, Route, Redirect, Switch } from "react-router-dom";
import Home from './components/Home/Home';
import Login from './components/Login/Login';
export default () => (
<BrowserRouter>
<Switch>
<Route exact path="/" component={Home} />
<Route path="/login" component={Login}/>
</Switch>
</BrowserRouter>
);
Login.js:
import React, {Component} from 'react';
import './Login.scss'
class Login extends React.Component {
render() {
return(
<div className="container2">
<h1>Login Page</h1>
</div>
)
}
}
export default Login;
package.json:
{
"name": "upstar_music",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "webpack",
"dev": "webpack-dev-server --progress --colors",
"start": "webpack && npm run dev"
},
"author": "",
"license": "ISC",
"dependencies": {
"faker": "^3.1.0",
"lodash": "^4.17.2",
"react": "15.4.1",
"react-dom": "15.4.1",
"react-input-range": "^0.9.2",
"react-redux": "^4.4.6",
"react-router": "^3.0.0",
"react-router-dom": "^4.2.2",
"redux": "^3.6.0",
"redux-form": "^6.3.2",
"redux-thunk": "^2.1.0"
},
"devDependencies": {
"axios": "^0.18.0",
"babel-core": "^6.17.0",
"babel-loader": "^6.2.0",
"babel-plugin-transform-class-properties": "^6.24.1",
"babel-preset-env": "^1.1.4",
"babel-preset-react": "^6.16.0",
"browser-sync": "^2.24.5",
"browser-sync-webpack-plugin": "^2.2.2",
"css-loader": "^0.26.1",
"extract-text-webpack-plugin": "^3.0.2",
"image-webpack-loader": "^4.3.1",
"node-fetch": "^2.1.2",
"node-sass": "^4.9.0",
"sass-loader": "^7.0.3",
"style-loader": "^0.13.1",
"url-loader": "^1.0.1",
"webpack": "2.2.0-rc.0",
"webpack-dev-server": "^2.11.2"
}
}
Index.js:
import React, {Component} from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import '../style/style.scss';
ReactDOM.render(<App />, document.getElementById('root'));
Content Security Policy (CSP) is giving the violation simply because the CSP does not allow unsafe-inline in the Script src. For React, simply adding the hash (SHA) might not work as React simply load the script (DOM) once, when you navigate to other pages, React simply throws you "Sha-...". Another method you might look into is nonce by providing dynamic nonce. You might be able achieve from what these guys had mentioned https://stackoverflow.com/a/49890126/2875928
I was also facing the same problem, if you are using webpack simply add a new key to modules.exports named devServer as
devServer:{ historyApiFallback: true }
sharing my webpack config with devServer for reference
my working webpack configuration
for the production, if you are using nginx you can do the configuration to server same html for all requests with path being handled by react on client side.
For a new project, I started using rollup to bundle a UI library and consume that library in a react application. I'm also using yarn workspaces for the internal dependency management between the UI library and the web app.
When I try to use the UI library in my web app, the import returns undefined and throws the "cannot get from undefined" error.
TypeError: Cannot read property 'NavBar' of undefined
[0] at App (C:/Users/user/dev/project/packages/project-web/src/pages/App.jsx:9:6)
The webapp code:
import React from 'react';
import {NavBar} from 'project-ui';
const App = () => (
<div>
<NavBar/>
<div>App component!x</div>
</div>
);
root package.json:
{
"name": "project",
"version": "1.0.0",
"private": true,
"workspaces": [
"packages/*"
]
}
UI package.json:
{
"name": "project-ui",
"version": "1.0.0",
"main": "dist/project-ui.cjs.js",
"jsnext:main": "dist/project-ui.es.js",
"module": "dist/project-ui.es.js",
"files": ["dist"],
"scripts": {
"build": "rollup -c"
},
"peerDependencies": {
"react": "16.3.2",
"react-dom": "16.3.2"
},
"devDependencies": {
"babel-core": "6.26.3",
"babel-plugin-external-helpers": "6.22.0",
"babel-preset-env": "1.6.1",
"babel-preset-react": "6.24.1",
"babel-preset-stage-2": "6.24.1",
"rollup": "0.60.0",
"rollup-plugin-babel": "3.0.4",
"rollup-plugin-commonjs": "9.1.3",
"rollup-plugin-node-resolve": "3.0.0",
"rollup-plugin-replace": "2.0.0",
"rollup-plugin-uglify": "4.0.0"
}
}
web app package.json:
{
"name": "project-web",
"version": "1.0.0",
"scripts": {
"build": "webpack --colors --display-error-details --config=webpack/webpack.dev.js",
"dev": "concurrently --kill-others \"npm run dev:start\"",
"dev:start": "node ./server/index.js"
},
"dependencies": {
"babel-polyfill": "^6.26.0",
"express": "^4.16.3",
"react": "^16.3.2",
"react-dom": "^16.3.2",
"project-ui": "1.0.0"
},
"devDependencies": {
"babel-core": "^6.26.3",
"babel-eslint": "^8.2.3",
"babel-loader": "^7.1.4",
"babel-plugin-add-module-exports": "^0.2.1",
"babel-plugin-dynamic-import-node": "^1.2.0",
"babel-plugin-transform-runtime": "^6.23.0",
"babel-preset-env": "^1.6.1",
"babel-preset-react": "^6.24.1",
"concurrently": "^3.5.1",
"eslint": "^4.19.1",
"eslint-loader": "^2.0.0",
"eslint-plugin-react": "^7.7.0",
"piping": "^1.0.0-rc.4",
"webpack": "^4.6.0",
"webpack-cli": "^2.0.15",
"webpack-dev-middleware": "^3.1.3",
"webpack-dev-server": "^3.1.3",
"webpack-hot-middleware": "^2.22.1",
"webpack-node-externals": "^1.7.2"
}
}
rollup config:
import resolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import babel from 'rollup-plugin-babel';
import replace from 'rollup-plugin-replace';
import { uglify } from 'rollup-plugin-uglify';
import pkg from './package.json'
const FORMATS = {
UMD: 'umd',
ES: 'es',
CJS: 'cjs'
};
const allowedFormats = [FORMATS.UMD, FORMATS.ES, FORMATS.CJS];
const bundle = (fileFormat, {format, minify}) => {
if (!allowedFormats.includes(format)) {
throw new Error(`Invalid format given: ${format}`);
}
const shouldMinify = minify && format === FORMATS.UMD;
const externals = format === FORMATS.UMD
? Object.keys(pkg.peerDependencies || {})
: [
...Object.keys(pkg.dependencies || {}),
...Object.keys(pkg.peerDependencies || {})
];
return {
input: 'src/index.js',
output: {
file: fileFormat.replace('{format}', shouldMinify ? `${format}.min` : format),
format,
name: 'project-ui',
exports: 'named',
globals: {
react: 'React',
'prop-types': 'PropTypes'
}
},
external: externals,
plugins: [
resolve({ jsnext: true, main: true }),
commonjs({ include: 'node_modules/**' }),
babel({
exclude: 'node_modules/**',
}),
format === FORMATS.UMD
? replace({'process.env.NODE_ENV': JSON.stringify(shouldMinify ? 'production' : 'development')})
: null,
shouldMinify ? uglify() : null
].filter(Boolean)
};
};
export default [
bundle('dist/project-ui.{format}.js', {format: FORMATS.UMD, minify: true}),
bundle('dist/project-ui.{format}.js', {format: FORMATS.CJS}),
bundle('dist/project-ui.{format}.js', {format: FORMATS.ES})
];
the actual generated code from rollup:
import React from 'react';
var NavBar = function NavBar() {
return React.createElement(
'header',
null,
'nav bar'
);
};
module.exports = exports['default'];
export { NavBar };
The original navbar:
import React from 'react';
const NavBar = () => (
<header>
nav bar
</header>
);
export default NavBar;
index.js:
export { default as NavBar} from './NavBar/NavBar';
.babelrc:
{
"presets": [
["env", {
"loose": true,
"modules": false,
"targets": {
"browsers": ["last 2 versions"]
}
}],
"react",
"stage-2"
],
"plugins": [
"transform-runtime",
"add-module-exports",
"external-helpers"
]
}
The generated rollup code looks to be ok, so I'm thinking this is a yarn issue, but I'm not sure. Any help would be appreciated!
Regards
Cornel
The problem must be in the way you are transpilling the code with babel/rollup. I have a live example in how your code should look in an online babel:
The generated code for me is:
import React from 'react';
const NavBar = () => React.createElement(
'header',
null,
'nav bar'
);
export default NavBar; // first define default and then we assign export['default']
module.exports = exports['default'];
Observe that in this code we first assign export default to the desired value and then we assign export['defaults'] (when I debug your example I get that export['default'] is undefined, hence you get the error Cannot read property 'NavBar' of undefined [0], since you are passing undefined to exports.
This is done by the plugin 'add-module-exports', that is kind of necessary if you really need module.exports (that shouldnt be needed unless NodeJS or some RequireJS is present).
In order to make it work, just remove "add-module-exports" from your plugins in the project-ui .babelrc.
How do you make Jest play nicely with ES7 initializers? I've searched far a wide on here and other sources, but didn't find anything conclusive.
.babelrc.js
{
"env": {
"development": {
"presets": [["es2015", { "modules": false }], "react", "react-hmre"],
"plugins": [
"transform-class-properties",
"react-hot-loader/babel"
]
},
"test": {
"presets": ["env", "react"],
"plugins": ["transform-class-properties"]
},
"production": {
"presets": [["es2015", { "modules": false }], "react"],
"plugins": ["transform-class-properties"]
}
}
}
package.json
{
"name": "demo",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"private": true,
"dependencies": {
"react": "^15.5.4",
"react-dom": "^15.5.4",
},
"devDependencies": {
"babel-cli": "^6.24.1",
"babel-core": "^6.24.1",
"babel-jest": "^20.0.3",
"babel-plugin-transform-class-properties": "^6.24.1",
"babel-polyfill": "^6.23.0",
"babel-preset-env": "^1.5.2",
"babel-preset-es2015": "^6.24.1",
"babel-preset-react": "^6.24.1",
"babel-preset-react-hmre": "^1.1.1",
"enzyme": "^2.8.2",
"react-hot-loader": "next",
"babel-plugin-import": "^1.2.1",
"enzyme": "^2.9.1",
"enzyme-to-json": "^1.5.1"
},
"scripts": {
"test": "export NODE_ENV=test && ./node_modules/.bin/jest --no-cache"
},
"engines": {
"node": ">= 7.8.0"
},
"jest": {
"verbose": true,
"collectCoverage": true,
"coverageDirectory": "__coverage__",
"mapCoverage": true,
"setupFiles": [
"./tests/setup.js"
],
"testPathIgnorePatterns": [
"/node_modules/"
],
"transform": {
"\\.js$": "../node_modules/babel-jest"
},
"testRegex": ".*\\.test\\.js$",
"snapshotSerializers": [
"enzyme-to-json/serializer"
]
}
}
Demo.jsx
import React from 'react';
import PropTypes from 'prop-types';
export class Demo extends React.Component {
static props = { name: PropTypes.string.isRequired };
constructor(props) {
super(props);
}
render() {
return (
<div className='demo'>{this.props.name}</div>
);
}
}
Demo.test.js
import React from 'react';
import { Demo } from '..';
import { render } from 'enzyme';
describe('Demo', () => {
it('renders correctly', () => {
const wrapper = render(<Demo name="foo" />);
expect(wrapper).toMatchSnapshot();
});
});
After running yarn test or export NODE_ENV=test && ../node_modules/.bin/jest --no-cache, Jest will complain that it sees an unexpected character
8 | props = {
| ^
9 | name: PropTypes.string.isRequired
From my understanding, the environment variable set when we run the tests should automatically transform the initializers to something which can be used by Jest, but this doesn't appear to be happening.
I am also using webpack 2.x, but the configuration overhead to get that to work seems daunting. Is there another way?
Update 1
I modified my Jest settings as follows:
"transform": {
"\\.js$": "./node_modules/babel-plugin-transform-class-properties"
}
This failed immediately with:
TypeError: Jest: a transform must export a process function.
Removing transform altogether yields a slightly different issue:
TypeError: Cannot read property 'props' of null
I also added the constructor to the Demo component.
I believe if you are trying to add propTypes, with ES7 initializers and using the transform-class-properties you need to do
static propTypes = {
name: PropTypes.string.isRequired
};
So it would be
import React from 'react';
import PropTypes from 'prop-types';
export class Demo extends React.Component {
static propTypes = {
name: PropTypes.string.isRequired
};
render() {
return (
<div className='demo'>{this.props.name}</div>
);
}
}
Pretty sure you do not have to explicitly define props as it is part of the React.Component when you extends from it. That or you may need to declare constructor and then call super(props);
Jest uses babel to transpile JS code. You need to add support for ES7 features in .babelrc file.
Here are the steps:
Do npm install --save-dev babel-preset-stage-0 babel-jest
In your package.json, add babel-jest for transforming all the js files.
In your .babelrc file, add "stage-0" preset.
Here is how my package.json looks like:
...
"jest": {
"transform": {
"^.+\\.js$": "babel-jest"
}
}
...
And here is how my .babelrc file looks like:
{
"presets": [
"es2015",
"react",
"stage-0"
]
}