React bootstrap 没有设置我的 React 组件的样式 [英] React bootstrap not styling my react components
问题描述
昨天刚开始使用 React,所以设置了一个演示应用程序.环境是:
- 打字稿
- 网络包
- 反应&反应 DOM
我正在尝试设置 Bootstrap 样式.
我遵循了本教程,但对其进行了修改以适合 Typescript:
https://medium.com/@victorleungtw/how-to-use-webpack-with-react-and-bootstrap-b94d33765970
一切正常,页面显示登录表单,Bootstrap HTMl 由 React-Bootstrap 输出.但是样式并未应用于元素,它只是一个没有应用任何 Bootstrap 样式的纯 HTML 页面.我不确定配置中缺少什么:
webpack.config.js
我已经按照教程中提到的方式通过 npm 添加了加载器,但也进行了调整以从 css 设置 Typescript 模块.
module.exports = {入口: {目录:./src/apps/CatalogApp.tsx",身份验证:./src/apps/AuthApp.tsx"},输出: {文件名:[名称].bundle.js",publicPath: "/build/",路径:__dirname + "/dist"},//启用用于调试 webpack 输出的源映射.开发工具:源地图",解决: {//添加 '.ts' 和 '.tsx' 作为可解析的扩展名.扩展名:[.ts"、.tsx"、.js"、.json"]},模块: {规则: [//所有带有.ts"或.tsx"扩展名的文件都将由awesome-typescript-loader"处理.{测试:/\.tsx?$/,loader: "awesome-typescript-loader"},//所有输出 '.js' 文件都将包含由 'source-map-loader' 重新处理的所有源映射.{强制执行:预",测试:/\.js$/,加载器:源映射加载器"},//css加载器{测试:/\.css$/,loader: "typings-for-css-modules-loader?modules"},{测试:/\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/,loader: 'url-loader?limit=10000&mimetype=application/font-woff'},{测试:/\.ttf(\?v=\d+\.\d+\.\d+)?$/,loader: 'url-loader?limit=10000&mimetype=application/octet-stream'},{测试:/\.eot(\?v=\d+\.\d+\.\d+)?$/,加载器:'文件加载器'},{测试:/\.svg(\?v=\d+\.\d+\.\d+)?$/,loader: 'url-loader?limit=10000&mimetype=image/svg+xml'}]},//当导入一个路径匹配以下之一的模块时,只需//假设存在相应的全局变量并改用它.//这很重要,因为它允许我们避免捆绑我们所有的//依赖项,允许浏览器在构建之间缓存这些库.外部:{"反应": "反应","react-dom": "ReactDOM"}};
AuthApp.tsx
这是我的应用程序入口点.
import * as React from "react";import * as ReactDOM from "react-dom";从 "../components/users/SigninForm" 导入 { SigninForm };从 '../components/cart/MiniCart' 导入 { MiniCart };从'../components/users/UserMenu'导入{用户菜单};import * as bs from 'bootstrap/dist/css/bootstrap.css';import * as bst from 'bootstrap/dist/css/bootstrap-theme.css';if (document.getElementById("signin-form")) {ReactDOM.render(<登录表单/>,document.getElementById("登录表单"));}如果 (document.getElementById('cart')) {ReactDOM.render(<迷你车/>,document.getElementById('购物车'));}if (document.getElementById('user-menu')) {ReactDOM.render(<用户菜单/>,document.getElementById('用户菜单'));}
SigninForm.tsx
以及登录表单的相关用户界面.
import * as React from 'react';import * as ReactDOM from "react-dom";从反应引导"导入 { Button, Col, Row };从'../shared/Spinner'导入{微调器};接口 SigninFormProps {}接口 SigninFormState {电子邮件:字符串;密码:字符串;}导出类 SigninForm 扩展 React.Component{构造函数(道具:SigninFormProps){超级(道具);this.state = {电子邮件: '',密码: ''};this.handleChange = this.handleChange.bind(this);this.handleSubmit = this.handleSubmit.bind(this);}handleChange(事件:任何){this.setState({ [event.target.name]: event.target.value });}句柄提交(事件:任何){event.preventDefault();console.log('提交表单', this.state);}使成为() {返回 (<行><Col md={8}><form className="signin-form" onSubmit={this.handleSubmit}><div className="form-group"><label htmlFor="email">电子邮件</label><input id="email" name="email" type="email" value={this.state.email} onChange={this.handleChange}/>
<div className="form-group"><label htmlFor="password">密码</label><input id="password" name="password" type="password" value={this.state.password} onChange={this.handleChange}/>
<按钮>提交</按钮></表单></Col><Col md={4}>右边</Col></行>);}}
你使用的 webpack config 和中篇文章有点不同.
在中篇文章中,作者使用style-loader
和css-loader
来处理css
文件.
module.exports = {条目:'./main.js',输出:{ 路径:__dirname,文件名:'bundle.js' },模块: {装载机: [...{测试:/\.css$/,loader: "style-loader!css-loader"},...]},};
style-loader
会将 css 代码注入 <style/>
标签.所以这就是教程工作的原因
在你的 webpack 配置中,你使用 typings-for-css-modules-loader
来加载 css.使用此加载器,您需要将 css 类变量名称传递给 className
.
这意味着你应该写这样的代码(简化一些代码):
import * as React from "react";import * as bs from 'bootstrap/dist/css/bootstrap.css';import * as bst from 'bootstrap/dist/css/bootstrap-theme.css';从反应引导"导入 { Button, Col, Row };从'../shared/Spinner'导入{微调器};导出类 SigninForm 扩展 React.Component {...使成为() {返回 (<行><Col md={8}><form className={bt["signin-form"]} onSubmit={this.handleSubmit}><div className={bt["form-group"]}><label htmlFor="email">电子邮件</label><input id="email" name="email" type="email" value={this.state.email} onChange={this.handleChange}/>
<按钮>提交</按钮></表单></Col><Col md={4}>右边</Col></行>);}}
将 bt[classname]
传递给 className
.
我认为它会起作用.
顺便说一句,我找到了另一篇使用 typings-for-css-modules-loader
-> 链接.
Just started out using React yesterday so setting up a demo app. Environment is:
- Typescript
- Webpack
- React & React DOM
I'm trying to setup Bootstrap styles.
I followed this tutorial along but modified it to suit Typescript:
https://medium.com/@victorleungtw/how-to-use-webpack-with-react-and-bootstrap-b94d33765970
Everything works, the page displays the signin form and the Bootstrap HTMl is output by React-Bootstrap. But the styles are not applied to the elements, it's just a plain HTML page with none of the Bootstrap styles applied. I'm not sure what I'm missing from the config:
webpack.config.js
I've added the loaders through npm as mentioned in the tutorial, but also adjusted to setup Typescript modules from the css.
module.exports = {
entry: {
catalog: "./src/apps/CatalogApp.tsx",
auth: "./src/apps/AuthApp.tsx"
},
output: {
filename: "[name].bundle.js",
publicPath: "/build/",
path: __dirname + "/dist"
},
// Enable sourcemaps for debugging webpack's output.
devtool: "source-map",
resolve: {
// Add '.ts' and '.tsx' as resolvable extensions.
extensions: [".ts", ".tsx", ".js", ".json"]
},
module: {
rules: [
// All files with a '.ts' or '.tsx' extension will be handled by 'awesome-typescript-loader'.
{
test: /\.tsx?$/,
loader: "awesome-typescript-loader"
},
// All output '.js' files will have any sourcemaps re-processed by 'source-map-loader'.
{
enforce: "pre",
test: /\.js$/,
loader: "source-map-loader"
},
// css loader
{
test: /\.css$/,
loader: "typings-for-css-modules-loader?modules"
},
{
test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/,
loader: 'url-loader?limit=10000&mimetype=application/font-woff'
},
{
test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/,
loader: 'url-loader?limit=10000&mimetype=application/octet-stream'
},
{
test: /\.eot(\?v=\d+\.\d+\.\d+)?$/,
loader: 'file-loader'
},
{
test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
loader: 'url-loader?limit=10000&mimetype=image/svg+xml'
}
]
},
// When importing a module whose path matches one of the following, just
// assume a corresponding global variable exists and use that instead.
// This is important because it allows us to avoid bundling all of our
// dependencies, which allows browsers to cache those libraries between builds.
externals: {
"react": "React",
"react-dom": "ReactDOM"
}
};
AuthApp.tsx
This is my entry point for the application.
import * as React from "react";
import * as ReactDOM from "react-dom";
import { SigninForm } from "../components/users/SigninForm";
import { MiniCart } from '../components/cart/MiniCart';
import { UserMenu } from '../components/users/UserMenu';
import * as bs from 'bootstrap/dist/css/bootstrap.css';
import * as bst from 'bootstrap/dist/css/bootstrap-theme.css';
if (document.getElementById("signin-form")) {
ReactDOM.render(
<SigninForm />,
document.getElementById("signin-form")
);
}
if (document.getElementById('cart')) {
ReactDOM.render(
<MiniCart />,
document.getElementById('cart')
);
}
if (document.getElementById('user-menu')) {
ReactDOM.render(
<UserMenu />,
document.getElementById('user-menu')
);
}
SigninForm.tsx
And the relevant UI for the signin form.
import * as React from 'react';
import * as ReactDOM from "react-dom";
import { Button, Col, Row } from 'react-bootstrap';
import { Spinner } from '../shared/Spinner';
interface SigninFormProps {
}
interface SigninFormState {
email: string;
password: string;
}
export class SigninForm extends React.Component<SigninFormProps, SigninFormState> {
constructor(props: SigninFormProps) {
super(props);
this.state = {
email: '',
password: ''
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event: any) {
this.setState({ [event.target.name]: event.target.value });
}
handleSubmit(event: any) {
event.preventDefault();
console.log('Submitting form', this.state);
}
render() {
return (
<Row>
<Col md={8}>
<form className="signin-form" onSubmit={this.handleSubmit}>
<div className="form-group">
<label htmlFor="email">Email</label>
<input id="email" name="email" type="email" value={this.state.email} onChange={this.handleChange} />
</div>
<div className="form-group">
<label htmlFor="password">Password</label>
<input id="password" name="password" type="password" value={this.state.password} onChange={this.handleChange} />
</div>
<Button>Submit</Button>
</form>
</Col>
<Col md={4}>
Right Side
</Col>
</Row>
);
}
}
The webpack config you use is a little different from the medium article.
In the medium article, the author uses style-loader
and css-loader
to process css
file.
module.exports = {
entry: './main.js',
output: { path: __dirname, filename: 'bundle.js' },
module: {
loaders: [
...
{
test: /\.css$/,
loader: "style-loader!css-loader"
},
...
]
},
};
style-loader
will inject the css code to <style/>
tag. So that is why the tutorial work
In your webpack config, you use typings-for-css-modules-loader
to load css. With this loader, you need to pass the css class variable name to className
.
It means you should write the code like (simplify some code):
import * as React from "react";
import * as bs from 'bootstrap/dist/css/bootstrap.css';
import * as bst from 'bootstrap/dist/css/bootstrap-theme.css';
import { Button, Col, Row } from 'react-bootstrap';
import { Spinner } from '../shared/Spinner';
export class SigninForm extends React.Component {
...
render() {
return (
<Row>
<Col md={8}>
<form className={bt["signin-form"]} onSubmit={this.handleSubmit}>
<div className={bt["form-group"]}>
<label htmlFor="email">Email</label>
<input id="email" name="email" type="email" value={this.state.email} onChange={this.handleChange} />
</div>
<Button>Submit</Button>
</form>
</Col>
<Col md={4}>
Right Side
</Col>
</Row>
);
}
}
Pass bt[classname]
to className
.
I think it will work.
btw, I find another medium article using typings-for-css-modules-loader
-> link.
这篇关于React bootstrap 没有设置我的 React 组件的样式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!