我用Node.js + Express + MongoDB创建了一款文章管理应用程序
简要概述
記事を投稿、管理できるアプリを作成した。機能としては、アカウント登録、ログイン機能、記事作成&編集&削除機能がある。見た目は以下のようになる。
外貌
外观如下所示。





源代码
我把源代码上传到了GitHub上。
https://github.com/akikisai/Article-management-app
使用过的库
以下是使用的工具和版本。
使用的物品和版本如下。
“cookie-parser”: “~1.4.4” -> “cookie-parser”: “~1.4.4”,
“debug”: “~2.6.9” -> “debug”: “~2.6.9”,
“ejs”: “~2.6.1” -> “ejs”: “~2.6.1”,
“express”: “~4.16.1” -> “express”: “~4.16.1”,
“express-session”: “^1.17.2” -> “express-session”: “^1.17.2”,
“http-errors”: “~1.6.3” -> “http-errors”: “~1.6.3”,
“moment”: “^2.29.1” -> “moment”: “^2.29.1”,
“mongodb”: “^4.4.0” -> “mongodb”: “^4.4.0”,
“morgan”: “~1.9.1” -> “morgan”: “~1.9.1”
搭建环境
首先进行环境搭建。
建立node.js环境
请从以下链接下载并安装node.js的推荐版本,按照安装程序的流程进行安装,无需进行任何修改。这样就可以使用npm命令了。
node.js下载站点。
構建MongoDB環境
根据以下链接的内容进行环境配置。
进行MongoDB环境配置。
如果输入mongo命令后出现mongo shell,则表示成功。
创建项目
我想在桌面上创建一个项目。首先使用cd命令进行移动,并安装express,以便能够快速创建应用程序。
$ cd Desktop
$ npm install express-generator -g
创建一个名为textapp的项目。这时候在桌面上会创建一个textapp文件夹。
然后进入textapp文件夹,使用npm install命令安装初始的软件包,以便可以使用它们。
$ express -e textapp
$ cd textapp
$ npm install
如果没有文本编辑器,建议使用Visual Studio Code或Atom。
Visual Studio Code官方网站
Atom官方网站
在Node.js中,为了使更改生效,需要重新启动进程,但使用nodemon可以自动重新启动进程,从而消除额外的步骤。请安装nodemon。
$ npm install nodemon -g
将package.json文件中的”start”: “node ./bin/www”修改为以下内容,以支持nodemon。
"start": "nodemon ./bin/www"
用npm start命令启动项目。
$ npm start
在文件中,我们可以看到端口被设置为3000,
bin文件 > www文件 > var port = normalizePort(process.env.PORT || ‘3000’);
当我们在网站上输入以下链接时,
http://localhost:3000/
显示”欢迎使用express”。
在这里需要注意的是,在进行下一步操作时,请不要关闭输入npm start的终端。
连接到MongoDB
MongoDB的环境已经设置好了,在这里打开一个新的git bash,使用以下命令来确定数据库的存储位置。在这个例子中,将其保存在C:\mongodb\data中。
$ mongod --dbpath "C:\mongodb\data"
要连接到MongoDB,需要同时存在输入npm start命令的shell和打开的mongo shell。若存在已经打开的mongo shell表示成功连接到MongoDB。另外,如果在终端无法成功输入mongo shell命令,可以尝试使用Windows的命令提示符。
$ mongo
能够与MongoDB连接并使用shell。
确认数据库的内容
>show dbs
默认情况下如下所示。
admin 0.000GB
config 0.000GB
local 0.000GB
使用textapp来创建数据库。
创建用户集合。
db.createCollection(‘users’);
展示收藏品。
MongoDB 命令供参考使用。
为了连接Node.js和MongoDB,可以使用MongoDB Node.js驱动程序。
※另外还有使用Mongoose的方法,似乎比较受欢迎。
有关安装和使用方法,请参考 MongoDB Node.js 驱动程序文档。
在textapp文件夹中使用cd命令安装mongodb nodejs驱动程序,可以使用以下命令:
cd textapp
npm install mongodb –save
参考ドキュメントの例に従って、MongoDBに接続するためのコードを作成します。ファイルの新規作成などの詳細な手順は省略します(GitHubのソースコードを参照すれば分かるので)。この記事では、主に機能についてまとめたいと思います。
var MongoClient = require('mongodb').MongoClient;
var url = 'mongodb://localhost:27017/textapp';
var dbName = 'textapp';
//データベースへ接続用関数
function connect(callback) {//関数化
MongoClient.connect(url, function(err, client) {//コールバック関数
//エラーの場合
if (err) {
console.log('データベース接続エラー', err);
//エラーじゃない場合
} else {
//接続成功
var db = client.db(dbName);
callback && callback(db);
}
});
}
module.exports = {
connect
}
将连接功能转换为函数,并使其可以在之后使用。
注册和登录
进行路由设置。
// 登録ページ
router.get('/regist', function(req, res, next) {
res.render('regist', {})
});
// ログインページ
router.get('/login', function(req, res, next) {
res.render('login', {})
});
注册页面的代码将如下所示。
<body>
<div class="container">
<div class="login-container">
<div class="form-box">
<form action="/users/regist" method="post">
<input type="text" name="username" value="" placeholder="ユーザ名">
<input type="password" name="password" value="" placeholder="パスワード">
<button class="btn btn-info btn-block login" type="submit">登録する</button>
</form>
<div>アカウントをお持ちの場合、<br><a href="/login">ログイン</a>してください。</div>
</div>
</div>
</div>
</body>
这将导致用户名和密码被发送到”/users/regist”。
// 登録
router.post('/regist', function(req, res, next) {
var data = {
username: req.body.username,
password: req.body.password
};
// データの接続
model.connect(function(db) {
//コレクションusersにデータ挿入する
db.collection('users').insertOne(data, function(err, ret) {
//登録失敗
if (err) {
console.log('登録失敗');
res.redirect('/regist');
} else {
//登録成功、ログインページへ
res.redirect('/login');
}
});
})
})
收到的信息会存储在数据中,并连接到数据库进行验证,以确定是否成功注册。如果安装了MongoDB和MongoDB Compass,可以打开MongoDB Compass并点击连接按钮,即可连接到MongoDB,并在图形界面上确认已注册的信息是否存在。可参考使用MongoDB Compass。
ログインページのコードは以下のようになる。
<body>
<div class="container">
<div class="login-container">
<div class="form-box">
<form action="/users/login" method="post">
<input name="username" type="text" placeholder="ユーザ名">
<input name="password" type="password" placeholder="パスワード">
<button class="btn btn-info btn-block login" type="submit">ログイン</button>
</form>
<div>アカウントをお持ちでない場合、<a href="/regist">作成</a>できます。</div>
</div>
</div>
</div>
</body>
これにより、ユーザ名とパスワードは”/users/login”へ送信される。
// ログイン
router.post('/login', function(req, res, next) {
var data = {
username: req.body.username,
password: req.body.password
}
//データベースに接続する。
model.connect(function(db) {
//コレクションに同じデータがあるか、あればログイン成功。
db.collection('users').find(data).toArray(function(err, docs) {
if (err) {
//ログイン失敗→もう一回ログインページへ
res.redirect('/login');
}else {
//調べたdocsの結果が0以上であれば成功
if (docs.length > 0) {
// ログイン成功 session保存
req.session.username = data.username;//ユーザーネームをセッションに保存
res.redirect('/');
} else {
res.redirect('/login');
}
}
})
})
})
送信されてきた情報はdataに格納され、データベースに接続し、照らし合わせることでログイン成功か失敗か。失敗したらもう一度ログインページへ行く。また、上のコードでsessionを使用している。これはログイン状態を保存するため(毎回ログインするのはめんどくさいので)
首先,在textapp文件夹中安装express-session以使用session。请执行以下命令。使用方法请参考express-session文档。
$ npm install express-session -S
首先进行设置。
var session = require('express-session');
//セッション
app.use(session({
secret: 'sai textapp',//何でもよい
resave: false,
saveUninitialized: true,
cookie: { maxAge: 1000 * 60 * 20 } //cookie有効時間=ログイン有効期間
}))
ここでのログイン有効期間を20分とした。また上のログインが成功した場合ユーザ名をsessionに格納される。もしsessionにユーザ名がある場合、ログインせずにホームぺーズへ飛ぶことができるようになる。ユーザ名がニア場合、かつログインページと登録ページ以外ならば、ログインページへ戻る。これでログインしていない状態だとホームページは見れない。
// sessionの中身判定
app.get('*', function(req, res, next) {
var username = req.session.username;
//パスを判断したいので宣言
var path = req.path;
//ログインページと登録ページ以外で、ユーザ名なければログインページへ飛ぶ。
if (path != '/login' && path != '/regist') {
if (!username) {
res.redirect('/login');
}
}
next();
})
ログアウト
将发布按钮和注销按钮放置在标题栏上。
<li class="header_navi_item"><a href="/users/logout"><span>ログアウト</span></a></li>
ログアウトするには簡単で、sessionの中身を空っぽにしてlogin画面へ飛べばよい。
//ログアウト
router.get('/logout',function(req,res,next){
req.session.username = null;
res.redirect('/login');
})
发表文章
ホームページに投稿するボタンを用意する。投稿画面/writeへ飛ぶ。
<li class="header_navi_item"><a href="/write"><span>投稿する</span></a></li>
创造画面。
<body>
<%- include('bar', {username: username}) %>
<div class="article">
<form action="/article/add" method="post">
<input type="text" name="title" placeholder="タイトル" value="">
<textarea name="content" class="xheditor" id="mytextarea"></textarea>
<input type="submit" value="投稿">
</form>
</div>
</body>
然而,在这里的bar是指bar.ejs,并且我们会在这里创建一个标题。由于多个页面都会使用相同的标题,因此我们将其作为一个独立的bar.ejs文件创建,并通过include来调用并使用它。在这种情况下,我们需要在routes/index.ejs的router.get(‘/write’, function(req, res, next) {})中获取username并返回它,因为我们需要求得username。这样一来,我们就可以将username存储在bar(标题)的用户名处,并显示在页面的顶部,就像最上面所显示的一样。
我想在这里实现一个富文本编辑器,以便进行投稿。
富文本编辑器是指可以在不了解HTML的情况下,通过使用工具按钮来创建和编辑文字、图片、表格等内容的工具。实际上,即使将复制的内容粘贴到投稿栏中,格式也会保留。
→ 就像博客投稿时使用的编辑器一样。
今回使用するのはTinyMCEというもの。公式ページの始め方参照はこちら
やや古いですがとても分かりやすいTinyMCE使い方記事はこちら
なお、ほかのリーチテキストエディタを使いたい場合、リッチテキストエディタ一覧を参考して、各自調べてください。
写代码时,请按照文档上的要求进行操作。文档可能会有些陈旧,但一定要参考文档进行操作。按照文档的指示来做,
<script src="https://cdn.tiny.cloud/1/no-api-key/tinymce/5/tinymce.min.js" referrerpolicy="origin"></script>
http://から始まって直接読み込むことができるので便利ですが、今回はTinyMCEを直接ダウンロードページからDownlord TinyMCE SDK nowをクリックし、ダウンロードして解凍して中身のファイルをtextapp/public/javascriptsの中にいれ、リンクは代わりにtinymce.min.jsを適切なパスで読み込む。今回の例では
javascripts/tinymce_5.10.3/tinymce/js/tinymce/
の中に存在する。
修改write.js文件中的head标签,添加了两个script标签。
<head>
<title>記事作成</title>
<%- include head %>
<script src="javascripts/tinymce_5.10.3/tinymce/js/tinymce/tinymce.min.js" referrerpolicy="origin"></script>
<script>
tinymce.init({
selector: 'textarea',
language: 'ja'
});
</script>
</head>
言語を日本語化にしたいので、TinyMCE言語パッケージページからjaを見つけ、ダウンロードする。解凍したlangsフォルダの「ja.js」を「tinymce/」にある「langsフォルダ」へ移動する。
うえのようにlanguage: ‘ja’と記入すれば完成。
我将投稿一篇文章,将新的集合添加到数据库中。
在Mongo Shell中输入以下命令,创建一个名为articles的集合。
use textapp
db.createCollection('articles');
次は実際に記事書いたら、記事を投稿する機能を持つボタンを作る。ここで入力内容はformの/article/addへ行く。ということで作成していく。
// 追加
router.post('/add', function(req, res, next) {
//データを受け取る
var data = {
title: req.body.title,//タイトル
content: req.body.content,//記事内容
username: req.session.username,//ユーザ名
id: Date.now()//時間
//データベースに接続し、データを挿入する
model.connect(function(db) {
db.collection('articles').insertOne(data, function(err, ret) {
if(err) {
console.log('文件发布失败', err)
//失敗、もう一回記事投稿ページ
res.redirect('/write')
} else {
//成功、ホームページへ
res.redirect('/')
}
})
})
}
})
正しく入っているかどうか、Mongo shellで確認するか、MongoDB compassで確認する。
新闻显示(网页)
まずroutes/index.jsの”/”へ飛ぶ時の処理を編集する。
時間を扱いたいので、gitbashでtextapp内においてmomentをインストール。
npm install moment -S
公式ドキュメントはこちら
/* ホームページ*/
router.get('/', function(req, res, next) {
var username = req.session.username;
//データベース接続
model.connect(function(db) {
// すべての記事を調べる。
db.collection('articles').find().toArray(function(err, docs) {
var list = docs;
//ここでマップを使って、時間を表しているidを日付形式に変換し、timeと名付ける。
list.map(function(ele, index) {
ele['time'] = moment(ele.id).format('YYYY-MM-DD HH:mm:ss')
res.render('index', { username: username, data: list });
})
})
});
接下来要创建新闻显示页面。所获取的内容对象中包含了所需的信息。
<% list.map(function(item,index){ %>
<div class="row">
<span><%= index+1 %></span>
<span><%= item.username %></span>
<span><%= item.title %></span>
<!-- 定義したtimeを使用している。-->
<span><%= item.time %></span>
<span>
<a href="">編集</a>
<a href="">削除</a>
</span>
</div>
<% }) %>
文章列表分页
如果有很多篇文章,可以將頁面分開設定每頁可顯示多少篇文章。需要編輯 routes/index.js 和 views/index.js。
/* ホームページ*/
router.get('/', function(req, res, next) {
var username = req.session.username;
//フロント側で今は何ページ目にいるかデータを受け取る、なければ1
var page = req.query.page || 1;
var data = {
total: 0,//トータル何ページ必要か
curPage: page,//現在あるページ数
list:[]//今表示しているページの記事リスト
}
var pageSize = 2;//表示しているページに記事何個ひょうじするか
model.connect(function(db) {
// すべての記事を調べる。
db.collection('articles').find().toArray(function(err, docs) {
//全部の記事数÷1ぺ時に表示する記事数=トータル何ページ必要か
//Math.ceil() 関数は、引数として与えた数以上の最小の整数を返す
data.total = Math.ceil(docs.length / pageSize)
// 今のページの記事リストを調べる。
model.connect(function(db) {
// sort() limit() skip()
//降順で、一回に調べる記事数を限定(2)、スキップする個数(1ページ目なら(1-1)*2で0,スキップせず最初から2つ調べる)
db.collection('articles').find().sort({_id: -1}).limit(pageSize).skip((page-1)*pageSize).toArray(function(err, docs2) {
//時間変換
docs2.map(function(ele, index) {
ele['time'] = moment(ele.id).format('YYYY-MM-DD HH:mm:ss')
})
data.list = docs2
res.render('index', { username: username, data: data });
})
})
})
})
});
在分類文章時需要的信息是
-
- total: トータルで何ページ必要か
-
- cuiPage: 現在あるページ数 (ここでは必要ないが後で削除機能のために使う)
-
- list: 今表示しているページの記事のリスト
-
- page: フロント側で今は何ページ目にいるかデータ
- pageSize: 1ページに表示したい記事数
であり、取得した記事数によって、
total =記事数÷pageSize(小数の場合大き目の整数に変換)
<body>
<%- include('bar', {username}) %>
<div class="list">
<!-- ページ分け、何ページ目 -->
<div class="pages">
<% for(let i=1; i<=data.total; i++) { %>
<!-- ここでクリックすると今いる何ページ目かが"/"にわたり、そのページ内容を表示したい-->
<a class="pages_style" href="/?page=<%= i %>"><%= i %></a>
<% } %>
</div>
<div class="row">
<span>順番</span>
<span>作者</span>
<span>タイトル</span>
<span>公開日</span>
<span>
<i class="fa-solid fa-pen-to-square"></i>
</span>
</div>
<!-- 記事リスト -->
<% data.list.map(function(item,index){ %>
<div class="row">
<span><%= index+1 %></span>
<span><%= item.username %></span>
<span><%= item.title %></span>
<span><%= item.time %></span>
<span>
<a href="">編集</a>
<a href="">削除</a>
</span>
</div>
<% }) %>
</div>
</body>
使用for循环来利用data.total,以显示实际页面数。此外,将表示当前页码的page传递给页码按钮中的“/”,利用这个信息来选择应该显示的文章,并存储在data.list中。
删除文章
将views/index.js中的删除部分修改如下。
删除所需的信息包括文章的id,以及当前所在的页数,即需要一个page变量。需要注意的是,?id=<%=item.id%>&page=<%=data.curPage%>这部分,?之后是URL参数,并将该值传递给目标位置。
<a href="/article/delete?id=<%=item.id%>&page=<%=data.curPage%>">削除</a>
編輯routes/article.js文件。
// 記事削除
router.get('/delete', function(req, res, next) {
var id = parseInt(req.query.id)
var page = req.query.page
//接続
model.connect(function(db) {
//idで調べる
db.collection('articles').deleteOne({id: id}, function(err, ret) {
if (err) {
console.log('削除失敗');
} else {
console.log('削除成功');
}
//リダイレクトする
res.redirect('/?page='+page);
})
})
})
然而,在这种情况下,即使删除页面中没有任何文章,也可以显示出来,这是不合适的。为了修复这个问题,需要在routes/index.js中添加判断条件。
/* ホームページ*/
router.get('/', function(req, res, next) {
var username = req.session.username;
//フロント側で今は何ページ目にいるかデータを受け取る、なければ1
var page = req.query.page || 1;
var data = {
total: 0,//トータル何ページ必要か
curPage: page,//現在あるページ数
list:[]//今表示しているページの記事リスト
}
var pageSize = 2;//表示しているページに記事何個ひょうじするか
model.connect(function(db) {
// すべての記事を調べる。
db.collection('articles').find().toArray(function(err, docs) {
//全部の記事数÷1ぺ時に表示する記事数=トータル何ページ必要か
//Math.ceil() 関数は、引数として与えた数以上の最小の整数を返す
data.total = Math.ceil(docs.length / pageSize)
// 今のページの記事リストを調べる。
model.connect(function(db) {
// sort() limit() skip()
//降順で、一回に調べる記事数を限定(2)、スキップする個数(1ページ目なら(1-1)*2で0,スキップせず最初から2つ調べる)
db.collection('articles').find().sort({_id: -1}).limit(pageSize).skip((page-1)*pageSize).toArray(function(err, docs2) {
//記事がなければ
if (docs2.length == 0) {
//前のページに戻る、最小1
res.redirect('/?page='+((page-1) || 1))
} else {
//記事があれば、時間の処理をする。
docs2.map(function(ele, index) {
ele['time'] = moment(ele.id).format('YYYY-MM-DD HH:mm:ss')
})
data.list = docs2
}
res.render('index', { username: username, data: data });
})
})
})
})
});
新闻编辑
跳转至write页面。同样需要id和curPage参数。
<a href="/write?id=<%=item.id%>&page=<%=data.curPage%>">編集</a>
以下是以一种方式实现的:
router.get(‘/write’, function(req, res, next) {})
// 投稿&編集ページ
router.get('/write', function(req, res, next) {
var username = req.session.username || ''
var id = parseInt(req.query.id)
var page = req.query.page
var item = {
title: '',
content: ''
}
if (id) { // idがあれば編集
model.connect(function(db) {
db.collection('articles').findOne({id: id} , function(err, docs) {
if (err) {
console.log('失败')
} else {
item = docs
item['page'] = page
res.render('write', {username: username, item: item})
}
})
})
} else { // idがなければ追加
res.render('write', {username: username, item: item})
}
})
此外,还需要对write画面进行编辑。
<body>
<%- include('bar', {username: username}) %>
<div class="article">
<form action="/article/add" method="post">
<input type="hidden" name="id" value="<%- item.id %>">
<input type="hidden" name="page" value="<%- item.page %>">
<input type="text" name="title" placeholder="タイトル" value="<%= item.title %>">
<textarea name="content" class="xheditor" id="mytextarea"><%- item.content %></textarea>
<% if (item.id) { %>
<input type="submit" value="編集">
<%} else {%>
<input type="submit" value="投稿">
<%}%>
</form>
</div>
</body>
如果有id,则在按钮上显示“编辑”,否则显示“投稿”。
此外,为了进行编辑,页面和id必须要传入。
编辑成功后,希望跳转到页面。
<input type="hidden" name="id" value="<%- item.id %>">
<input type="hidden" name="page" value="<%- item.page %>">
使用隐藏使其不可见并进行排列。
还需要编辑 /article/add 部分。同样使用id进行编辑。
// 追加、編集
router.post('/add', function(req, res, next) {
var id = parseInt(req.body.id)
if (id) { //編集
var page = req.body.page
var title = req.body.title
var content = req.body.content
model.connect(function(db) {
db.collection('articles').updateOne({id: id}, {$set: {
title: title,
content: content
}}, function(err, ret) {
if (err) {
console.log('編集失敗', err)
} else {
console.log('編集成功')
res.redirect('/?page='+page)
}
})
})
} else { //追加
var data = {
title: req.body.title,
content: req.body.content,
username: req.session.username,
id: Date.now()
}
model.connect(function(db) {
db.collection('articles').insertOne(data, function(err, ret) {
if(err) {
console.log('失败', err)
res.redirect('/write')
} else {
res.redirect('/')
}
})
})
}
})
新闻报道
在标题栏处设置目的地。
<span><a href="/detail?id=<%=item.id%>"><%= item.title %></a></span>
创建文章表达页面。
<!DOCTYPE html>
<html lang="ja">
<head>
<title><%=item.title%></title>
<%- include head %>
</head>
<body>
<%- include('bar', {username: username}) %>
<div class="detail">
<div class="title"><%=item.title%></div>
<div class='desc'>
<span>作者:<%=item.username%></span>
<span>投稿日:<%=item.time%></span>
</div>
<div class="content"><%-item.content%></div>
</div>
</body>
</html>
也需要在routes/index.js中添加代码。
// 記事詳細ページ
router.get('/detail', function(req, res, next) {
var id = parseInt(req.query.id)
var username = req.session.username || ''
model.connect(function(db) {
db.collection('articles').findOne({id: id}, function(err, docs) {
if (err) {
console.log('失败', err)
} else {
var item = docs
item['time'] = moment(item.id).format('YYYY-MM-DD HH:mm:ss')
res.render('detail', {item: item, username: username})
}
})
})
})
按下标题后,可以查看相关文章的详细信息。
其他
如果继续这样下去,实际上其他人也可以编辑和删除他人的文章。这是不好的,需要进行改变。方法很简单,只需按照以下方式进行修正即可。
<!-- 記事リスト -->
<% data.list.map(function(item,index){ %>
<div class="row">
<span><%= index+1 %></span>
<span><%= item.username %></span>
<span><a href="/detail?id=<%=item.id%>"><%= item.title %></a></span>
<span><%= item.time %></span>
<span>
<% if (item.username===username) { %>
<a href="/write?id=<%=item.id%>&page=<%=data.curPage%>">編集</a>
<a href="/article/delete?id=<%=item.id%>&page=<%=data.curPage%>">削除</a>
<%} else {%>
<span class="grey">編集</span>
<span class="grey">編集</span>
<%}%>
</span>
</div>
<% }) %>
这里使用if语句进行判断。username是从session中获取的当前登录用户的用户名,item.username分别是每篇文章的作者名。如果不匹配,则无法进行编辑和删除。
发布/部署
尚未公开,但我计划使用EC2进行公开。我会先记下以下文章,似乎会有所参考。
EC2是什么?从概述到使用方法的简要解释(包含实际操作)
[AWS] 在Amazon EC2上通过具有图片的步骤搭建Node.js和Express环境的教程:在Amazon EC2实例上设置Node.js
在AWS EC2上运行Node.js指南
在Amazon Linux上安装MongoDB Community Edition
我在途中停下来了。指令备忘录↓↓
$ ssh -i textapp-key.pem ec2-user@18.183.176.255
$ ssh -i textapp-key.pem ec2-user@18.183.176.255
$ sudo yum update
$ sudo yum install git gcc-c++ make openssl-devel
$ nvm install v16.14.0
$ nvm alias default v16.14.0
$ npm install express-generator -g
npm WARN deprecated mkdirp@0.5.1: Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)
$ npm update -g mkdirp
$ npm install -g npm@8.5.3
$ git clone https://github.com/akikisai/Article-management-app.git
$ ls -a
$ cd Article-management-app/
$ npm install
$ grep ^NAME /etc/*release
/etc/os-release:NAME="Amazon Linux"
$ cd /etc/yum.repos.d
$ sudo touch mongo-org-5.0.repo
$ sudo su
# vi mongo-org-5.0.repo
[mongodb-org-5.0]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/amazon/2/mongodb-org/5.0/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-5.0.asc
:wq!
# sudo yum install -y mongodb-org
exclude=mongodb-org,mongodb-org-database,mongodb-org-server,mongodb-org-shell,mongodb-org-mongos,mongodb-org-tools
# ps --no-headers -o comm 1
systemd
# sudo systemctl start mongod
# sudo systemctl status mongod
Active: active (running) since Sat 2022-03-05 12:30:03 UTC; 29s ago
$ mongosh
>use textapp
>db.createCollection('users');
>db.createCollection('articles');
$ cd Article-management-app/
node ./bin/www
我失败了,我想再试一试其他的方法。
问题点
这次我只是试着创建了一些功能,但还没有写完善的错误处理(如用户名验证)和支持Markdown的功能,虽然还有很多新功能可以添加,但本次暂时先设定了截止时间。