Storybook + MDX - javascript

My .js stories show perfectly on storybook but .mdx stories do not show & I get no error as well
main.js
module.exports = {
addons: [
'#storybook/addon-docs/register',
'#storybook/addon-actions/register',
'#storybook/addon-links/register',
'#storybook/addon-knobs/register',
'#storybook/addon-storysource/register',
'#storybook/addon-viewport/register',
],
};
webpack.config.js
as suggested here https://www.npmjs.com/package/#storybook/addon-docs#manual-configuration
config.module.rules.push({
test: /\.(stories|story)\.mdx?$/,
use: [
{
loader: 'babel-loader',
options: {
plugins: ['#babel/plugin-transform-react-jsx'],
},
},
{
loader: '#mdx-js/loader',
options: {
compilers: [createCompiler({})],
},
},
],
});
config.module.rules.push({
test: /\.(stories|story)\.jsx?$/,
loader: require.resolve('#storybook/source-loader'),
exclude: [/node_modules/],
enforce: 'pre',
});
preview.js
addParameters({
docs: {
container: DocsContainer,
page: DocsPage,
},
});
function loadStories() {
const requires = [require.context('#rrc', true, /\.stories\.(js|mdx)$/)];
for (const req of requires) req.keys().forEach(filename => req(filename));
}
configure(loadStories, module);
Now I have 2 types of stories
story.mdx
import { Meta, Story } from '#storybook/addon-docs/blocks';
// Components
import Chips from '../';
<Meta title="AAAAAAAAA AAAAAA/Chip2" component={Chip} />
# Chip
I can define a story with the function imported from CSF:
And I can also embed arbitrary markdown & JSX in this file.
<Chip label="Basic" />
<Preview>
<Story name="all checkboxes">
<form>
<Chip label="Basic" />
</form>
</Story>
</Preview>
### Installing
A step by step series of examples that tell you how to get a development env running
and .js stories which are like
import React from 'react';
import { storiesOf } from '#storybook/react';
import { Chip } from '../../..';
storiesOf('Chip', module)
.addParameters({
component: Chip,
})
.add('Basic', () => <Chip label="Basic" />)
.add('Disabled', () => <Chip label="Disabled" disabled />)

Related

React component not rendering correctly after await call

i have html template i purchased at themeforest.net im trying to convert it to webpack and react every thing works fine now but there is weird bug when ever i make await call in componentDidMount the page didnt render correctly
let res = await axios({
method: "get",
url: "http://localhost:8080/api/main/mainProducts",
});
this.setState({ allProducts: res.data });
when i comment the await call
and setstate to static data
let allProducts = [
{
//array data
},
]
this.setState({ allProducts: allProducts });
its render correctly. here is the component
export class MainComponent extends React.Component<{}, any> {
constructor(props) {
super(props);
this.state = {
allProducts: [],
};
}
async componentDidMount() {
let res = await axios({
method: "get",
url: "http://localhost:8080/api/main/mainProducts",
});
this.setState({ allProducts: res.data });
}
render(): any {
return (
<div className="product-4 product-m no-arrow">
{this.state.allProducts.map((x) => (
<div key={x.id} className="product-box product-wrap">
<div className="img-wrapper">
<div className="lable-block">
<span className="lable3">new</span>{" "}
<span className="lable4">on sale</span>
</div>
<div className="front">
<a href={"/product/" + x.id}>
{x.images.map((image) =>
image.main.toString() === "true" ? (
<img
className="img-fluid blur-up lazyload bg-img"
key={image.id}
src={`/public/productImages/${x.id.toString()}/${
image.imageName
}`}
></img>
) : (
""
)
)}
</a>
</div>
</div>
</div>
))}
</div>
// long html lines here
// ...
);
}
}
webpack config
const HtmlWebpackPlugin = require("html-webpack-plugin");
const path = require("path");
const webpack = require("webpack");
module.exports = {
entry: path.join(__dirname, "src/index.tsx"),
module: {
rules: [
{
test: /\.css$/,
use: ["style-loader", "css-loader"],
},
{
test: /\.scss$/,
use: ["style-loader", "css-loader", "sass-loader"],
},
{
test: /\.(svg|gif|jpg|png|eot|woff|woff2|ttf)$/,
use: [
'url-loader',
],
},
{
test: /\.js$/,
exclude: /node_modules/,
use: ["babel-loader"],
},
{
test: /\.tsx?$/,
loader: "ts-loader",
exclude: /node_modules/,
},
{
test: /\.ts$/,
use: ["ts-loader"],
},
],
},
resolve: {
extensions: [".tsx", ".ts", ".js"],
},
plugins: [
new HtmlWebpackPlugin({
template: path.resolve(__dirname, "src", "index.html"),
filename: "./index.html",
}),
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery",
}),
],
output: {
path: __dirname + "/dist/",
filename: "index.js",
publicPath: '/'
},
devServer: {
historyApiFallback: true,
proxy: {
"/api": {
target: "http://localhost:5050",
pathRewrite: { "^/api": "" },
},
},
},
mode: "development",
};
entry point index.tsx
import React from "react";
import { render } from "react-dom";
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
import { MainComponent } from "./views/user/main/main";
import { Bottom } from "./views/user/layout/bottom";
import { Top } from "./views/user/layout/top";
import "core-js/stable";
import "regenerator-runtime/runtime";
import "./helpers/css"; //css imports of the html template
render(
<Router>
<Switch>
<Route path="/" exact>
<>
<Top />
<MainComponent />
<Bottom />
</>
</Route>
</Switch>
</Router>,
document.getElementById("r")
);
import "./helpers/js"; //js imports of the html template
and most importantly css and js imports
css.tsx
import "/public/assets/css/fontawesome.css";
import "/public/assets/css/slick.css";
import "/public/assets/css/slick-theme.css";
import "/public/assets/css/animate.css";
import "/public/assets/css/themify-icons.css";
import "/public/assets/css/bootstrap.min.css";
import "/public/assets/css/bootstrap4-toggle.min.css";
import "/public/assets/css/jquery.lazyloadxt.spinner.css";
import "/public/assets/css/color5.css";
import "/public/assets/css/site.css";
js.tsx
import "/public/assets/js/jquery-ui.min.js";
import "/public/assets/js/jquery.exitintent.js";
import "/public/assets/js/exit.js";
// #ts-ignore
window.Popper = require("/public/assets/js/popper.min.js");
import "/public/assets/js/slick.js";
import "/public/assets/js/menu.js";
import "/public/assets/js/lazysizes.min.js";
import "/public/assets/js/bootstrap.min.js";
import "/public/assets/js/bootstrap4-toggle.min.js";
import "/public/assets/js/bootstrap-notify.min.js";
import "/public/assets/js/fly-cart.js";
import "/public/assets/js/script.js";
import "/public/scripts/layout.js";
i suspect its something to do with slick library
ive tried import() slick js and css files after setstate but it doesnt work
this.setState({ allProducts: res.data }, () => {
import("../../../../public/assets/css/slick.css");
import("../../../../public/assets/css/slick-theme.css");
import("../../../../public/assets/js/slick.js");
});
i have also tried re import the whole css and js files but also doesnt work
i have also tried many other things like using ajax instead of axios but it give the exact same bug ive also tried this
axios({
method: "get",
url: "http://localhost:8080/api/main/mainProducts",
}).then((x) => {
this.setState({ allProducts: x.data });
});
no await here but its same bug also.
a picture of when its render correctly
wrong render
any help would be really appreciated.
thanks !

React not rendering components

I am dealing with an electron BrowserWindow that should render an HTML file filled with some react components. However the React components are not showing.
I have an html file which is:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta http-equiv="Content-Security-Policy" content="script-src 'self'" />
</head>
<body>
<div id='QA_Dialog'></div>
<script src="../js/index.js"></script>
</body>
</html>
My script source file "../js/index.js" contains some easy React rendering:
import ReactDOM from 'react-dom';
import QAWindow from './QAWindow';
document.body.style.overflow = "hidden";
document.body.style.borderRadius = "5px";
ReactDOM.render(<QAWindow />, document.getElementById('QA_Dialog'))
Where QAWindow is :
import React from 'react';
import { electron } from 'webpack';
import { CloseButton, StyledButton} from '../templates/style';
const useState = React.useState
function QuestionForm() {
const [question, setQuestion] = useState()
function handleSubmit(e) {
e.preventDefault()
electron.QandA.askQuestionSignal(question);
}
function handleClose(e){
e.preventDefault()
electron.QandA.closeWindowSignal('Dio')
}
return (
<>
<CloseButton onClick={handleClose}>
<img src="../templates/close.svg" />
</CloseButton>
<form onSubmit={handleSubmit}>
<input value={question} onChange={e => setQuestion(e.target.value)} placeholder="Ask a question..." />
<span>
<StyledButton>Find Answer</StyledButton>
</span>
</form>
</>
)
}
export default function QAWindow() {
return(
<>
<QuestionForm />
</>
)
}
If I change the above file to only export a simple element it doesn't work anyways. So I assume that the problem is not in QAWindow.
These files are copied in the build/ folder, and there, the reference '../js/index.js' is still valid (the structure of the files dosn't change).
../js/index.js got compiled by web-pack using a babel-loader.
Why does this render a white page???
EDIT:
To better debug this, I am also providing my webpack.config.js:
// This first configuration bundles the script that renders the react components
const QandAExtension= {
mode: 'development',
entry: './src/preloads/QandA/js/index.js', // This entry point match the correct react script that needs to be bundled.
devtool: 'inline-source-map',
target: 'electron-renderer',
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: [[
'#babel/preset-env', {
targets: {
esmodules: true
}
}],
'#babel/preset-react']
}
}
},
{
test: [/\.s[ac]ss$/i, /\.css$/i],
use: [
// Creates `style` nodes from JS strings
'style-loader',
// Translates CSS into CommonJS
'css-loader',
// Compiles Sass to CSS
'sass-loader',
],
},
{
test: /\.svg$/,
use: [
{
loader: 'svg-url-loader',
options: {
limit: 10000,
},
},
],
}
]
},
resolve: {
extensions: ['.js'],
},
output: {
filename: 'index.js',
path: path.resolve(__dirname, 'build', 'QandA', 'js'),
},
};
// This second configuration copies the folder containing the HTML file
// into the build/ folder of this app.
const preloadConfig = getConfig({
target: 'electron-renderer',
devtool: false,
watch: dev,
entry: {
'view-preload': './src/preloads/view-preload',
},
// Here in plugin you can specify what you want to copy in the build/ folder.
plugins: [
new CopyPlugin({
patterns: [
{
from: join(__dirname, "src", "preloads", "QandA", "templates"),
to: "QandA/templates",
toType: "dir",
}
],
}),
],
},);
module.exports = [preloadConfig, QandAExtension];
You need to import React's Javascript bundles, which React does through the command line react-scripts start (and isn't explicitly defined in the index.html file).
e.g.
<script src="/static/js/bundle.js"></script>
<script src="/static/js/0.chunk.js"></script>
<script src="/static/js/main.chunk.js"></script>
are imports on functioning index.html React pages.

Server-side render does not render UI library

I am trying to implement a server-side rendering for my app. It used to be a client side render using ReactDom. Everything works fine in client-side render, but now when I make it server-side render, none of the CSS sheet and UI libraries(Reactstrap + Material UI) are rendered. The UI broke completely.
I am injecting my App.js(actual front-end page with all the UI) into my html.js(a template)
My server:
import express from 'express';
import React from 'react';
import { renderToString } from 'react-dom/server'
import App from '../../src/App'
import Html from '../../src/html.js'
const app = express();
// console.log that your server is up and running
app.listen(3001, () => console.log(`Listening on port 3001`));
app.get('/',(req,res) => {
const title="2FA SDK"
const body = renderToString(<App/>)
res.send(
Html({
body,
title,
})
)
})
My html.js(just a simple template):
const Html = ({ body, styles, title }) => `
<!DOCTYPE html>
<html>
<head>
<title>${title}</title>
</head>
<body style="margin:0">
<div id="app">${body}</div>
</body>
</html>
`;
My app.js(using material ui, minimal)
render(){
return(
<div className="container">
<div>
<TextField
label="Application Name"
type="text"
variant="outlined"
onChange={this.handleApplicationName}
/>
</div>
<div>
<FormLabel>Phone</FormLabel>
<div>
<OutlinedInput
value={this.state.textmaskArray[2]}
onChange={(e) => this.handlePhoneNumber(e,2)}
labelWidth={200}
/>
</div>
</div>
<Button variant="contained" color="primary" onClick={this.props.buttonAction}>
</Button>
</div>
Part of App.js that uses reactstrap:
render(){
return(
<CardControl
title={"Code Authention"}
message={"For your security, we need to verify your identity by sending a code to your phone number"}
>
<Container>
<Row>
<Col>
<div>{this.props.phoneList}</div>
</Col>
<Col>
<div>{this.props.methodList}</div>
</Col>
</Row>
<Button className="sm-2" disabled={this.props.disabled} color="info" onClick={this.props.buttonAction}>{this.props.buttonName}</Button>
</Container>
</CardControl>
)
}
My webpack.config.js:
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const HtmlWebPackPlugin = require("html-webpack-plugin");
const nodeExternals = require("webpack-node-externals");
module.exports = [
{
/*Config for backend code*/
entry: './src/server/server.js',
target: 'node',
output: {
filename: 'server.js'
},
externals: [nodeExternals()],
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: /\.html$/,
use: {
loader: "html-loader",
options: { minimize: true }
}
},
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader,"css-loader"]
}
]
},
plugins: [
new HtmlWebPackPlugin({
template: "./public/index.html",
filename:"./index.html"
}),
new MiniCssExtractPlugin({
filename: "[name].css",
chunkFilename:"[id].css"
})
]
},
]
What I am using: Create-react-app
What I have tried: I installed CSS loders, but it is not working at all.
I also looked up material-ui's document on server-side rendering, I feel like I am just missing a small part and the instruction they provided may be a overkill.
What I need help with: I am trying to figure out why the UI component from material-ui or bootstrap did not get render at all. I am suspecting that nodeExternal exclude them, but I am not sure.
You will need to hydrate your rendered HTML in the client side in order to have react take over.
Create a client.js file with:
import React from 'react';
import ReactDOM from 'react-dom';
ReactDOM.hydrate(
<App/>,
document.querySelector('#app'),
);
note that the hydrate should match what renderToString rendered.
Next add this as an additional entry in your webpack configuration:
module.exports = [
{
/*Config for backend code*/
entry: './src/server/server.js',
target: 'node',
output: {
filename: 'server.js'
},
externals: [nodeExternals()],
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: /\.html$/,
use: {
loader: "html-loader",
options: { minimize: true }
}
},
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader,"css-loader"]
}
]
},
plugins: [
new HtmlWebPackPlugin({
template: "./public/index.html",
filename:"./index.html"
}),
new MiniCssExtractPlugin({
filename: "[name].css",
chunkFilename:"[id].css"
})
]
},
{
entry: './client.js',
output: {
filename: 'bundle.js',
},
module: {
rules: [ {
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
},
],
},
]
Change your html rendering code to include this:
const Html = ({ body, styles, title }) => `
<!DOCTYPE html>
<html>
<head>
<title>${title}</title>
</head>
<body style="margin:0">
<div id="app">${body}</div>
<script async src="/bundle.js"></script>
</body>
</html>
`;
I'm not 100% confident on whether this exact code will work but this is the general idea.

Why does isomorphic-style-loader throw a TypeError: Cannot read property 'apply' of undefined when being used in unison with CSS-Modules

I'm currently trying to render the application on the server, which works for the HTML and JS, but found that my styles (.less | .scss) would not load. I did some research and figured, not sure, that I was missing the isomorphic-style-loader in my Webpack configuration based on others running into the same issues. I set it up, at least how I understood it, but am now finding that when running the application I receive the following error:
TypeError: Cannot read property 'apply' of undefined at WithStyles.componentWillMount
I'm somewhat new to the whole React / Express thing but have been trying to follow along with tutorials and learning as I go, if anything seems out of place, please excuse me. I am hoping to see if anybody can explain what exactly causes this error, and provide me with some idea of what I could follow to resolve this error. Below is some example code that resembles the one I am having issues with, if it helps in any way.
(For reference I was following Tyler McGinnis React Router Server Rendering tutorial and tried to expand upon it to add styling - Link Here)
Thanks beforehand for any explanation provided as to what may be causing this error.
webpack.config.babel.js
import path from 'path'
import webpack from 'webpack'
import nodeExternals from 'webpack-node-externals'
const paths = {
browser: path.join(__dirname, './src/browser'),
server: path.join(__dirname, './src/server'),
build: path.resolve(__dirname, 'public')
}
let browserConfig = {
entry: `${paths.browser}/index.js`,
output: {
path: paths.build,
filename: 'bundle.js',
publicPath: '/'
},
module: {
rules: [
{
test: /\.s?(a|c)ss$/,
use: [
'isomorphic-style-loader',
{
loader: 'css-loader',
options: {
modules: true,
importLoaders: 1,
localIdentName: '[name]__[local]___[hash:base64:5]',
sourceMap: true
}
},
'sass-loader',
'postcss-loader'
]
}, {
test: /\.less$/,
use: [
'isomorphic-style-loader',
{
loader: 'css-loader',
options: {
modules: true,
importLoaders: 1,
localIdentName: '[name]__[local]___[hash:base64:5]',
sourceMap: true
}
},
{
loader: 'less-loader',
options: {
javascriptEnabled: true
}
},
'postcss-loader'
]
}, {
test: /\.jsx?$/,
loader: 'babel-loader',
exclude: /node_modules/
}
]
},
plugins: [
new webpack.DefinePlugin({
__isBrowser__: true
})
],
resolve: {
extensions: ['.js', '.jsx', '.json', '.css', '.scss', '.sass', '.less']
}
}
let serverConfig = {
entry: `${paths.server}/index.js`,
target: 'node',
externals: [nodeExternals()],
output: {
path: __dirname,
filename: 'server.js',
publicPath: '/'
},
module: {
rules: [
{
test: /\.s?(a|c)ss$/,
use: [
'isomorphic-style-loader',
{
loader: 'css-loader',
options: {
modules: true,
importLoaders: 1,
localIdentName: '[name]__[local]___[hash:base64:5]',
sourceMap: true
}
},
'sass-loader',
'postcss-loader'
]
}, {
test: /\.less$/,
use: [
'isomorphic-style-loader',
{
loader: 'css-loader',
options: {
modules: true,
importLoaders: 1,
localIdentName: '[name]__[local]___[hash:base64:5]',
sourceMap: true
}
},
{
loader: 'less-loader',
options: {
javascriptEnabled: true
}
},
'postcss-loader'
]
}, {
test: /\.jsx?$/,
loader: 'babel-loader',
exclude: /node_modules/
}
]
},
plugins: [
new webpack.DefinePlugin({
__isBrowser__: false
})
],
resolve: {
extensions: ['.js', '.jsx', '.json', '.css', '.scss', '.sass', '.less']
}
}
module.exports = [browserConfig, serverConfig]
server.js
import express from "express"
import cors from "cors"
import React from "react"
import bodyParser from 'body-parser'
import serialize from "serialize-javascript"
import { renderToString } from "react-dom/server"
import { StaticRouter, matchPath } from "react-router-dom"
import App from '../shared/App'
import routes from '../shared/routes'
const app = express()
const port = process.env.PORT || 3000
app.use(cors())
app.use(bodyParser.json()) // support json encoded bodies
app.use(bodyParser.urlencoded({extended: true})) // support encoded bodies
app.use(express.static("public"))
app.get("*", (req, res, next) => {
const activeRoute = routes.find((route) => matchPath(req.url, route)) || {}
const promise = activeRoute.fetchInitialData
? activeRoute.fetchInitialData(req.path)
: Promise.resolve()
promise.then((data) => {
const css = new Set()
const context = { data, insertCss: (...styles) => styles.forEach(style => css.add(style._getCss())) }
const markup = renderToString(
<StaticRouter location={req.url} context={context}>
<App />
</StaticRouter>
)
res.send(`
<!DOCTYPE html>
<html>
<head>
<title>React on the Server!</title>
<script src="/bundle.js" defer></script>
<script>window.__INITIAL_DATA__ = ${serialize(data)}</script>
</head>
<body>
<div id="app">${markup}</div>
</body>
</html>
`)
}).catch(next)
})
app.listen(port, () => console.log(`Server is listening on port: ${port}`))
routes.js
import AboutMain from './components/About/AboutMain'
const routes = [
{
path: '/about',
component: AboutMain
}
]
export default routes
browser.js
// Import the neccessary modules for use in file
import React from 'react' // Main React module
import { hydrate } from 'react-dom' // render alternative for server rendering
import App from '../shared/App'
import { BrowserRouter } from 'react-router-dom' // React Router component for client side routing
import '../shared/components/global.scss' // Only has general rules, which do get applied
hydrate(
<BrowserRouter>
<App />
</BrowserRouter>,
document.getElementById('app')
)
App.js
import React, { Component } from 'react'
import routes from './routes'
import { Route, Link, Redirect, Switch } from 'react-router-dom'
class App extends Component {
render() {
return (
<div>
<Switch>
{routes.map(({ path, exact, component: Component, ...rest }) => (
<Route key={path} path={path} exact={exact} render={(props) => (
<Component {...props} {...rest} />
)} />
))}
<Route render={(props) => <NoMatch {...props} /> } />
</Switch>
</div>
)
}
}
export default App
AboutMain.js
// Importing Required Modules
import React, {Component, Fragment} from 'react' // Importing React, Component, Fragment from "react"
import withStyles from 'isomorphic-style-loader/lib/withStyles';
import s from './about.scss'
class AboutMain extends Component {
state = {
phrase: 'We Made It!'
}
render() {
return (
<Fragment>
<header className={s.banner}>
<h1 className={s.heading}>{this.state.phrase}</h1>
</header>
</Fragment>
)
}
}
export default withStyles(s)(AboutMain) <-- Error Seems to occur here, at least I think.
about.scss
.banner {
margin: 0 auto;
padding: 15px;
border: 2px solid #000;
}
.heading {
text-transform: uppercase;
text-decoration: underline;
}
The problem went away simply because you removed isomorphic-style-loader. Please don't accept your own answer like that. The problem here is you did not provide a context so insertCss.apply(_context, styles) will complain because _context is undefined. To solve the problem, follow these steps:
Create a ContextProvider component in the same directory of App
ContextProvider.js
import React from 'react';
import PropTypes from 'prop-types'
import App from './App'
class ContextProvider extends React.Component {
static childContextTypes = {
insertCss: PropTypes.func,
}
getChildContext() {
return { ...this.props.context }
}
render () {
return <App { ...this.props } />
}
}
export default ContextProvider
Wrap the ContextProvider in BOTH your browser.js and server.js. Remember to declare the context in both files.
browser.js (in other apps, this would be root client code, i.e client.js or index.js)
// Import the neccessary modules for use in file
/* import statements */
const context = {
insertCss: (...styles) => {
const removeCss = styles.map(x => x._insertCss());
return () => {
removeCss.forEach(f => f());
};
},
}
hydrate(
<BrowserRouter>
//ContextProvider wraps around and returns App so we can do this
<ContextProvider context={context} />
</BrowserRouter>,
document.getElementById('app')
)
server.js
//Additional code above
app.get("*", (req, res, next) => {
const activeRoute = routes.find((route) => matchPath(req.url, route)) || {}
const promise = activeRoute.fetchInitialData
? activeRoute.fetchInitialData(req.path)
: Promise.resolve()
promise.then((data) => {
const css = new Set()
const context = { insertCss: (...styles) =>
styles.forEach(style => css.add(style._getCss()))}
const markup = renderToString(
<StaticRouter location={req.url}>
<ContextProvider context={context}>
<App />
</ContextProvider>
</StaticRouter>
)
res.send(`
<!DOCTYPE html>
<html>
<head>
<title>React on the Server!</title>
<script src="/bundle.js" defer></script>
<script>window.__INITIAL_DATA__ = ${serialize(data)}</script>
<style type="text/css">${[...css].join('')}</style>
</head>
<body>
<div id="app">${markup}</div>
</body>
</html>
`)
}).catch(next)
})
app.listen(port, () => console.log(`Server is listening on port: ${port}`))
I wrote an article explaining this in more detail here: https://medium.com/#danielnmai/load-css-in-react-server-side-rendering-with-isomorphic-style-loader-848c8140a096
After reviewing the code all night and endlessly searching Google. I found a fix that the main issue with my code was in the webpack.config.babel.js setup.
I changed the browser test for sass || scss to use style-loader, rather than the isomorphic-style-loader. I also removed all isomorphic-style-loader logic from my app (ie. withStyles, insertCss, etc.)
I'm not sure if this was the correct approach, but for the meantime, it seems to fix my problem and does not return any errors or network issues.

React Route not displaying component on production

I am developing a React Webapp and I am using webpack for automating some tasks. The development mode works fine, I can see all components showing up, but when I open index.html from /dist folder where I have bundle.js and bundle.css same directory the webapp does not show the components.
I tried to upload on a apache web server whole /dist folder and tried to access like localhost/dist still I cannot see the comopnents.
Any idea how to make it so the files within dist folder I can use, in fact that's why I am using webpack to automate tasks so I can use this folder for production.
Webpack:
const HtmlWebPackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CleanWebpackPlugin = require('clean-webpack-plugin');
const webpack = require('webpack');
const path = require('path');
module.exports = (env, argv) => {
console.log("ENV DETECTED: " + argv.mode);
return {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
//publicPath: '/', // Remove this when running in production
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: /\.html$/,
use: [
{
loader: "html-loader",
options: {
minimize: true
}
}
]
},
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
// 'style-loader',
{
loader: 'css-loader',
options: {
importLoaders: 1,
minimize: true
}
},
{
loader: 'postcss-loader',
options: {
config: {
path: './postcss.config.js'
}
}
}
]
},
{
test: /\.scss$/,
use: [
argv.mode !== 'production' ? 'style-loader' : MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
importLoaders: 1,
minimize: true
}
},
{
loader: 'postcss-loader',
options: {
config: {
path: './postcss.config.js'
}
}
},
"sass-loader"
]
}
],
},
devServer: {
historyApiFallback: true,
},
plugins: [
new CleanWebpackPlugin('dist', {}),
new HtmlWebPackPlugin({
template: "src/index.html",
filename: "./index.html"
}),
new MiniCssExtractPlugin({
filename: "bundle.css",
chunkFilename: "bundle.css"
}),
require('autoprefixer'),
]
}
};
Routes:
import React from "react";
import { Switch, Route } from 'react-router-dom';
import Helloworld from './components/helloworld/helloworld.component';
import SecondView from './components/secondview/secondview.component';
import ThirdView from "./components/thirdview/thirdview.component";
const AppRoutes = () => (
<main>
<Switch>
<Route exact path='/' component={Helloworld}/>
<Route path='/secondview' component={SecondView}/>
<Route path='/thirdview' component={ThirdView}/>
<Route path='/thirdview/:number' component={ThirdView}/>
</Switch>
</main>
);
export default AppRoutes;
Helloworld component:
import React from 'react';
import HelloworldApi from './helloworld.api';
import { Link , withRouter } from 'react-router-dom';
require('./helloworld.style.scss');
class Helloworld extends React.Component {
constructor(props) {
super(props);
this.state = {
persons: [],
};
}
componentDidMount() {
console.log("I am being called helloworld component...");
HelloworldApi.getAll().then(response => {
if (response.data) {
console.log(response.data);
const persons = response.data;
this.setState({persons});
} else {
console.log(response);
}
});
}
render() {
return (
<div className={"boxDiv"}>
<p>Helloworld components</p>
<h1>Hello World</h1>
<h3>Web pack and React aree awesome together!!! test</h3>
{this.state.persons.map(person => <li>{person.name}</li>)}
<Link to='/secondview'>go to secondview</Link>
</div>
);
}
}
export default withRouter(Helloworld);

Categories

Resources