从今天开始,准备每天写一篇技术日志了,已经从C++到 As3、Java 再到 C# ,现在对Node渐渐熟悉了。觉得这篇文章写的不错,翻译一下。
介绍:
Node.js 在过去的几年已经有了较好的发展,很多互联网巨头例如Walmart、PayPal 都已经在应用它了。越来越多的人开始熟悉node,并且在NPM上发布自己的Node模块。然而,Node的概念不是那么容易理解的,尤其如果你是从其他语言转向Node的话。
在这一组文章中,我们将会讨论Node开发者最长犯的错误以及如何避免犯这些错误。你可以在这里找到这些源码:github。
常见错误一:不使用开发状态下的一些工具
- nodemon or supervisor for automatic restart
- In-browser live reload (reload after static files and/or views change)
1.1 自动重启
我们都习惯在编辑器中保存一个文件, 按下 ctrl + c 关闭应用,然后按下 up 键,enter键重启。
其实还可以使用以下几个工具自动的做这些重复的工作,让你的开发过程变的更加简洁。
这些模块的作用就是监控文件变化,并且重启服务,让我们用nodemon实验一下,首先全局安装这个模块插件。
<pre name="code" class="plain"> npm i nodemon -g
然后,就只需要简单的替换node命令为nodemon命令:
<pre name="code" class="plain"> # node server.js
$ nodemon server.js
14 Nov 21:23:23 - [nodemon] v1.2.1
14 Nov 21:23:23 - [nodemon] to restart at any time, enter `rs`
14 Nov 21:23:23 - [nodemon] watching: *.*
14 Nov 21:23:23 - [nodemon] starting `node server.js`
14 Nov 21:24:14 - [nodemon] restarting due to changes...
14 Nov 21:24:14 - [nodemon] starting `node server.js`
在nodemon或者node-supervisor最常见的选项命令中,可能 “忽略某些特定文件或者文件夹”这个选项是最常见的。
</pre><pre name="code" class="javascript" style="font-family: Consolas, Monaco, 'Andale Mono', monospace;">1.2 自动浏览器刷新
在<span style="font-family: Consolas, Monaco, 'Andale Mono', monospace;">脚本代码产生了变化,这不仅对</span><span style="font-family: Consolas, Monaco, 'Andale Mono', monospace;">加载Node应用有用,也会对web应用产生作用。 使用这个工具类似livereload,我们不用手动刷新网页,让一切都变得自动化。</span>
<span style="font-family:Consolas, Monaco, Andale Mono, monospace;">它的工作原理和之前描述的一致,由于这个工具会检测特定文件夹的文件变化,并且触发浏览器刷新。这个刷新可以通过一个内嵌脚本实现或者是通过一个浏览器插件实现。</span>
</pre><pre name="code" class="javascript" style="font-family: Consolas, Monaco, 'Andale Mono', monospace;">接下来,我们自己来创建一个相似的工具来介绍 如何使用 livereload:
</pre><pre name="code" class="javascript" style="font-family: Consolas, Monaco, 'Andale Mono', monospace;">*检测一个文件夹的文件变化
*给所有使用server-sent 事件的连接的客户端发送一个消息
*触发页面重新加载
</pre><pre name="code" class="javascript" style="font-family: Consolas, Monaco, 'Andale Mono', monospace;">首先,我们需要安装工程所需要的npm依赖:
<ul style="font-family: 'Open Sans', 'Century Gothic'; box-sizing: border-box; margin: 10px 0px 15px 10px; max-width: 620px; padding-left: 15px; color: rgb(126, 127, 127); font-size: 15px;"><li style="box-sizing: border-box;"><a target=_blank href="http://npm.im/express" style="box-sizing: border-box; color: rgb(206, 84, 36); text-decoration: none; cursor: pointer; background: 0px 0px;">express</a> - for creating the sample web application</li><li style="box-sizing: border-box;"><a target=_blank href="http://npm.im/watch" style="box-sizing: border-box; color: rgb(206, 84, 36); text-decoration: none; cursor: pointer; background: 0px 0px;">watch</a> - to watch for file changes</li><li style="box-sizing: border-box;"><a target=_blank href="http://npm.im/sendevent" style="box-sizing: border-box; color: rgb(206, 84, 36); text-decoration: none; cursor: pointer; background: 0px 0px;">sendevent</a> - server-sent events, SSE (an alternative would have been websockets)</li><li style="box-sizing: border-box;"><a target=_blank href="http://npm.im/uglify-js" style="box-sizing: border-box; color: rgb(206, 84, 36); text-decoration: none; cursor: pointer; background: 0px 0px;">uglify-js</a> - for minifying the client-side JavaScript files</li><li style="box-sizing: border-box;"><a target=_blank href="http://npm.im/ejs" style="box-sizing: border-box; color: rgb(206, 84, 36); text-decoration: none; cursor: pointer; background: 0px 0px;">ejs</a> - view templates</li></ul><div><span style="font-family:Open Sans, Century Gothic;color:#7e7f7f;"><span style="font-size: 15px;"></span></span><pre name="code" class="javascript" style="line-height: 18px; font-family: Consolas, Monaco, 'Andale Mono', monospace;">
<pre name="code" class="javascript" style="line-height: 18px; font-family: Consolas, Monaco, 'Andale Mono', monospace;">然后,我们将创建一个简单的Express服务器,渲染一个home主页。
<pre name="code" class="javascript">var express = require('express');
var app = express();
var ejs = require('ejs');
var path = require('path');
var PORT = process.env.PORT || 1337;
// view engine setup
app.engine('html', ejs.renderFile);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'html');
// serve an empty page that just loads the browserify bundle
app.get('/', function(req, res) {
res.render('home');
});
app.listen(PORT);
console.log('server started on port %s', PORT);
因为用了Express,所以我们将创建一个Express的中间件作为浏览器刷新工具。这个中间件将会连接SSE 端 ,并且为客户端脚本创建一个显示帮助。中间件函数的参数将会在Express app中或者被监控的文件夹中。 那我们接下来添加以下几行到server.js中:
</pre><pre name="code" class="javascript" style="line-height: 18px; font-family: Consolas, Monaco, 'Andale Mono', monospace;"><pre name="code" class="javascript">var reloadify = require('./lib/reloadify');
reloadify(app, __dirname + '/views');
我们现在监控的是 /views文件夹的变化。 然后是我们的中间件:
<pre name="code" class="javascript"> var sendevent = require('sendevent');
var watch = require('watch');
var uglify = require('uglify-js');
var fs = require('fs');
var ENV = process.env.NODE_ENV || 'development';
// create && minify static JS code to be included in the page
var polyfill = fs.readFileSync(__dirname + '/assets/eventsource-polyfill.js', 'utf8');
var clientScript = fs.readFileSync(__dirname + '/assets/client-script.js', 'utf8');
var script = uglify.minify(polyfill + clientScript, { fromString: true }).code;
function reloadify(app, dir) {
if (ENV !== 'development') {
app.locals.watchScript = '';
return;
}
// create a middlware that handles requests to `/eventstream`
var events = sendevent('/eventstream');
app.use(events);
watch.watchTree(dir, function (f, curr, prev) {
events.broadcast({ msg: 'reload' });
});
// assign the script to a local var so it's accessible in the view
app.locals.watchScript = '<script>' + script + '</script>';
}
module.exports = reloadify;
也许你们注意到了,如果这个环境没有被设置成 “开发模式” 这个中间件是不会工作的,这就意味着,我们并不需要在“产品模式”移除这个中间件。
前端JS文件是更简单的,仅仅是监听SSE消息,在需要的时候重新刷新加载页面。
</pre><pre name="code" class="javascript" style="line-height: 18px; font-family: Consolas, Monaco, 'Andale Mono', monospace;"></pre><pre name="code" class="javascript" style="line-height: 18px; font-family: Consolas, Monaco, 'Andale Mono', monospace;">
</pre><pre name="code" class="javascript"> (function() {
function subscribe(url, callback) {
var source = new window.EventSource(url);
source.onmessage = function(e) {
callback(e.data);
};
source.onerror = function(e) {
if (source.readyState == window.EventSource.CLOSED) return;
console.log('sse error', e);
};
return source.close.bind(source);
};
subscribe('/eventstream', function(data) {
if (data && /reload/.test(data)) {
window.location.reload();
}
});
}());
</pre>这个eventsource-plyfill.js脚本是<a target=_blank target="_blank" href="https://github.com/remy/polyfills/blob/master/EventSource.js" style="color:rgb(206,84,36); text-decoration:none; font-family:'Open Sans','Century Gothic'; font-size:16px; line-height:26px">Remy Sharp's polyfill for SSE</a>, 现在最后一步:使用这个显示帮助工具,包含前端生成的脚本到页面<span style="color:rgb(77,77,87); font-family:'Open Sans','Century Gothic'; font-size:16px; line-height:26px">(</span><code style="font-size:14.3999996185303px; font-family:Menlo,Monaco,Consolas,'Courier New',monospace; padding:2px 4px; color:rgb(199,37,78); line-height:26px; background-color:rgb(249,242,244)">/views/home.html</code><span style="color:rgb(77,77,87); font-family:'Open Sans','Century Gothic'; font-size:16px; line-height:26px">) </span><pre>
...
<%- watchScript %>
...
好了,现在你不管怎么变化home.html页面,这个浏览器将会自动的刷新主页。
(今天就写到这里吧,明天继续。)
原文请戳这里:https://www.airpair.com/node.js/posts/top-10-mistakes-node-developers-make