第一章:搭建react开发环境
当我们抛开React其生态中的其他库(Redux,React-Router)来看,它本身仅仅是由少量API构成的一个Web库。
打造kodo的目标是希望大家可以通过简单的UI库来重新认识React其本身,而不是夹杂在其他东西中去学习它。我们的目标是使用最新的ES2015来编写完我们的UI库,并且使用了React 15.0.2版本做为基础。
使用到的工具
Webpack
正如官网对 Webpack 的描述,它是一种模块化加载器,当然也不仅仅限于此。某种程度上来说,可以代替某些gulp的功能,至少有些还是无法替代的。在webpack中所有的资源都会被视作模块来处理,为了应对这样的情况,webpack有对应的loader机制来处理,另外shim,plugins,和其他构建工具,一样一样的,更多的细节,需要你在实际的应用中慢慢去体会了。
你可以阅读如下两篇文章:
Babel
Babel 是一个 JavaScript 编译器,用于将你的ES2015代码转换成ES5跑在浏览器中。
NPM包依赖管理
做为Node世界里的包管理器,我想大家从Grunt时代起就已经熟练的使用npm install命令来安装一些依赖完成前端自动化构建任务。
更多的信息你可以通过阅读玩转NPM来增加理解。
nodemon和koa
nodemon可以用来监控文件并且重启Node服务器,koa是Node世界里的一个Web开发框架。由于kodo项目用koa写了一个静态服务器,所以且需要使用它。如果你有browser-sync
的使用经验,你可以替换成它。(请原谅我的偷懒)
React Dev Tools
调试工具:React Dev Tools
开始行动
- 将工具--save-dev到应用开发环境
- 将react,react-dom,classnames,normalize.css --save到你的应用依赖环境
- 如果你需要漂亮的icon,请求引用ionic提供的icon库
你所需要的工具列表:
"devDependencies": {
"babel-core": "^6.8.0",
"babel-loader": "^6.2.4",
"babel-preset-es2015": "^6.6.0",
"babel-preset-react": "^6.5.0",
"css-loader": "^0.23.1",
"extract-text-webpack-plugin": "^1.0.1",
"koa": "^1.2.0",
"koa-logger": "^1.3.0",
"koa-static": "^2.0.0",
"less": "^2.6.1",
"less-loader": "^2.2.3",
"nodemon": "^1.9.2",
"webpack": "^1.13.0"
}
你的应用依赖环境:
"dependencies": {
"classnames": "^2.2.5",
"normalize.css": "^4.1.1",
"react": "^15.0.2",
"react-dom": "^15.0.2"
}
使用npm install xxx
命令来安装它们吧。
kodo项目已经使用了package.json文件来管理依赖,如果你是在跑kodo项目,请直接npm install 即可。
目录结构说明
总体而言kodo
项目的目录结构分为了bin
,src
,test
,examples
四个目录。
bin
目录中放置了Webpack
所使用的配置文件webpack.config.js
src
目录少许复杂,内部又分了index.js
入口文件,util
工具函数目录,components
组件放置的目录,stylesheets
less文件放置的目录test
目录放置了单元测试文件examples
目录放置了demo的html文件
Webpack配置说明
var path = require('path');
var webpack = require('webpack');
var plugins = [];
var env = process.env.NODE_ENV;
var containerPath = path.resolve('.');
var config = {
entry: './src/index.js',
devtool: 'source-map',
output: {
path: path.resolve(containerPath,'dist/'),
filename: 'kodo.js',
library: 'Kodo',
libraryTarget: 'umd'
},
module:{
loaders: [
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/,
query: {
presets: ['react','es2015']
}
}
]
},
externals: [
{
'react': {
root: 'React',
commonjs2: 'react',
commonjs: 'react'
}
},
{
'react-dom': {
root: 'ReactDOM',
commonjs2: 'react-dom',
commonjs: 'react-dom'
}
}
],
extensions: ['', '.js', '.css', '.scss', '.jade', '.png', '.jpg'],
plugins:plugins
};
module.exports = config;
if (env === 'production') {
config.plugins.push(new webpack.DefinePlugin({
'process.env': {
'NODE_ENV': JSON.stringify(env)
}
}));
config.devtool = 'eval-source-map';
config.output.filename = 'kodo-min.js';
}
这里主要通过NODE_ENV参数production
来区分dev环境还是需要压缩的环境,在这里你只需要关注配置好babel即可。
How Run?
现在你可以运行npm run dev
和npm run dev-server
来启动webpack的构建和一个web服务器,如果你使用了npm run dev-server,你还需要在启动命令之前安装nodemon(建议全局安装)。
创建一个React组件
以Mask
蒙板为例,如果你已经成功运行了kodo项目,你可以访问http://127.0.0.1:3001/examples/dialog.html,点击一个任意的对话框,查看Mask组件的效果。
- 在
components
中创建一个mask
目录,并且在mask
目录中创建index.js
文件。
因为mask
是一个非常简单的组件,所以我用函数来编写,不继承React.Componet
。
import classNames from 'classnames';
function Mask(props){
const { type } = props;
const css = classNames({
'overlay active': true,
['overlay-'+ type]: !!type
});
return (
<div className={ css }></div>
);
}
export default Mask;
最后你可以在dialog中查看使用的方式(Mask):
import React,{ PropTypes } from 'react';
import classNames from 'classnames';
import Mask from '../mask/';
import Alert from './Alert';
import Confirm from './Confirm';
const propTypes = {
type: PropTypes.string,
show: PropTypes.bool,
title: PropTypes.string,
buttons: PropTypes.array,
}
const defaultProps = {
type: 'alert',
show: false,
title: '',
buttons: []
}
class Dialog extends React.Component {
render (){
const { type, show, className, title } = this.props;
const css = classNames({
'dialog-wrap': true,
'active': show,
[className]: className
});
const Component = type === 'alert' ? Alert : Confirm;
return (
<section
className={ css }
>
<Mask type="dialog"/>
<Component {...this.props }/>
</section>
);
}
}
Dialog.propTypes = propTypes;
Dialog.defaultProps = defaultProps;
export default Dialog;