概览: 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; }
|
预览