標籤:
Webpact打包React後端Node+Express前言
React官方推薦用Browserify或者Webpack 來開發React組件。
Webpack 是什嗎?是德國開發人員 Tobias Koppers 開發的模組載入器。Instagram 工程師認為這個方案很棒, 似乎還把作者招過去了。在 Webpack 當中, 所有的資源都被當作是模組, js, css, 圖片等等..Webpack 都有對應的模組 loader,如下文中將用到jsx-loader來載入帶react文法的js檔案
Express 是目前最流行的 Node.js Web MVC開發架構,最受 Web 開發人員歡迎。使用其強大的功能,開發人員可以建立單頁和多頁,和混合模式的 Web 應用程式。本執行個體用Json數組類比實現資料model模組,在Express架構下實現Restful API
[1]後端
一、安裝及配置環境[window環境]
1、開啟命令列,安裝監聽代碼變更可自動重啟node伺服器的supervisor
npm install -g supervisor
在開發nodejs程式,調試的時候,無論你修改了代碼的哪一部分,都需要重啟服務才會生效。Node.js的這種設計雖然有利於提高效能,卻不利於開發調試,因為我們在開發過程中總是希望修改後立即看到效果,而不是每次都要終止進程並重啟。supervisor 可以協助你實現這個功能,它會監視你對代碼的改動,並自動重啟 Node.js。
2、命令列全域安裝Nodejs MVC架構express。
注意:如果運行有問題可以加上版本號碼安裝。
npm install -g express
3、使用Express建立項目
cd E:\nelson\test\express\ express -t ejs commentboxcd commentboxnpm intall
如上:命令列下先定位到自己的目錄E:\nelson\test\express\ ,再輸入express -t ejs commentbox建立項目,此時,會自動產生一個commentbox檔案夾。檔案夾裡面面會有model、public、routes和views檔案夾,還有app.js和package.json兩個檔案。再命令列cd commentbox定位到commentbox檔案夾下,然後輸入npm install(這是必需的),此時,目錄下會多出node_modules檔案夾,這是node模組檔案夾。
二、編寫代碼
1、添加model檔案E:\nelson\test\express\commentbox\model\comments.js
exports.comments = [ { author : ‘小明‘, text : "Nothing is impossible, the word itself says ‘I‘m possible‘!"}, { author : ‘小強‘, text : "You may not realize it when it happens, but a kick in the teeth may be the best thing in the world for you"}, { author : ‘小兵‘, text : "Even the greatest was once a beginner. Don‘t be afraid to take that first step."}, { author : ‘拉登‘, text : "You are afraid to die, and you‘re afraid to live. What a way to exist."}];
用json數組類比後台資料,當然可以直接去連資料庫,寫資料庫連接配好model就可以了。
2、修改應用入口檔案E:\nelson\test\express\commentbox\app.js
/** * Module dependencies. */var express = require(‘express‘);var routes = require(‘./routes‘);var comment = require(‘./routes/comment‘);var http = require(‘http‘);var path = require(‘path‘);var app = express();// all environmentsapp.set(‘port‘, process.env.PORT || 3000);app.set(‘views‘, path.join(__dirname, ‘views‘));app.set(‘view engine‘, ‘jade‘);//app.use(express.favicon());app.use(express.logger(‘dev‘));app.use(express.json());app.use(express.urlencoded());app.use(express.methodOverride());app.use(express.bodyParser());app.use(app.router);app.use(express.static(path.join(__dirname, ‘public‘)));// development onlyif (‘development‘ == app.get(‘env‘)) { app.use(express.errorHandler());}app.get(‘/‘, routes.index);app.get(‘/comments‘, comment.list);app.get(‘/comments/:id‘, comment.get); app.delete(‘/comments/:id‘, comment.delete); app.post(‘/comments‘, comment.add); app.put(‘/comments/:id‘, comment.update); http.createServer(app).listen(app.get(‘port‘), function(){ console.log(‘Express server listening on port ‘ + app.get(‘port‘));});
紅色部分是自己加上去的,定義好增刪改查api介面。代碼書寫方式遵從CommonJS規範
3、增加路由/控制器設定檔E:\nelson\test\express\commentbox\routes\comment.js
/* * GET comments listing. */var comments = require(‘../model/comments‘).comments; exports.list = function(req, res){ res.json(comments); }; exports.get = function(req, res){ if(comments.length <= req.params.id || req.params.id < 0) { res.statusCode = 404; return res.send(‘Error 404: No comment found‘); } var q = comments[req.params.id]; res.json(q); }; exports.delete = function(req, res){ if(comments.length <= req.params.id) { res.statusCode = 404; return res.send(‘Error 404: No comment found‘); } comments.splice(req.params.id, 1); res.json(true); }; exports.update = function(req, res){ res.setHeader(‘Content-Type‘, ‘application/json;charset=utf-8‘); for(var i=0;i<comments.length;i++){ if(comments[i].author==req.body.author){ comments[i] = req.body; res.send({status:"success", message:"update comment success"}); console.log(comments); } } }; exports.add = function(req, res){ if(!req.body.hasOwnProperty(‘author‘) || !req.body.hasOwnProperty(‘text‘)) { res.statusCode = 400; return res.send(‘Error 400: Post syntax incorrect.‘); } var newComment = { author : req.body.author, text : req.body.text }; comments.push(newComment); res.json(true); };
這裡比較清晰的定義了增刪改查的請求處理
4、命令列輸入supervisor app.js,ok,現在開啟瀏覽器輸入localhost:3000你就可以運行並測試API介面了,也可以使用postman或者curl來測試,本例只用上了get與add請求。
supervisor app.js
瀏覽器開啟http://localhost:3000/comments
結果如下:
[ { "author": "小明", "text": "Nothing is impossible, the word itself says ‘I‘m possible‘!" }, { "author": "小強", "text": "You may not realize it when it happens, but a kick in the teeth may be the best thing in the world for you" }, { "author": "小兵", "text": "Even the greatest was once a beginner. Don‘t be afraid to take that first step." }, { "author": "拉登", "text": "You are afraid to die, and you‘re afraid to live. What a way to exist." }]
瀏覽器開啟http://localhost:3000/comments/1
結果如下:
{ "author": "小強", "text": "You may not realize it when it happens, but a kick in the teeth may be the best thing in the world for you"}
後端到此結束!
[2]前端
一、配置前端環境1、添加Webpack設定檔E:\nelson\test\express\commentbox\webpack.config.js
module.exports = { entry: [ ‘./public/assets/js/entry.js‘ ], output: { path: __dirname + ‘/public/assets/‘, publicPath: "/public/assets/", filename: ‘bundle.js‘ }, module: { loaders: [ { test: /\.js?$/, loaders: [‘jsx-loader?harmony‘] } ] }};
webpack.config.js是webpack預設的設定檔。如果改了檔案名稱要重新執行:webpack --config webpack.config.js 這樣的命令,如果不改檔案名稱就直接輸入webpack就會自動打包檔案。
2、命令列安裝各種相依模組。
npm install -g webpack(如果沒安裝wepack的話需要全域安裝)
npm install --save-dev jsx-loader
npm install --save-dev reactnpm install --save-dev react-domnpm install --save-dev markednpm install --save-dev jquery
二、編寫前端js代碼
1、編寫react 留言版組件:E:\nelson\test\express\commentbox\public\assets\js\commentbox.js
var React = require(‘react‘);var ReactDOM = require(‘react-dom‘);var marked = require(‘marked‘);var $ = require(‘jquery‘);var Comment = React.createClass({ rawMarkup: function() { var rawMarkup = marked(this.props.children.toString(), {sanitize: true}); return { __html: rawMarkup }; }, render: function() { return ( <div className="comment"> <h2 className="commentAuthor"> {this.props.author} </h2> <span dangerouslySetInnerHTML={this.rawMarkup()} /> </div> ); }});var CommentList = React.createClass({ render: function() { var commentNodes = this.props.data.map(function (comment) { return ( <Comment author={comment.author}> {comment.text} </Comment> ); }); return ( <div className="commentList"> {commentNodes} </div> ); }});var CommentForm = React.createClass({ handleSubmit: function(e) { e.preventDefault(); var author = this.refs.author.value.trim(); var text = this.refs.text.value.trim(); if (!text || !author) { return; } this.props.onCommentSubmit({author: author, text: text}); this.refs.author.value = ‘‘; this.refs.text.value = ‘‘; return; }, render: function() { return ( <form className="commentForm" onSubmit={this.handleSubmit}> <input type="text" placeholder="你的名字" ref="author" /> <input type="text" placeholder="說些什麼..." ref="text" /> <input type="submit" value="發表" /> </form> ); }});var CommentBox = React.createClass({ loadCommentsFromServer: function() { $.ajax({ url: this.props.url, dataType: ‘json‘, cache: false, success: function(data) { this.setState({data: data}); }.bind(this), error: function(xhr, status, err) { console.error(this.props.url, status, err.toString()); }.bind(this) }); }, handleCommentSubmit: function(comment) { // TODO: submit to the server and refresh the list var comments = this.state.data; var newComments = comments.concat([comment]); this.setState({data: newComments}); $.ajax({ url: this.props.url, dataType: ‘json‘, type: ‘POST‘, data: comment, success: function(data) { this.setState({data: data}); }.bind(this), error: function(xhr, status, err) { console.error(this.props.url, status, err.toString()); }.bind(this) }); }, getInitialState: function() { return {data: []}; }, componentDidMount: function() { this.loadCommentsFromServer(); setInterval(this.loadCommentsFromServer, this.props.pollInterval); }, render: function() { return ( <div className="commentBox"> <h1>我的留言板</h1> <CommentList data={this.state.data} /> <CommentForm onCommentSubmit={this.handleCommentSubmit} /> </div> ); }});module.exports = CommentBox;
這例子代碼直接與react官方代碼一樣,只是改成了CommonJs風格。注意:webpack尊從CommonJS規範,使用起來非常方便,require相應的模組,如$ = require(‘jquery‘),就可以直接使用jQuery,當然要先npm安裝了要使用的模組。
2、webpack入口js檔案:E:\nelson\test\express\commentbox\public\assets\js\entry.js
var React = require(‘react‘);var ReactDOM = require(‘react-dom‘);var CommentBox = require(‘./CommentBox‘);ReactDOM.render( <CommentBox url="/comments" pollInterval={2000} />, document.getElementById(‘commentbox‘) );
可參考第1點設定檔裡面定義好入口js檔案,名稱和路徑要一致。
3、添加留言版靜態html頁面:E:\nelson\test\express\commentbox\public\html\index.html
<!DOCTYPE html><html><head> <meta charset="utf-8"> <title>我的留言板</title></head><body> <div id="commentbox"></div> <script src="/assets/bundle.js"></script></body></html>
bundle.js檔案就是webpack打包好的js檔案,引用進來就可以直接看到效果。
4、命令列輸入webpack打包js檔案
webpack
這時,根據設定檔,在目錄E:\nelson\test\express\commentbox\public\assets下會自動產生bundle.js檔案
5、好,大功告成;這時在剛才開啟的瀏覽器頁面修改url地址為:http://localhost:3000/html/index.html,效果如下:
在頁面上面測試發表留言,測試通過,OK
前端React代碼參考自官方教程,略有改動
--React Tutorial https://facebook.github.io/react/docs/tutorial.html
後端Restful API介面參考自
--NODE.JS AND EXPRESS - CREATING A REST API http://blog.modulus.io/nodejs-and-express-create-rest-api
--nodejs+Express實現Restful的web應用 http://blog.csdn.net/jthink_/article/details/9708087
標籤: node, express, supervisor, react, Webpact, jsx-loader
Webpact打包React後端Node+Express