How to add examples a component with dependencies in react-styleguidist - javascript

I would like to document a ButtonGroup component rendering Button components within it using `react-styleguidist'.
I have a styleguidist webpack config which looks like this:
module.exports = {
module: {
rules: [
{
test: /\.jsx?$/,
use: [
{
loader: 'babel-loader'
}
],
exclude: /node_modules/
}
]
},
devtool: 'cheap-module-eval-source-map'
}
I know that I dont need to define commonly used loaders and plugins because styleguidist already adds them internally
Inside the src/components/, the directory structure for allowing styleguidist to pick up my components looks a little like this:
Button
index.js
Readme.md
ButtonGroup
index.js
example.js (created for Case II after Case I failed)
Readme.md
Case I
In my Readme.md within the ButtonGroup directory:
```jsx
const Button = require('../index')
<ButtonGroup>
<Button type='primary' size='lg'>Hello, World</Button>
<Button type='primary' size='lg'>Hello, Doctor</Button>
</ButtonGroup>
```
When I do that, my styleguide has an error that says:
SyntaxError: Adjacent JSX elements must be wrapped in an enclosing tag (5:2)
Case II
I have tried enclosing the information in an example.js inside ButtonGroup directory as illustrated above, the file contains:
import React from 'react'
const ButtonGroup = require('./index')
const Button = require('../index')
export default function ButtonGroupExample (props) {
return (
<ButtonGroup>
<Button>Hello, World</Button>
<Button>Hello, Doctor</Button>
</ButtonGroup>
)
}
Now the example component is imported into the Readme.md:
```jsx
const Example = require('./example')
(<Example />)
```
which throws the error:
TypeError: require(...) is not a function

I know that I dont need to define commonly used loaders and plugins because styleguidist already adds them internally
This is not true. Styleguidist doesn’t add any loaders to your code.
SyntaxError: Adjacent JSX elements must be wrapped in an enclosing tag (5:2)
Most likely you need a semicolon after ;. And probably you don’t need to require a Button component. It depends on your style guide config and whether you want to show your Button component in a style guide.
If you want to show both components in a style guide, point Styleguidist to all you components: components: 'src/components/**/index.js'.
If you want to hide some components from a style guide but be able to use them in examples, enable skipComponentsWithoutExample option an use require option to load your components:
// styleguide.config.js
module.exports = {
skipComponentsWithoutExample: true,
require: [
path.resolve(__dirname, 'styleguide/setup.js')
]
}
// styleguide/setup.js
import Buttom from './src/components/Button';
global.Button = Button;
Case II
I’m not sure what you’re trying to do here.

Related

Why can't we invoke ReactDOM or React directly in the browser?

I'm new to React and I'm still trying to wrap my head around how it works.
I understand that in our React code before "compiling" we can use React.createElement and ReactDOM.render to do all sorts of stuff but after the code is compiled and run on the client, suppose I wanted to dynamically create a new DOM node with one of my components.
Adding some code for further explanation
This is my index.js:
import React from 'react'
import ReactDOM from 'react-dom'
class HelloWorld extends React.Component {
render() {
return (
<div>
Hello World!
</div>
)
}
}
ReactDOM.render(
//React Element,
<HelloWorld />,
//where to render the Element to
document.getElementById('hello')
)
This works fine. However when I try dynamically adding the component "live" via the devtools console and type React.createElement, I get:
React is not defined
The same with ReactDOM. Are they not available via the console? There's probably something missing in my understanding and I'm thinking about this wrong but how exactly is React and ReactDOM not defined if my index.js was able to invoke ReactDOM.render?
Thanks!
React and ReactDOM can be used in the console if:
You export, what you need in the global scope, from webpack's entry point. For example:
export {React, ReactDOM, LeaveStats }
The bundle generated from webpack is included in the HTML page via a non-module script
Webpack is configured to output a "library" like so:
module.exports = {
entry: './app/LeaveStats.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
library: 'ReactApp' // <-- this will allow us access to whatever is exported in ./app/LeaveStats.js
},
module: {
rules: [
{ test: /\.js$/, use: 'babel-loader' },
]
},
mode: 'development'
}
You can then have access to React, ReactDOM and LeaveStats from the global scope e.g.:
ReactApp.ReactDOM.render(
ReactApp.React.createElement(ReactApp.LeaveStats),
document.getElementById("mydiv")
)
Not that I would really use this, but kind of helped my understand a few things along the way reaching to this point.

inject style into DOM using link tag in Gatsby

Is there any way to configure gatsby to inject a style file using a link tag?
currently, I have a global style (style.less) which I import it using a Layout Component. It's ok but It injects all CSS content into each page and bumps the page size.
I want to configure gatsby to load this style file using a link tag instead of injecting directly into DOM. webpack has an option for this purpose but I couldn't find anything similar for Gatsby.
Try:
exports.onCreateWebpackConfig = ({ actions, loaders, getConfig }) => {
const config = getConfig();
config.module.rules = [
...config.module.rules.filter(rule => String(rule.test) !== String(/\.jsx?$/)),
{
test: /\.link\.css$/i,
use: [
{ loader: `style-loader`, options: { injectType: `linkTag` } },
{ loader: `file-loader` },
],
},
];
actions.replaceWebpackConfig(config);
};
Gatsby allows you to customize the webpack's configuration by exposing some APIs (such as onCreateWebpackConfig or setWebpackConfig) functions.
The code is quite self-explanatory if you take into account the style-loader from webpack. Basically, you are setting some custom loaders for all files that match the regular expression, and finally, you override the default configuration with actions.replaceWebpackConfig(config).
For further details check Adding Custom webpack configuration docs.
In addition, regarding your original issue, you don't need to add your global styles in your Layout component since it will cause what you said, it will bump the page size. With Gatsby, you can use gatsby-browser.js API to add global styles like (in your gatsby-browser.js file):
import './src/your/path/to/global/style.less';
Check the link you've provided (Standard Styling with Global CSS file).

How to solve the problem "error 'Vote' is defined but never used ( no-unused-vars)"?

can you help me?.I'm getting error when i will to import file Vote.And
errors that appear like 'Vote' is defined but never used ( no-unused-vars).I tried to rename the Vote file and he result are nill.
Home.vue
import Vote from "#/components/Vote.vue";
export default {
name: "Home",
components: { Vote }
};
Vote.vue
<script> // # is an alias to /src //import HelloWorld from "#/components/HelloWorld.vue";
export default {
name: "Vote",
components: {},
data: function(){
return{ emoticons : ['calon-1','calon-2','calon-3','calon-4'] }
}
};
sounds like a linting notice.
https://eslint.org/docs/rules/no-unused-vars.
To solve this you should use your <Vote/> component somewhere in your Home.vue HTML.
I am pretty sure that your linting rules want to have a component registration with a component use inside your HTML.
That means a simple import wont solve this, because a import is not a "using".
Do you work with the Vue-CLI? if yes, which lint rule set do you use?
you can disable not needed rules in your Webpack config.
And to find your webpack.config.js we need to know which kind of settings you did in your setup CLI process.
Check your: package.json file in your root directory, is there something like esLint except the npm dependencies in there?
if not then you can create a new file in your root called .eslintrc.js and inside you paste this:
module.exports = {
root: true,
rules: {
"no-unused-vars": "off"
},
};
this will fix your problem but imho you should not disable such rules, they help you to clean code
Vote is a variable(or class). you defined it as a string here. Please change
name: "Vote"
to
name: Vote

How can I create a loader for webpack which exposes all sources via a function?

I would like to have a loader that collects all css sources and allows me to get all contents in a function. Like this:
Webpack config
module: {
loaders: [
{test: /\.css$/, loader: 'my-loader'}
]
}
JS file A (foo.js)
import './foo.css';
JS file B (bar.js)
import './bar.css';
JS file C (app.js)
import './app.css';
import getAllCSSContents from 'my-loader';
const css = getAllCSSContents();
where getAllCSSContents would return all CSS contents from foo.css, bar.css and app.css
This is a bit tricky because the loader you want to make needs to know about all CSS modules before it can generate the code it needs to return, making it stateful (loaders are meant to be pure functions that transform one input module).
You can kind of achieve what you want using raw-loader and require.context like this:
// Load all CSS files in the current directory and descendants
const context = require.context('!raw-loader!./', true, /\.css$/);
const cssFiles = {};
for (let filename of context.keys()) {
cssFiles[filename] = context(filename);
}

Render Transpiled ES6 in CSHTML

I have
Tutorial.jsx
class ShoppingList extends React.Component {
render() {
return (<div>Milk</div>);
}
}
export default ShoppingList;
webpack.config.js
module.exports = {
...
output: './React/bundle.js',
...,
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: "babel-loader",
query: {
presets: ['es2015', 'react'],
}
}
]
}
}
In my CMD prompt, when I run webpack -w everything is green and I see my bundle.js file appearing where it should, in the React folder. Opening it, I see
...
var ShoppingList = function (_React$Component) {
...
}
...
so it looks like that's all good.
Now I want to render ShoppingList in my _Layout.cshtml file.
Question: How do I do this? I've tried all methods below and get React errors all the time about invalid parameter type, or passing in the wrong element, or whatever. My CSHTML is below.
<div id="content1">render here</div>
....
<script src="~/React/bundle.js"></script>
<script>
ReactDOM.render("ShoppingList", document.getElementById("content1"));
ReactDOM.render(ShoppingList, document.getElementById("content1"));
ReactDOM.render(<ShoppingList />, document.getElementById("content1"));
</script>
Can someone please let me know if
It's possible to NOT have a ReactDOM.render() inside the JSX file and,
It's possible to do what I want to do which is render my ShoppingList in CSHTML
The best results I've got so far is to see ShoppingList in my DOM explorer but no HTML was actually rendered. It came out <shoppinglist ...></shoppinglist> which appears wrong to me.
Thanks.
You should have this inside your entry file:
import ShoppingList from 'path-to/ShoppingList';
ReactDOM.render(<ShoppingList />, document.getElementById("content1"));
In the CSHTML page the additional script tag is not required.
Your original example does not work because:
ShoppingList is not exposed globally (exporting as default does not make it global).
JSX syntax (<ShoppingList />) needs to be transpiled before it can be used in HTML page.
If you really need to use a component within a CSHTML page, you can make the component global:
window.ShoppingList = ShoppingList
inside the file that defines the component.
And use vanilla javascript instead of JSX syntax:
ReactDOM.render(React.createElement(ShoppingList), document.getElementById("content1"))

Categories

Resources