react-04-前端工事搭建-react客户端渲染

概览: react,sass,webpack的使用 , 客户端渲染

react原本就是用来客户端渲染的, redux则是flux思想的实现,用来处理单向的数据绑定. 现在也可以都拿来在服务器端渲染首屏页面.
现在先从它原本的职责浏览器端渲染开始熟悉. 项目又切换到 express-server 作为服务器
在建立一个react项目作为客户端,使用webpack打包构建 webpack文档

预备工作

使用 CSS预处理器 sass

文档: sass十分钟入门 , 阮一峰的blog
安装命令 npm uninstall node-sass , npm install sass-loader node-sass webpack --save-dev
webpack 配置 sass的加载器 见 sass-loader
目录结构:

/index.html , 引入的bundle.js是 将js和css打包后的结果

1
2
3
4
5
6
7
8
9
10
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>index</title>
</head>
<body>
<script type="text/javascript" charset="utf-8" src="bundle.js"></script>
</body>
</html>

/index.js , webpack的想法就是万物皆可require

1
2
require('./style.scss');
document.write('<div>你是这个世界上无与伦比的美丽</div>');

/package.json , devDependencies的意思是开发依赖工具,不会被打包到最终的js中

1
2
3
4
5
6
7
8
9
10
11
12
{
"name": "react-client",
"version": "0.0.1",
"scripts": {
"start": "webpack-dev-server"
},
"devDependencies": {
"node-sass": "^3.9.3",
"sass-loader": "^4.0.2",
"webpack": "^1.13.2"
}
}

/style.scss 这里示例了scss变量,Mixin的使用

1
2
3
4
5
6
7
8
9
10
11
12
13
$bodyColor: pink;
$divColor: blue;
@mixin divFacade($width:100px,$height:100px,$color:yellow) {
width: $width;
height: $height;
background-color: $color;
}
body {
background: $bodyColor;
}
div {
@include divFacade(330px, 140px, $divColor)
}

/webpack.config.js ,webpack打包配置,entry入口,output出口,loaders指定加载器,这里使用正则匹配到scss文件并使用sass加载器编译

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
module.exports = {
entry: './index.js',
output: {
path: __dirname,
filename: 'bundle.js'
},
module: {
loaders: [
{
test: /\.scss$/,
loaders: ["style", "css", "sass"]
}
]
}
};

react的使用

参考文档 : React.createClass和extends Component的区别 , React 入门实例教程

这里开始要把工程结构变得合理一点 , 如图:

/dist/ 目录为编译后js存放之地 , 一般有一个应用js和应用依赖库的打包文件,这里是把react,redux等库打包到vendors.js.在html里需要将这两个文件引入.
/src/components/ 为组件目录 , 一个组件一个目录,对应一个样式文件 ,这里是css in js写法,参考 react-css-modules 打包时会统统打包进app.js . variables.scss为全局的样式定义文件
/src/index.js 为打包路径的入口 , webpack会根据依赖进行打包.

/webpack.config.js , 加了sass编译器,将scss样式文件转为普通css, 加入babel编译器, 将jsx和es6语法转为大多浏览器兼容的es5语法.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
var path = require('path');
var webpack = require('webpack');

module.exports = {
entry: {
app: path.join(__dirname, 'src'),
vendors: ['react', 'redux']
},
output: {
path: path.join(__dirname, 'dist'),
publicPath: "/dist/",
filename: '[name].js'
},
module: {
loaders: [
{test: /\.scss$/, loaders: ["style", "css", "sass"]},
{test: /\.js?$/, exclude: /node_modules/, loader: 'babel', query: {presets: ['react', 'es2015']}}
]
},
plugins: [
new webpack.optimize.CommonsChunkPlugin('vendors', 'vendors.js')
]
};

/package.json webpack-dev-server 是个开发服务器,可对js/css文件热部署

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{
"name": "react-client",
"version": "0.0.1",
"scripts": {
"build": "webpack",
"start": "webpack-dev-server"
},
"devDependencies": {
"node-sass": "^3.9.3",
"sass-loader": "^4.0.2",
"webpack": "^1.13.2",
"babel-core": "^6.4.0",
"babel-loader": "^6.2.1",
"babel-preset-es2015": "^6.3.13",
"babel-preset-react": "^6.3.13",
"path": "^0.12.7",
"react": "^0.14.6",
"react-dom": "^0.14.6",
"react-redux": "^4.0.6",
"redux": "^3.0.5"
}
}

/index.html

1
2
3
4
5
6
7
8
9
10
11
12
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>index</title>
</head>
<body>
<div id="app"></div>
<script src="dist/vendors.js"></script>
<script type="text/javascript" charset="utf-8" src="dist/app.js"></script>
</body>
</html>

/src/index.js render 方法将react组件渲染到html节点

1
2
3
4
5
import React from "react";
import {render} from "react-dom";
import Demo from './components/Demo/Demo';

render(<Demo />, document.getElementById('app'));

/src/components/variables.scss 组件共用的样式 ,一般放置全局变量和mixin , 在组件的样式文件中通过 @import "../variables"; 引入

1
2
3
4
5
$bodyColor: pink;

body {
background: $bodyColor;
}

/src/components/Demo/Demo.js 这个react组件语法要记住,另外引入外部样式,使用 className 属性 , 尝试了 className={s.demo} 没有成功,尚不清楚原因

1
2
3
4
5
6
7
8
import React from "react";
import s from "./style.scss";

export default class Demo extends React.Component{
render(){
return <div className="demo">你是这个世界上无与伦比的美丽~</div>
}
}

/src/components/Demo/style.scss

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@import "../variables";

$divColor: lightblue;
$demoColor: seashell;

@mixin divFacade($width:100px,$height:100px,$color:yellow) {
width: $width;
height: $height;
background-color: $color;
}

div {
@include divFacade(330px, 140px, $divColor)
}
.demo {
background-color: $demoColor;
}

预览

推荐文章