Documentation for Next.js configuration seems incorrect
Problem
The Next.js section of the Styleguidist docs state:
That's it, notice that we don't need to install webpack as it's already included by Next.js.
I tried following this in a Next.js app and only added the Babel presets, but Styleguidist wouldn't run and load the guide until I installed and configured Webpack.
Suggestion
This behavior was unexpected based on how I read the docs. Unless there's something I did wrong and I really shouldn't have needed to install and configure Webpack with my Next app, I'm happy to update the Next.js section of the Webpack config docs to reflect this. If there is something else I missed, I'll gladly update the docs to include whatever that is!
Additional details
Without installing webpack, running npx styleguidist server showed this error:
Webpack is required for Styleguidist, please add it to your project:
npm install --save-dev webpack
See how to configure webpack for your style guide:
https://react-styleguidist.js.org/docs/webpack
After explicitly installing webpack but without adding a webpack config, npx styleguide run does "run" the project but can't parse the files and shows this warning:
Warning: No webpack config found. You may need to specify "webpackConfig" option in your style guide config:
https://react-styleguidist.js.org/docs/webpack
Once I added webpackConfig to styleguide.config.js (used the example copied in the "Custom webpack config" section), it ran fine.
I have the same problem. Does anyone have a suggestions to fix this without added webpack in the configuration?
I also have the same problem. Anyone got this working that can share the steps to get set up in next js
😴 This issue has been automatically marked as stale because it has not had recent activity. It will be closed in a week without any further activity. Consider opening a pull request if you still have this issue or want this feature.
same issue here, any fixes yet?
Not sure if this will work for the nextjs folks, but i ran into the same problem with create-react-app, that is to say webpack is built into CRA but styleguidist wouldn't work with it until I added a custom webpackConfig key to the module.exports of styleguide.config.js to tell it how to handle various file types. Essentially I had to redo this part of webpack. Here's my config file, if it helps at least one person then I've done some good in the world :)...unless you're using styleguidist for evil :(
webpackConfig: {
// https://github.com/styleguidist/react-styleguidist/issues/1910
plugins: [
// Rewrites the absolute paths to those two files into relative paths
new webpack.NormalModuleReplacementPlugin(
/react-styleguidist\/lib\/loaders\/utils\/client\/requireInRuntime$/,
'react-styleguidist/lib/loaders/utils/client/requireInRuntime'
),
new webpack.NormalModuleReplacementPlugin(
/react-styleguidist\/lib\/loaders\/utils\/client\/evalInContext$/,
'react-styleguidist/lib/loaders/utils/client/evalInContext'
),
],
module: {
rules: [
{
test: /\.tsx?$/,
use: {
loader: 'ts-loader',
options: {
transpileOnly: true,
},
},
exclude: /node_modules/,
},
{
test: /\.(css)$/,
use: 'css-loader',
},
{
test: /\.(s(a|c)ss)$/,
use: ['style-loader', 'css-loader', 'sass-loader'],
},
{
test: [/\.(png|jpe?g|gif)$/i, /\.(ttf|eot)(\?[a-z0-9]+)?$/],
use: 'file-loader',
},
{
test: /\.svg$/,
use: {
loader: 'svg-url-loader',
options: {
limit: 10000,
},
},
},
{
test: /\.woff(2)?(\?[a-z0-9]+)?$/,
use: {
loader: 'url-loader',
options: {
limit: 10000,
},
},
},
],
},
},
nextjs now uses turbopack. not webpack, i guess that's the big issue.
this is my styleguide.config.js
module.exports = {
components: 'src/components/**/*.{jsx,tsx}',
propsParser: require('react-docgen-typescript').withCustomConfig(
'./tsconfig.json'
).parse
};
didn't work, took a lot of time.. but says:
It usually happens when using third-party libraries, see possible solutions here:
https://react-styleguidist.js.org/docs/thirdparties
Warning: src/components/user/LoginForm/index.tsx matches a pattern defined in “components” or “sections” options in your style guide config but doesn’t export a component.
It usually happens when using third-party libraries, see possible solutions here:
https://react-styleguidist.js.org/docs/thirdparties
Module parse failed: Unexpected token (41:23)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
| title
| }) {
> const selectedNetwork: Network = useRef(
| store,
| (state: GlobalState) => state.networks.selectedNetwork,
Learn how to add webpack loaders to your style guide:
https://react-styleguidist.js.org/docs/webpack
the configuration shared above gives me this error:
er
SyntaxError: Unexpected token ':'
~/devel/helpbuttons.org/web/styleguide.config.js:14
module: {
^
SyntaxError: Unexpected token ':'
at Object.compileFunction (node:vm:352:18)
at wrapSafe (node:internal/modules/cjs/loader:1033:15)
at Module._compile (node:internal/modules/cjs/loader:1069:27)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1159:10)
at Module.load (node:internal/modules/cjs/loader:981:32)
at Function.Module._load (node:internal/modules/cjs/loader:822:12)
at Module.require (node:internal/modules/cjs/loader:1005:19)
at require (node:internal/modules/cjs/helpers:102:18)
at getConfig (/home/ajeremias/devel/helpbuttons.org/web/node_modules/react-styleguidist/lib/scripts/config.js:70:14)
at Object.<anonymous> (/home/ajeremias/devel/helpbuttons.org/web/node_modules/react-styleguidist/lib/bin/styleguidist.js:56:12)
https://github.com/helpbuttons/helpbuttons/tree/dev/web
any kind of support would be greatful, and pull requests are very welcome.
this is the code:
import React, { useEffect, useState } from 'react';
import Form from 'elements/Form';
import Popup from 'components/popup/Popup';
import ButtonType from 'components/button/ButtonType';
import Btn, { BtnType, ContentAlignment } from 'elements/Btn';
import FieldLocation from 'elements/Fields/FieldLocation';
import { FieldTextArea } from 'elements/Fields/FieldTextArea';
import FieldText from 'elements/Fields/FieldText';
import ButtonShare from 'components/button/ButtonShare';
// import ButtonNewDate from 'components/button/ButtonNewDate';
import FieldTags from 'elements/Fields/FieldTags';
import { useRef } from 'store/Store';
// import FieldImageUpload from "elements/Fields/FieldImageUpload";
import { GlobalState, store } from 'pages';
import { FieldImageUpload } from 'elements/Fields/FieldImageUpload';
import { Network } from 'shared/entities/network.entity';
import FieldDate from 'elements/Fields/FieldDate';
import t from 'i18n';
import { LoadabledComponent } from 'components/loading';
import Router from 'next/router';
import { SaveButtonDraft } from 'state/Explore';
import { useButtonTypes } from 'shared/buttonTypes';
export default function ButtonForm({
onSubmit,
watch,
reset,
getValues,
handleSubmit,
register,
errors,
control,
setValue,
setFocus,
isSubmitting,
title,
}) {
const selectedNetwork: Network = useRef(
store,
(state: GlobalState) => state.networks.selectedNetwork,
);
const buttonDraft = useRef(
store,
(state: GlobalState) => state.explore.draftButton,
);
const [buttonTypes, setButtonTypes] = useState([]);
useButtonTypes(setButtonTypes);
const [date, setDate] = useState('');
const [errorMsg, setErrorMsg] = useState(undefined);
const [isReadyForLocationAndTime, setIsReadyForLocationAndTime] =
useState(false);
const [markerColor, setMarkerColor] = useState(null);
useEffect(() => {
if (buttonDraft) {
reset(buttonDraft);
}
}, [buttonDraft]);
const buttonType = watch('type')
useEffect(() => {
const subscription = watch((value, { name, type }) => {
const values = getValues();
if (
values?.image?.length > 0 &&
values.title.length > 0 &&
values.type.length > 0
) {
setIsReadyForLocationAndTime(true);
} else {
setIsReadyForLocationAndTime(false);
}
});
return () => subscription.unsubscribe();
}, [watch]);
useEffect(() => {
if(buttonTypes)
{
const values = getValues();
const buttonType = buttonTypes.find((buttonType) => {
return buttonType.name === values.type;
});
if (buttonType) {
setMarkerColor(() => buttonType.cssColor);
}
}
}, [buttonType, buttonTypes])
const closeClicked = () => {
store.emit(new SaveButtonDraft(getValues()));
Router.push('/Explore');
};
return (
<LoadabledComponent loading={!selectedNetwork}>
<Popup title={title} onCloseClicked={closeClicked}>
<Form
onSubmit={handleSubmit(onSubmit)}
classNameExtra="publish_btn"
>
<div className="form__inputs-wrapper">
<ButtonType
name="type"
label={t('button.typeLabel')}
{...register('type', { required: true })}
validationError={errors.type}
explain={t('button.typeExplain')}
buttonTypes={buttonTypes}
/>
<FieldText
name="title"
label={t('button.titleLabel')}
placeholder={t('button.placeHolderTitle')}
validationError={errors.title}
watch={watch}
setValue={setValue}
explain={t('button.titleExplain')}
setFocus={setFocus}
{...register('title', { required: true })}
/>
<FieldTextArea
label={t('button.descriptionLabel')}
name="description"
placeholder={t('button.placeHolderDescription')}
validationError={errors.description}
classNameExtra="squared"
watch={watch}
setValue={setValue}
setFocus={setFocus}
{...register('description', {
required: true,
minLength: 10,
})}
/>
{/* TODO: Warning: Cannot update a component (`ButtonNew`) while rendering a different component (`FieldTags`). To locate the bad setState() call inside `FieldTags`, follow the stack trace as described in https://reactjs.org */}
<FieldTags
label={t('button.tagsLabel')}
placeholder={t('common.add')}
validationError={errors.tags}
setTags={(tags) => {
setValue('tags', tags);
}}
tags={watch('tags')}
/>
<FieldImageUpload
name="image"
label={t('button.imagesLabel')}
// width={55}
// height={125}
setValue={setValue}
control={control}
{...register('image', { required: true })}
validationError={errors.image}
/>
<>
{selectedNetwork && (
<FieldLocation
label={t('button.whereLabel')}
updateMarkerPosition={([lat, lng]) => {
setValue('latitude', lat);
setValue('longitude', lng);
}}
updateAddress={(address) => {
setValue('address', address);
}}
markerAddress={watch('address')}
markerImage={watch('image')}
markerCaption={watch('title')}
markerColor={markerColor}
selectedNetwork={selectedNetwork}
validationError={errors.location}
/>
)}
{/* <FieldDate
dateType={watch('when.type')}
dates={watch('when.dates')}
setDateType={(value) => setValue('when.type', value)}
setDate={(value) => setValue('when.dates', value)}
title={t('button.whenLabel')}
/> */}
</>
{/* <ButtonNewDate title="When ?" setDate={setDate} date={date} /> */}
<ButtonShare />
</div>
<div className="publish__submit">
<Btn
btnType={BtnType.submit}
contentAlignment={ContentAlignment.center}
caption={t('common.publish')}
isSubmitting={isSubmitting}
submit={true}
/>
</div>
</Form>
</Popup>
</LoadabledComponent>
);
}
https://github.com/helpbuttons/helpbuttons/blob/dev/web/src/components/button/ButtonForm/index.tsx#L40