目录
*1.上节回顾
*2.分离样式
*3.添加loader与打包
*4.简单的引用Bootstrap样式
*5.另一种方式,将Bootstrap打包进代码
1.上节回顾
本篇文档发布在距离上篇大约半年之后,团队更换,所以间歇有些空闲来继续学习React。
在上一章react中简单的数据绑定与事件中,我们直接在jsx代码中的html写上了样式,这并不友好,于是我们必须分离样式成单独的文件了。
var React = require("react");
module.exports = React.createClass({
displayName: 'panel',
getInitialState:function () {
return {
logo: "http://img.99diary.com/blog/src/201603161422/logo.jpg",
title: "让《疯狂动物城》背后的迪士尼告诉...",
publishdate:"2016-03-15"
}
},
render: function () {
return <div style={{"width":"350px","height":"300px","border":"1px solid silver","MozBoxShadow":"2px 2px 13px #333333","WebkitBoxShadow":"2px 2px 13px #333333","BoxShadow":"2px 2px 13px #333333"}}>
<div style= {{"width":"320px","height":"240px","margin":"auto auto","cursor":"pointer"}} onClick={this.showdetail}>
<img src={this.state.logo} width="320" height="240" />
</div>
<div style={{"width":"320px","height":"50px","margin":"10px auto auto auto"}}>
<div style={{"width":"40px","float":"left"}}>
<img src={this.state.logo} width="38" height="38" />
</div>
<div style={{"width":"280px","float":"left"}}>
<div>{this.state.title}</div>
<div>
{this.state.publishdate}
</div>
</div>
</div>
</div>
},
showdetail: function (event) {
this.setState(
{
title: "《疯狂动物城2》即将上映",
publishdate: "2016-03-16"
}
);
}
});
样式和HTML,js 混杂,难以维护。
2.分离样式
我们新建项目,命名: import css
我们实现如图的简单效果:
分解:
文件夹结构如下:
project--
|
|--components
| |
| |--box.jsx
| |--icon.jsx
| |--index.jsx
| |--info.jsx
|
|--css
| |--box.css
|
|--index.html
|--package.json
|--webpack.config.js
这种写法类似上一节。
小图标 icon.jsx
'use strict'
var React = require('react');
module.exports = React.createClass({
displayName: 'Icon',
render: function () {
return (
<div className='icon'>
<div className='logo'>
</div>
</div>
);
}
});
图标右侧信息 info.jsx
'use strict'
var React = require('react');
module.exports = React.createClass({
displayName: 'Info',
render: function () {
return (
<div className='info'>
<div className='title'>Customer Support</div>
<div className='describe'>Lorem ipsum dolor sit amet, consectetur adip.</div>
</div>
);
}
});
合并两者,取名 box.jsx
'use strict'
var React = require('react');
var Info = require('./info');
var Icon = require('./icon');
module.exports = React.createClass({
displayName: 'Box',
render: function () {
return (
<div className='box'>
<Icon></Icon>
<Info></Info>
</div>
);
}
});
合并到 index.jsx
'use strict'
var ReactDOM = require('react-dom');
var Box = require('./box');
ReactDOM.render(
<div>
<Box></Box>
</div>,
document.getElementById('content'));
分离出来的样式 box.css
.box{
width: 320px;
height: 60px;
background-color: #52AD81;
font-family: 'Open Sans',serif;
}
.box .icon{
width: 60px;
height: 60px;
vertical-align: middle;
float: left;
}
.box .icon .logo{
width: 40px;
height: 40px;
background-color: white;
margin: 10px auto 10px auto;
border-radius: 20px;
background-image: url('../image/0.png');
/*background-image: url('http://localhost:8889/image/0.png')*/
background-size: 100%;
background-repeat: no-repeat;
}
.box .info{
width: 260px;
height: 60px;
float: right;
color: white;
}
.box .info .title{
font-weight: 300;
padding-left: 10px;
}
.box .info .describe{
padding-left: 10px;
}
3.添加loader与打包
开始我在index.jsx
中引入box.css
require('react')
然而并什么卵用,查看了一些资料,原来是需要css loader,然后打包进去即可。
var webpack = require('webpack');
module.exports = {
// entry: './components/index.jsx',
entry: {
index: ['./components/index.jsx', './css/box.css'] //将css文件打包进去
},
output: {
filename: 'bundle.js',
publicPath: 'http://localhost:8889/dist/'
},
module: {
loaders: [
{
test: /\.jsx$/,
loader: 'jsx-loader?insertPragma=React.DOM&harmony'
},
// 添加css loader
{
test: /\.css$/,
loader: 'style-loader!css-loader'
},
// {
// test: /\.(png|jpg|gif)$/,
// loader: 'url-loader?limit=8192'
// }, // <=8k的图片使用base64内联, 其他的继续用图片
{
test: /\.(png|jpg|gif)$/,
loader: 'file-loader'
} // 图片独立(兼容<IE8的browser)
]
},
externals: {
react: 'React'
},
plugins: [
],
resolve: {
extensions: ['', '.js', '.jsx']
}
}
CMD运行 > npm start
已经有上图中效果了。
4.简单的引用Bootstrap样式
直接引入bootstrap样式,我们可以在index.html
添加引用,这里调用一个bootstrap的cdn链接:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>Hello World</title>
<meta charset="utf-8" />
<title>import css</title>
<script src="./node_modules/react/dist/react-with-addons.js"></script>
<link rel="stylesheet" href="http://cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="http://cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
<script src="http://cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script>
<script src="http://cdn.bootcss.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
</head>
<body>
<div id="content">
</div>
<!--<script src="http://localhost:8889/vendor.js"></script>-->
<!--注意这里的路径,要和配置文件端口设置一致-->
<script src="http://localhost:8889/webpack-dev-server.js"></script>
<script type="text/javascript" src="http://localhost:8889/dist/bundle.js"></script>
</body>
</html>
为了证明引用成功,我们添加一个div来展示bottstrap中panel效果。
在components
文件夹中添加 panel.jsx 文件:
'use strict'
var React = require('react');
module.exports = React.createClass({
displayName: 'Panel',
render: function () {
return (
<div className='row'>
<div className='col-sm-4'>
<div className="panel panel-default">
<div className="panel-heading">
<h3 className="panel-title">Panel title</h3>
</div>
<div className="panel-body">
Panel content
</div>
</div>
</div>
</div>
);
}
});
在index.jsx
中添加对panel
的引用。
页面被刷新,bootstarp效果生效。
右侧可以猜测,我们自己分离的box.css
也可以使用这种方式引用,这样就不会打包进我们的代码。
当然,这里是学习,我们可以尝试将bootstrap文件简单的打包到我们的代码中。
5.另一种方式,将Bootstrap打包进代码
删除html中关于Bootstrap的引用(注释会在打包时候报错…),将Bootstrap文件保存到本地并放入lib/bootstrap
文件夹中,修改webpack.config.js
。
注意:bootstrap中引用了一些字体,需要去掉bootstrap.min.css中的字体引用,不然会报错
var webpack = require('webpack');
module.exports = {
// entry: './components/index.jsx',
entry: {
index: [
'./components/index.jsx',
'./lib/bootstrap/bootstrap-theme.min.css',
'./lib/bootstrap/bootstrap.min.css',
'./lib/bootstrap/jquery.js',
'./lib/bootstrap/bootstrap.min.js',
'./css/box.css'
] //将css文件打包进去
},
output: {
filename: 'bundle.js',
publicPath: 'http://localhost:8889/dist/'
},
module: {
loaders: [
{
test: /\.jsx$/,
loader: 'jsx-loader?insertPragma=React.DOM&harmony'
},
// 添加css loader
{
test: /\.css$/,
loader: 'style-loader!css-loader'
},
// {
// test: /\.(png|jpg|gif)$/,
// loader: 'url-loader?limit=8192'
// }, // <=8k的图片使用base64内联, 其他的继续用图片
{
test: /\.(png|jpg|gif)$/,
loader: 'file-loader'
}// 图片独立(兼容<IE8的browser)
]
},
externals: {
'react': 'React'
},
plugins: [
],
resolve: {
extensions: ['', '.js', '.jsx', 'css']
}
}
CMD运行 > npm start
然而报错
bundle.js:21322 Uncaught Error: Bootstrap's JavaScript requires jQuery(…)
bootstrap库虽然被打包但是依然报错缺少jquery依赖。
尝试将jquery暴露给全局的变量的方法,修改webpack.config.js
,
这里采用知乎网友给出的方法:
jQuery 直接在 html 中引入,然后在 webpack 中把它配置为全局即可。
externals: {
jquery: 'window.$'
},
使用则直接 require 进来,反正 webpack 也不会把它打包进来。
var $ = require('jquery');
既然 $ 已经被设置为全局了,那么挂载在它下面的一系列 jQuery 插件就好办了,直接在 html 中引入。
<script type="text/javascript" src="./src/lib/jquery-1.11.1.min.js"></script>
<script type="text/javascript" src="./src/lib/jquery.nail.min.js"></script>
js 中引入 jquery 直接使用即可。
var $ = require('jquery');
$('#leftNav').nail();
然后看我们自己的代码,
修改webpack.config.js
externals: {
'react': 'React',
'jquery': 'window.$'
},
在index.html
中添加对jquery.js
的引用:
<script src="lib/bootstrap/jquery.min.js"></script>
这个时候Juqey已经被暴露给全局,再次将bootstrap
打包进去必然可以使用。
再次修改webpack.config.js
:
entry: {
index: [
'./components/index.jsx',
'./lib/bootstrap/bootstrap-theme.min.css',
'./lib/bootstrap/bootstrap.min.css',
'./lib/bootstrap/bootstrap.min.js',
'./css/box.css'
] //将css文件打包进去
},
CMD运行 > npm start
,页面已经能够复现 4 所显示的效果。
上两节目录: