Native Abstractions for Node.js
===============================
**A header file filled with macro and utility goodness for making add-on development for Node.js easier across versions 0.8, 0.10 and 0.11, and eventually 0.12.**
***Current version: 1.3.0***
*(See [nan.h](https://github.com/rvagg/nan/blob/master/CHANGELOG.md) for complete ChangeLog)*
[![NPM](https://nodei.co/npm/nan.png?downloads=true)](https://nodei.co/npm/nan/) [![NPM](https://nodei.co/npm-dl/nan.png?months=6)](https://nodei.co/npm/nan/)
[![Build Status](https://secure.travis-ci.org/rvagg/nan.png)](http://travis-ci.org/rvagg/nan)
[![Build status](https://ci.appveyor.com/api/projects/status/kh73pbm9dsju7fgh)](https://ci.appveyor.com/project/RodVagg/nan)
Thanks to the crazy changes in V8 (and some in Node core), keeping native addons compiling happily across versions, particularly 0.10 to 0.11/0.12, is a minor nightmare. The goal of this project is to store all logic necessary to develop native Node.js addons without having to inspect `NODE_MODULE_VERSION` and get yourself into a macro-tangle.
This project also contains some helper utilities that make addon development a bit more pleasant.
* **[News & Updates](#news)**
* **[Usage](#usage)**
* **[Example](#example)**
* **[API](#api)**
<a name="news"></a>
## News & Updates
### Aug-2014: 1.3.0 release
* `NanCString()` and `NanRawString()` have been deprecated in favour of new <a href="#api_nan_ascii_string"><b><code>NanAsciiString</code></b></a>, <a href="#api_nan_utf8_string"><b><code>NanUtf8String</code></b></a> and <a href="#api_nan_ucs2_string"><b><code>NanUcs2String</code></b></a>. These classes manage the underlying memory for you in a safer way than just handing off an allocated array. You should now `*NanAsciiString(handle)` to access the raw `char` data, you can also allocate on the heap if you need to keep a reference.
* Two more <a href="#api_nan_make_callback"><b><code>NanMakeCallback</code></b></a> overloads have been added to for parity with Node core.
* You can now `NanNew(std::string)` (use `NanNew<std::string&>(std::string&)` to pass by reference)
* <a href="#api_nan_set_template"><b><code>NanSetTemplate</code></b></a>, <a href="#api_nan_set_prototype_template"><b><code>NanSetPrototypeTemplate</code></b></a> and <a href="#api_nan_set_instance_template"><b><code>NanSetInstanceTemplate</code></b></a> have been added.
### May-2014: 1.1.0 release
* We've deprecated `NanSymbol()`, you should just use `NanNew<String>()` now.
* `NanNull()`, `NanUndefined()`, `NanTrue()`, `NanFalse()` all return `Local`s now.
* `nan_isolate` is gone, it was intended to be internal-only but if you were using it then you should switch to `v8::Isolate::GetCurrent()`.
* `NanNew()` has received some additional overload-love so you should be able to give it many kinds of values without specifying the `<Type>`.
* Lots of small fixes and additions to expand the V8 API coverage, *use the source, Luke*.
### May-2014: Major changes for V8 3.25 / Node 0.11.13
Node 0.11.11 and 0.11.12 were both broken releases for native add-ons, you simply can't properly compile against either of them for different reasons. But we now have a 0.11.13 release that jumps a couple of versions of V8 ahead and includes some more, major (traumatic) API changes.
Because we are now nearing Node 0.12 and estimate that the version of V8 we are using in Node 0.11.13 will be close to the API we get for 0.12, we have taken the opportunity to not only *fix* NAN for 0.11.13 but make some major changes to improve the NAN API.
We have **removed support for Node 0.11 versions prior to 0.11.13**. As usual, our tests are run against (and pass) the last 5 versions of Node 0.8 and Node 0.10. We also include Node 0.11.13 obviously.
The major change is something that [Benjamin Byholm](kkoopa) has put many hours in to. We now have a fantastic new `NanNew<T>(args)` interface for creating new `Local`s, this replaces `NanNewLocal()` and much more. If you look in [./nan.h](nan.h) you'll see a large number of overloaded versions of this method. In general you should be able to `NanNew<Type>(arguments)` for any type you want to make a `Local` from. This includes `Persistent` types, so we now have a `Local<T> NanNew(const Persistent<T> arg)` to replace `NanPersistentToLocal()`.
We also now have `NanUndefined()`, `NanNull()`, `NanTrue()` and `NanFalse()`. Mainly because of the new requirement for an `Isolate` argument for each of the native V8 versions of this.
V8 has now introduced an `EscapableHandleScope` from which you `scope.Escape(Local<T> value)` to *return* a value from a one scope to another. This replaces the standard `HandleScope` and `scope.Close(Local<T> value)`, although `HandleScope` still exists for when you don't need to return a handle to the caller. For NAN we are exposing it as `NanEscapableScope()` and `NanEscapeScope()`, while `NanScope()` is still how you create a new scope that doesn't need to return handles. For older versions of Node/V8, it'll still map to the older `HandleScope` functionality.
`NanFromV8String()` was deprecated and has now been removed. You should use `NanCString()` or `NanRawString()` instead.
Because `node::MakeCallback()` now takes an `Isolate`, and because it doesn't exist in older versions of Node, we've introduced `NanMakeCallback()`. You should *always* use this when calling a JavaScript function from C++.
There's lots more, check out the Changelog in nan.h or look through [#86](https://github.com/rvagg/nan/pull/86) for all the gory details.
### Dec-2013: NanCString and NanRawString
Two new functions have been introduced to replace the functionality that's been provided by `NanFromV8String` until now. NanCString has sensible defaults so it's super easy to fetch a null-terminated c-style string out of a `v8::String`. `NanFromV8String` is still around and has defaults that allow you to pass a single handle to fetch a `char*` while `NanRawString` requires a little more attention to arguments.
### Nov-2013: Node 0.11.9+ breaking V8 change
The version of V8 that's shipping with Node 0.11.9+ has changed the signature for new `Local`s to: `v8::Local<T>::New(isolate, value)`, i.e. introducing the `isolate` argument and therefore breaking all new `Local` declarations for previous versions. NAN 0.6+ now includes a `NanNewLocal<T>(value)` that can be used in place to work around this incompatibility and maintain compatibility with 0.8->0.11.9+ (minus a few early 0.11 releases).
For example, if you wanted to return a `null` on a callback you will have to change the argument from `v8::Local<v8::Value>::New(v8::Null())` to `NanNewLocal<v8::Value>(v8::Null())`.
### Nov-2013: Change to binding.gyp `"include_dirs"` for NAN
Inclusion of NAN in a project's binding.gyp is now greatly simplified. You can now just use `"<!(node -e \"require('nan')\")"` in your `"include_dirs"`, see example below (note Windows needs the quoting around `require` to be just right: `"require('nan')"` with appropriate `\` escaping).
<a name="usage"></a>
## Usage
Simply add **NAN** as a dependency in the *package.json* of your Node addon:
``` bash
$ npm install --save nan
```
Pull in the path to **NAN** in your *binding.gyp* so that you can use `#include <nan.h>` in your *.cpp* files:
``` python
"include_dirs" : [
"<!(node -e \"require('nan')\")"
]
```
This works like a `-I<path-to-NAN>` when compiling your addon.
<a name="example"></a>
## Example
See **[LevelDOWN](https://github.com/rvagg/node-leveldown/pull/48)** for a full example of **NAN** in use.
For a simpler example, see the **[async pi estimation example](https://github.com/rvagg/nan/tree/master/examples/async_pi_estimate)** in the examples directory for full code and an explanation of what this Monte Carlo Pi estimation example does. Below are just some parts of the full example that illustrate the use of **NAN**.
Compare to the current 0.10 version of this example, found in the [node-addon-exa
使用node.js+express+mongodb来搭建一个简单的blog系统。.zip
需积分: 0 90 浏览量
更新于2023-08-03
收藏 4.85MB ZIP 举报
在本文中,我们将深入探讨如何使用Node.js、Express和MongoDB构建一个基本的博客系统。这是一个常见的技术栈,尤其适用于初学者和毕业设计项目。Node.js是一个基于Chrome V8引擎的JavaScript运行环境,使得JavaScript可以在服务器端运行。Express是Node.js的一个web应用框架,它简化了HTTP服务器的创建。而MongoDB则是一个流行的NoSQL数据库,非常适合存储结构化和半结构化的数据。
我们需要安装必要的开发工具和库。确保已经安装了Node.js和npm(Node包管理器)。接下来,通过命令行工具安装Express和MongoDB相关的模块:
```bash
npm init -y
npm install express mongoose body-parser ejs
```
`mongoose`是用于MongoDB的数据模型和ODM(对象文档映射),`body-parser`用于解析HTTP请求体中的JSON或URL编码的数据,`ejs`是模板引擎,用于渲染视图。
创建`app.js`作为主入口文件,初始化Express应用并设置路由。例如:
```javascript
const express = require('express');
const bodyParser = require('body-parser');
const mongoose = require('mongoose');
const ejs = require('ejs');
const app = express();
// 使用EJS作为视图引擎
app.set('view engine', 'ejs');
// 解析请求体
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
// 连接MongoDB
mongoose.connect('mongodb://localhost/blog', { useNewUrlParser: true, useUnifiedTopology: true });
// 引入模型和路由
require('./models/BlogPost');
require('./routes/blogRoutes')(app);
// 设置静态资源目录
app.use(express.static('public'));
// 启动服务器
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => console.log(`Server is running on port ${PORT}`));
```
在`./models/BlogPost.js`中定义一个Mongoose模型,描述博客文章的数据结构:
```javascript
const mongoose = require('mongoose');
const BlogPostSchema = new mongoose.Schema({
title: String,
content: String,
author: String,
date: { type: Date, default: Date.now }
});
module.exports = mongoose.model('BlogPost', BlogPostSchema);
```
接下来,在`./routes/blogRoutes.js`中设置博客的CRUD操作:
```javascript
const express = require('express');
const router = express.Router();
const BlogPost = require('../models/BlogPost');
// 获取所有文章
router.get('/', async (req, res) => {
const posts = await BlogPost.find();
res.render('index', { posts });
});
// 新增文章
router.post('/new', async (req, res) => {
const post = new BlogPost(req.body);
await post.save();
res.redirect('/');
});
// 显示单篇文章
router.get('/:id', async (req, res) => {
const post = await BlogPost.findById(req.params.id);
res.render('post', { post });
});
// 更新文章
router.put('/:id', async (req, res) => {
const post = await BlogPost.findByIdAndUpdate(req.params.id, req.body, { new: true });
res.redirect('/');
});
// 删除文章
router.delete('/:id', async (req, res) => {
await BlogPost.findByIdAndDelete(req.params.id);
res.redirect('/');
});
module.exports = (app) => {
app.use('/blog', router);
};
```
创建视图文件,例如`views/index.ejs`和`views/post.ejs`,用以展示博客列表和文章详情。这些文件使用EJS语法,将服务器端的数据动态渲染到HTML中。
至此,我们已经完成了基础的博客系统的搭建。用户可以通过HTTP请求创建、查看、更新和删除博客文章。这个系统虽然简单,但涵盖了Web开发的基本概念:路由、数据库操作、模板引擎和表单处理。你可以根据实际需求对其进行扩展,比如添加用户认证、评论功能或者优化界面设计。这个项目对于学习Node.js、Express和MongoDB的开发者来说是一个很好的实践平台。