Files
expressjs.com/2x/migrate.html
2014-09-17 23:50:47 +05:30

418 lines
13 KiB
HTML

<html>
<head>
<title>Express - node web framework</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-25235225-1']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
<style>
#warning {
background: #cb0000;
color: #eeeeee;
border-radius: 3px;
padding: 10px 16px;
}
#tagline {
margin-left: 75px;
margin-bottom: 30px;
color: rgba(255,255,255,0.7); }
html {
background: #1c1c1c url(images/bg.tile.jpg); }
body {
margin: 0;
padding-bottom: 30px;
font: 14px/1.4 "Helvetica Neue", "Lucida Grande", "Arial";
font-size: 14px;
line-height: 1.5;
-webkit-font-smoothing: antialiased;
background: url(images/bg.jpg) 50% 0 no-repeat;
color: #8b8b8b; }
* {
outline: none; }
em {
color: white; }
a img {
border: none !important; }
a {
font-weight: bold;
text-decoration: none;
color: white;
-webkit-transition-property: opacity, -webkit-transform, color, background-color, padding, -webkit-box-shadow;
-webkit-transition-duration: 0.15s;
-webkit-transition-timing-function: ease-out; }
a:hover {
opacity: 0.8; }
h1, h2, h3, h4 {
margin: 45px 0 0 0;
color: white;
text-shadow: 1px 2px 2px rgba(0,0,0,0.6); }
h3 {
font-size: 18px; }
h4 {
margin-left: 10px;
font-size: 14px;
}
pre {
margin: 20px 10px;
padding: 25px 20px;
background: rgba(0,0,0,0.5);
border: 1px solid #323232;
-webkit-box-shadow: 1px 2px 2px rgba(0,0,0,0.6);
-moz-box-shadow: 1px 2px 2px rgba(0,0,0,0.6);
-webkit-border-radius: 5px;
-moz-border-radius: 5px; }
code {
font-family: "Helvetica Neue", "Lucida Grande", "Arial"; }
ul {
margin: 15px 0;
padding: 0 0 0 35px; }
ul li {
margin: 0;
padding: 2px 0;
list-style: square; }
ul li ul {
margin: 0;
padding-left: 12px;
}
.man-name, #Express { display:none; }
.sect {
margin-left: 40px; }
img {
margin-left: 20px;
margin-bottom: 15px;
}
#logo {
display: block;
margin-left: 30%;
margin-bottom: 30px;
width: 194px;
height: 51px;
background: url(images/logo.png) 0 0 no-repeat;
text-indent: -99999px; }
#logo:hover {
opacity: 0.7; }
#logo:active {
opacity: 0.3; }
#ribbon {
position: fixed;
top: 0;
right: 0;
z-index: 2; }
#wrapper {
width: 100%;
min-height: 800px;
background: url(images/top.png) 0 0 repeat-x; }
#container {
margin: 0 auto;
padding-top: 80px;
width: 550px; }
#toc {
position: fixed;
top: 0;
left: 0;
margin: 0 0 0 15px;
padding: 15px;
height: 100%;
background: rgba(0,0,0,0.2);
overflow: auto;
border-right: 1px solid rgba(255,255,255,0.05);
}
#toc li {
padding: 0;
list-style: none;
}
#toc li a {
font-size: 11px;
}
#menu {
margin-left: 75px;
padding: 0;
padding-bottom: 30px; }
#menu li {
display: inline;
list-style: none; }
#menu li a {
display: block;
float: left;
margin: 0 2px;
padding: 3px 15px;
background: rgba(0,0,0,0.2);
-webkit-border-radius: 8px;
-moz-border-radius: 8px;
-webkit-box-shadow: 1px 2px 2px rgba(0,0,0,0.6);
-moz-box-shadow: 1px 2px 2px rgba(0,0,0,0.6);
-webkit-transition-property: opacity, -webkit-transform, color, background-color, -webkit-box-shadow;
-webkit-transition-duration: 0.15s;
-webkit-transition-timing-function: ease-out; }
#menu li a:hover,
#menu li a.active {
background: rgba(0,0,0,0.5); }
#menu li a:active {
background: rgba(0,0,0,0.1);
-webkit-box-shadow: 1px 1px 1px rgba(0,0,0,0.4);
-moz-box-shadow: 1px 1px 1px rgba(0,0,0,0.4); }
</style>
<script>
$(function(){
$('.section').hide();
$('.toggle, a.section-title').toggle(function(){
$(this).siblings('ul').fadeIn(300);
return false;
}, function(){
$(this).siblings('ul').fadeOut(300);
return false;
});
});
</script>
</head>
<body>
<a href='http://github.com/visionmedia/express'>
<img alt='Fork me on GitHub' id='ribbon' src='http://s3.amazonaws.com/github/ribbons/forkme_right_white_ffffff.png' />
</a>
<div id="wrapper">
<div id="container">
<a href='http://github.com/visionmedia/express' id='logo'>Express</a>
<div id="warning">
<center><strong>Express 2.x</strong> IS NO LONGER MAINTAINED</center>
<p>Known and unknown security and performance issues in 2.x have not been addressed since the last update (29 June, 2012). It is highly recommended to <a href="https://github.com/strongloop/express/wiki/Migrating-from-2.x-to-3.x">upgrade to <strong>Express 3.x</strong></a> or to <a href="http://expressjs.com/4x/api.html"><strong>Express 4.x</strong></a>.</p>
</div>
<p id="tagline">
High performance, high class web development for
<a href="http://nodejs.org">Node.js</a>
</p>
<ul id="menu">
<li><a href="index.html">Home</a></li>
<li><a href="guide.html">Guide</a></li>
<li><a href="screencasts.html">Screencasts</a></li>
<li><a href="applications.html">Applications</a></li>
</ul>
<h3>Express 1.x to 2.x Migration</h3>
<h3>HTTPS</h3>
<p> Creating an HTTPS server is simply, simply pass the TLS options to <em>express.createServer()</em>:</p>
<pre><code> var app = express.createServer({
key: ...
, cert: ...
});
app.listen(443);
</code></pre>
<h3>req.header() Referrer</h3>
<p> Previously if anyone was doing something similar to:</p>
<pre><code> req.headers.referrer || req.headers.referer
req.header('Referrer') || req.header('Referer')
</code></pre>
<p> With the new special-case we may now simply use <em>Referrer</em> which will return either if defined:</p>
<pre><code> req.header('Referrer')
</code></pre>
<h3>res.local(name, val)</h3>
<p> Previously all local variables had to be passed to <em>res.render()</em>, or either <em>app.helpers()</em> or <em>app.dynamicHelpers()</em>, now we may do this at the request-level progressively. The <em>res.local()</em> method accepts a <em>name</em> and <em>val</em>, however the locals passed to <em>res.render()</em> will take precedence.</p>
<p> For example we may utilize this feature to create locals in middleware:</p>
<pre><code> function loadUser(req, res, next) {
User.get(req.params.id, function(err, user){
res.local('user', user);
next();
});
}
app.get('/user/:id', loadUser, function(req, res){
res.render('user');
});
</code></pre>
<h3>req.param(name[, defaultValue])</h3>
<p> Previously only <em>name</em> was accepted, so some of you may have been doing the following:</p>
<pre><code> var id = req.param('id') || req.user.id;
</code></pre>
<p> The new <em>defaultValue</em> argument can handle this nicely:</p>
<pre><code> var id = req.param('id', req.user.id);
</code></pre>
<h3>app.helpers() / app.locals()</h3>
<p> <em>app.locals()</em> is now an alias of <em>app.helpers()</em>, as helpers makes more sense for functions.</p>
<h3>req.accepts(type)</h3>
<p> <em>req.accepts()</em> now accepts extensions:</p>
<pre><code> // Accept: text/html
req.accepts('html');
req.accepts('.html');
// =&gt; true
// Accept: text/*; application/json
req.accepts('html');
req.accepts('text/*');
req.accepts('text/plain');
req.accepts('application/json');
// =&gt; true
req.accepts('image/png');
req.accepts('png');
// =&gt; false
</code></pre>
<h3>res.cookie()</h3>
<p> Previously only directly values could be passed, so for example:</p>
<pre><code>res.cookie('rememberme', 'yes', { expires: new Date(Date.now() + 900000) });
</code></pre>
<p>However now we have the alternative <em>maxAge</em> property which may be used to set <em>expires</em> relative to <em>Date.now()</em> in milliseconds, so our example above can now become:</p>
<pre><code>res.cookie('rememberme', 'yes', { maxAge: 900000 });
</code></pre>
<h3>res.download() / res.sendfile()</h3>
<p> Both of these methods now utilize Connect&rsquo;s static file server behind the scenes (actually the previous Express code was ported to Connect 1.0). With this change comes a change to the callback as well. Previously the <em>path</em> and <em>stream</em> were passed, however now only an <em>error</em> is passed, when no error has occurred the callback will be invoked indicating that the file transfer is complete. The callback remains optional:</p>
<pre><code> res.download('/path/to/file');
res.download('/path/to/file', function(err){
if (err) {
console.error(err);
} else {
console.log('transferred');
}
});
</code></pre>
<p> The <em>stream threshold</em> setting was removed.</p>
<h3>res.render()</h3>
<p> Previously locals were passed as a separate key:</p>
<pre><code> res.render('user', { layout: false, locals: { user: user }});
</code></pre>
<p> In Express 2.0 both the locals and the options are one in the same, meaning you cannot have a local variable named <em>layout</em> as it is reserved for express, however this cleans up the API:</p>
<pre><code> res.render('user', { layout: false, user: user });
</code></pre>
<h3>res.partial()</h3>
<p> Express 2.0 adds the <em>res.partial()</em> method, helpful for rendering partial fragments over WebSockets or Ajax requests etc. The API is identical to the <em>partial()</em> calls within views.</p>
<pre><code> // render a collection of comments
res.partial('comment', [comment1, comment2]);
// render a single comment
res.partial('comment', comment);
</code></pre>
<h3>partial() locals</h3>
<p> Both <em>res.partial()</em> and the <em>partial()</em> functions accept a single object consisting of both the options and the locals. Previously with Express 1.x you may pass <em>user</em> to a partial, along with <em>date</em> like so:</p>
<pre><code> partial('user', { object: user, locals: { date: new Date }})
</code></pre>
<p>or perhaps if you preferred not to use the inferred name <em>user</em> you may used a local for this as well:</p>
<pre><code> partial('user', { locals: { user: user, date: new Date }})
</code></pre>
<p> With recent changes to Express 2.x the object passed is now both, so the following is valid for the <em>object</em> option and locals:</p>
<pre><code> partial('user', { object: user, date: new Date })
</code></pre>
<p> Or the following which is equivalent, however the local var name is explicitly set to <em>user</em> instead of deduced from the filename.</p>
<pre><code> partial('user', { user: user, date: new Date })
</code></pre>
<p> When a &ldquo;basic&rdquo; object aka <em>{}</em> or <em>new Object</em> is passed, it is considered options, otherwise it is considered the <em>object</em>. The following are equivalent:</p>
<pre><code> partial('user', user);
partial('user', { object: user });
</code></pre>
<h3>Template Engine Compliance</h3>
<p> To comply with Express previously engines needed the following signature:</p>
<pre><code> engine.render(str, options, function(err){});
</code></pre>
<p> Now they must export a <em>compile()</em> function, returning a function which when called with local variables will render the template. This allows Express to cache the compiled function in memory during production.</p>
<pre><code> var fn = engine.compile(str, options);
fn(locals);
</code></pre>
<h3>View Partial Lookup</h3>
<p> Previously partials were loaded relative to the now removed <em>view partials</em> directory setting, or by default <em>views/partials</em>, now they are relative to the view calling them, read more on <a href="guide.html#view-lookup">view lookup</a>.</p>
<h3>Mime Types</h3>
<p> Express and Connect now utilize the <em>mime</em> module in npm, so to add more use:</p>
<pre><code> require('mime').define({ 'foo/bar': ['foo', 'bar'] });
</code></pre>
<h3>static() middleware</h3>
<p> Previously named <code>staticProvider()</code>, the now <code>static()</code> middleware takes a single directory path, followed by options.</p>
<pre><code> app.use(express.static(__dirname + '/public', { maxAge: oneYear }));
</code></pre>
<p>Previously when using options the <code>root</code> option would be used for this:</p>
<pre><code> app.use(express.staticProvider({ root: __dirname + '/public', maxAge: oneYear }));
</code></pre>
</div>
</div>
</body>
</html>