koa+react(二)

这一节继续讲如何使用react和koa进行前后端分离的项目结构。

安装react依赖项

1
$ npm i --save react react-dom

新建文件夹app在项目根目录下
app/main.js和app/hello.js
内容分别为

1
2
3
4
5
6
7
8
9
10
11
12
// app/main.js
import React from 'react';
import Hello from './hello.js';
render(
<Hello />,
document.getElementById('root')
);
// app/hello.js
module.exports = function Hello() {
return <div>Hello World!</div>;
};

注:这里在你保存的时候,eslint会报各种错,包括no-undef和jsx错误,这时候就要把eslint优化一下了,如下:
先安装一个依赖:

1
$ npm i --save-dev eslint-plugin-jsx-a11y

.eslintrc.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
{
"env": {
"node": true,
"es6": true,
"jquery": true,
"browser": true
},
"parser": "babel-eslint",
"rules": {
"global-require": 0,
"object-curly-spacing": 0,
"valid-jsdoc": 2,
"max-len": [1, 150, 2],
"no-console": 1,
"no-var": 0,
"no-undef": 2,
"import/no-unresolved": [2, { "ignore": ["loader|react-router|css|style|sass"] }],
"import/extensions": 0,
"no-param-reassign": [1, { "props": false }],
"quotes": [2, "single"],
"semi": 2,
"arrow-body-style": [1, "as-needed"],
"comma-dangle": [2, "never"],
"react/jsx-uses-react": 1,
"react/wrap-multilines": 2,
"no-underscore-dangle": [2, { "allow": ["__INITIAL_STATE__"] }],
"react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }]
},
"extends": "airbnb",
"plugins": [
"react"
]
}

现在保存app里面的前端文件就不会报eslint错误啦。

页面

新建views/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>Webpack Sample Project</title>
</head>
<body>
<div id='root'>
</div>
<script src="bundle.js"></script>
</body>
</html>

koa模板引擎配置

server.js添加代码后变成:在这之前先安装koa-views

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import Koa from 'koa';
import views from 'koa-views';
import path from 'path';
const app = new Koa();
app.use(require('koa-static')(path.join(__dirname, '../build')));
app.use(views(path.join(__dirname, '../views'), {
extension: 'html'
}));
app.use(async (ctx, next) => {
const start = new Date();
await next();
const ms = new Date() - start;
console.log(`${ctx.method} ${ctx.url} - ${ms}ms`);
});
// response
app.use(async(ctx) => {
await ctx.render('index.html');
});
app.listen(3000);

安装webpack打包工具

1
2
3
$ npm i --save webpack
$ npm i -g webpack
$ npm i --save-dev babel-loader

添加webpack.config.dev.js文件到项目根目录下,内容为:(配置后面h还会进一步按需求优化,可以参考官方文档)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
const webpack = require('webpack');
module.exports = {
devtool: 'eval-source-map',
entry: `${__dirname}/app/main.js`,
output: {
path: `${__dirname}/build`,
filename: 'bundle.js'
},
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel'
}
]
},
plugins: [
new webpack.optimize.OccurenceOrderPlugin(),
// new webpack.optimize.UglifyJsPlugin(),
new webpack.HotModuleReplacementPlugin(),
new webpack.optimize.DedupePlugin(),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify(process.env.NODE_ENV)
}
})
]
};

注意:不管项目是否配置了babel,webpack是属于打包前端项目的,添加babel-loader可以使你的前端模块也支持使用es6语法。如果项目中没有.babelrc文件,可以在loaders里面添加preset,像这样,

1
2
3
4
5
6
7
8
{
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
loader: 'babel',
query: {
presets: ['es2015']
}
}

也可以添加一个.babelrc文件在根目录,webpack会自动提取里面的preset来加载。

打包启动

都配好了就可以准备启动了,执行以下命令:

1
2
3
$ webpack
# 或者runkoa server/server.js
$ nodemon server/babel.js

可以看到目录下生成一个build文件,访问localhost:3000可以看到页面打印出Hello World!

写的累死了,,如果有错,希望大家提出来,我自己也会走一遍看看哪里有错有漏说的。。。
未完待续。。。

如果您觉得受益了,欢迎打赏鼓励。