MEANのスタック。 使用例

こんにちは親愛なる読者。



今日、MEANスタックに関する記事(Mongo、Express、Angular、Node)に注目してください。これは、私たちにとって有望な(同時に非常にファッショナブルな)トピックのようです。 このスタックに関する本をロシア語でご覧になりたい場合は、声をかけてください。 猫へようこそ。



この記事では、いくつかの無料のJavaScriptフレームワークを組み合わせたMEANスタックを紹介します。 それらがどのように機能するか、そして彼らの助けを借りて1ページのアプリケーションを作成する方法を議論しましょう。 この場合のJavaScriptテクノロジーは、フロントエンドだけでなくバックエンドでも使用されます。



はじめに



名前が示すように、MEANは3つのJavaScriptフレームワークとドキュメント指向のNoSQLデータベースを組み合わせた略語です。



MはMongoDBです



MongoDBは、スケーラビリティと開発の柔軟性の両方を提供するように編成された無料のドキュメント指向データベースです。 MongoDBのデータは、リレーショナルデータベースのようにテーブルや列に書き込まれません。 代わりに、動的スキーマを持つJSONのようなドキュメントがMongoDBに保存されます。



EはExpressJSです



Express.jsは、単一ページ、複数ページ、およびハイブリッドWebアプリケーションを作成するためのNode.jsアプリケーションサーバーフレームワークです。 事実、node.jsの標準サーバーフレームワークです。



AはAngularJSです



AngularJSは、動的Webアプリケーションの構造フレームワークです。 HTMLをテンプレート言語として使用できるだけでなく、HTML構文を拡張して、アプリケーションのコンポーネントを明確かつ簡潔に記述することができます。 Angularのデータバインディングと依存性注入により、他の方法で記述する必要のある多くのコードを取り除くことができます。



NこれはNodeJSです



Node.jsは、サーバーサイドWebアプリケーションを開発するための無料のクロスプラットフォームランタイム環境です。 Node.jsアプリケーションはJavaScriptで記述されており、OS X、Microsoft Windows、Linux、FreeBSD、NonStop、IBM AIX、IBM System z、IBMのNode.jsランタイムで実行できます。







MEANとは



「MEANスタック」という用語は、Webアプリケーションを開発するためのJavaScriptベースのテクノロジーのセットを指します。 MEANは、MongoDB、ExpressJS、AngularJS、およびNode.jsの略です。 クライアント、サーバー、およびデータベースレベルでは、MEANスタック全体がJavaScriptで記述されます。



それらがどのように相互作用するかを説明します。 角度は、クライアント側の開発に使用されます。 Angular.jsを使用してビューを開発し、それらがすべて同じページに表示されるようにします。 サーバー側では、Node.jsを使用します。つまり、Express.jsフレームワークを使用します。 Expressを使用して、データベースと通信するためのAPIを作成します。 最後に、MongoDBを使用してデータを保存します。 これはすべて図に示されています。



だから、最初から。



ツール



まず、NodeとMongoDBをインストールする必要があります。 彼らはここにいる



ダウンロードMongodb



ダウンロードノード



この記事では、Visual Studio Codeバージョン0.9.2を使用しますが、Sublime Textエディターを使用できます。 Windowsコマンドラインからノードパッケージマネージャーを使用してパッケージをインストールします。 これは、nodejsのインストール後にnode cmdコマンドを使用して非常に簡単に実行できます。



背景



この記事は、MEANとNodeスタックの作業の概要として考案されたもので、stackoverflowで遭遇する多くの簡単な質問の影響下でそれを書くことにしました。 基本的に、ユーザーを登録し、適切なコントローラーとモジュールを使用してユーザーを認証する方法を示します。



コードの使用


MeanAppというメインディレクトリがあります。 このルートディレクトリにはさまざまなサブディレクトリがあります。



最も重要なサブディレクトリのいくつかを説明します。



  1. Angularには、角度コントローラーのコントローラー、モジュール、モデルの3つのサブディレクトリがあります。
  2. Publicでは、すべてのjavascriptライブラリが存在します。
  3. ルートにはapi expressjs apiが含まれ、リクエストを処理してMongoDBとやり取りします。
  4. ビューには、すべてのディレクトリに問題のビューがすべて含まれます。


ルートディレクトリで、スタートアップファイルにserver.jsを使用します。 それでは始めましょう。



アプリケーションの他のすべての無料ライブラリは、次のコマンドを使用してnpmパッケージマネージャーからインストールする必要があります。



npm install [package] --save







次のコマンドを実行して、必要なトレーニングパッケージをインストールする必要があります。



npm install express --save

npm install path --save

npm install morgan --save

npm install cookie-parser --save

npm install body-parser --save

npm install bcrypt-nodejs --save

npm install passport --save

npm install passport-local --save

npm install express-session --save

npm install mongoose --save







ユーザーインターフェイスの設計から始めましょう。 最初に、Angular / Modulesディレクトリに新しいmodules.jsファイルを作成します。



 //    Angular var main = angular.module("main", ['ui.router','ngRoute','ngResource']) .run(function($http,$rootScope) { if(sessionStorage.length > 0){ $rootScope.current_user = sessionStorage.current_user; $rootScope.authenticated = true; }else{ $rootScope.authenticated = false; $rootScope.current_user = 'Guest'; } $rootScope.signout = function(){ $http.get('auth/signout'); $rootScope.authenticated = false; $rootScope.current_user = 'Guest'; sessionStorage.clear(); }; }); //   ( ) main.config([ '$stateProvider', '$urlRouterProvider', '$httpProvider', function ($stateProvider, $urlRouterProvider,$rootScope) { $urlRouterProvider.otherwise('/'); $stateProvider .state('home', { url: '/', templateUrl: 'Index.html', caseInsensitiveMatch: true, controller: 'MainController' }) .state('contact', { url: '/contact', templateUrl: 'Contact.html', caseInsensitiveMatch: true, controller: 'MainController' }) .state('about', { url: '/about', templateUrl: 'About.html', caseInsensitiveMatch: true, controller: 'MainController' }) .state('login',{ url: '/login', templateUrl: 'login.html', caseInsensitiveMatch: true, controller: 'AuthController' }) .state('register',{ url: '/register', templateUrl: 'register.html', caseInsensitiveMatch: true, controller: 'AuthController' }).state('unauth',{ url: '/unauth', templateUrl: 'unauth.html', caseInsensitiveMatch: true }); } ]);
      
      





次に、Angular / Modelsディレクトリにuser.js



モデルを作成します。



 //   var mongoose = require('mongoose'); //   mongoose       //      var userSchema = new mongoose.Schema({ username: String, password: String, email: String, role: String, created_at: {type: Date, default: Date.now} }); mongoose.model('User', userSchema); var User = mongoose.model('User'); exports.findByUsername = function(userName, callback){ User.findOne({ user_name: userName}, function(err, user){ if(err){ return callback(err); } return callback(null, user); }); } exports.findById = function(id, callback){ User.findById(id, function(err, user){ if(err){ return callback(err); } return callback(null, user); }); }
      
      





モデルの準備ができました。 次に、2つの新しいコントローラーを作成します。



AuthController.js







そして



MainController.js







Angular / Controllerディレクトリにあります。



 //  auth main.controller("AuthController", function ($scope, $http, $rootScope, $location) { $scope.user = {username: '', password: ''}; $scope.error_message = ''; //    webapi (,    node) $scope.login = function(){ $http.post('/auth/login', $scope.user).success(function(data){ if(data.state == 'success'){ $rootScope.authenticated = true; $rootScope.current_user = data.user.username; $rootScope.sess = data.user; sessionStorage.setItem('current_user', $rootScope.sess.username); $location.path('/'); } else{ $scope.error_message = data.message; $rootScope.sess = null; } }); }; //    webapi (,    node) $scope.register = function(){ console.log($scope.user); $http.post('/auth/signup', $scope.user).success(function(data){ if(data.state == 'success'){ $rootScope.authenticated = true; $rootScope.current_user = data.user.username; $location.path('/'); } else{ $scope.error_message = data.message; } }); }; });
      
      





 //           you    main.controller("MainController", function ($scope) {}); //  ,      –  
      
      





新しいビューディレクトリを作成し、次のejsコードをメインディレクトリに追加します。これは、ejsがStarter.ejsファイルのnodejsで使用される表示メカニズムであるためです。



 <html ng-app="main"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width" /> <title>Super Application</title> <link href="bootstrap.css" rel="stylesheet" /> <link href="Site.css" rel="stylesheet" /> <script src="modernizr-2.6.2.js"></script> <script src="jquery-1.10.2.js"></script> <script src="bootstrap.js"></script> <script src="angular.js"></script> <script src="angular-route.js"></script> <script src="angular-ui-router.js"></script> <script src="angular-resource.js"></script> <script src="/Modules/mainApp.js"></script> <script src="/Controllers/MainController.js"></script> <script src="/Controllers/AuthController.js"></script> </head> <body> <div class="navbar navbar-inverse navbar-fixed-top"> <div class="container"> <div class="navbar-header"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="#/home">Application name</a> </div> <div class="navbar-collapse collapse"> <ul class="nav navbar-nav"> <li><a href="#/home">Home</a></li> <li><a href="#/about">About</a></li> <li><a href="#/contact">Contact</a></li> </ul> <ul class="nav navbar-nav navbar-right"> <li><p class="navbar-right navbar-text">Signed in as {{current_user}}</p></li> <li><p class="navbar-right navbar-text" ng-hide="authenticated"> <a href="#/login">Login</a> or <a href="#/register">Register</a> </p></li> <li><p class="navbar-right navbar-text" ng-show="authenticated"> <a href="#" ng-click="signout()">Logout</a> </p></li> </ul> </div> </div> </div> <div class="container body-content"> <div ui-view> </div> <hr /> <footer> <p>My ASP.NET Application</p> </footer> </div> </body> </html>
      
      





次に、ViewsディレクトリにAuthenticationディレクトリを作成します。 認証(登録、ログインなど)のすべてのビューが含まれます。



認証を目的としたビューの場合は、login.htmlという名前の新しいファイルを認証ディレクトリに追加します。



 <form class="form-auth" ng-submit="login()"> <h2>Log In</h2> <p class="text-warning">{{error_message}}</p> <input type="username" ng-model="user.username" placeholder="Username" class="form-control" required><br> <input type="password" ng-model="user.password" placeholder="Password" class="form-control" required><br> <input type="submit" value="Log in" class="btn btn-primary" /> </form>
      
      





登録を目的としたプレゼンテーションの場合、register.htmlという新しいファイルを認証ディレクトリに追加します



 <form class="form-auth" ng-submit="register()"> <h2>Register</h2> <p class="text-warning">{{error_message}}</p> <input type="email" ng-model="user.email" placeholder="Email" class="form-control" required><br> <input type="username" ng-model="user.username" placeholder="Username" class="form-control" required><br> <input type="password" ng-model="user.password" placeholder="Password" class="form-control" required><br> <select ng-init="user.role = roles[0].name" ng-model="user.role" ng-options="role.name as role.name for role in roles" class="form-control" required></select><br> <input type="submit" value="Sign Up" class="btn btn-primary" /> </form>
      
      





認証に失敗したことを報告するビューの場合、unauth.htmlという名前の新しいディレクトリを認証ディレクトリに追加します。



 <form class="form-auth"> <h2>You are Authentic/Unauthorize to access this page, This is because </h2> <p>1) Not login? Please register to access resources.</p> <p>2) Registered: You are not Authorize user, Please contact Administrator.</p> </form>
      
      





次に、Viewsディレクトリに新しいMainディレクトリを作成します。 すべての基本的なビュー(インデックス、当社について、連絡先など)が含まれます。



インデックスを表すには、新しいindex.htmlファイルをメインディレクトリに追加します。



 <div> <div class="jumbotron"> <h1>Node.js Application</h1> <p class="lead">Node.js is a free Javascript framework for building great Web sites and Web applications using HTML, CSS and JavaScript.</p> <p><a class="btn btn-primary btn-lg">Learn more »</a></p> </div> <div class="row"> <div class="col-md-4"> <h2>Getting started</h2> <p> ASP.NET MVC gives you a powerful, patterns-based way to build dynamic websites that enables a clean separation of concerns and gives you full control over markup for enjoyable, agile development. </p> <p><a class="btn btn-default" href="http://go.microsoft.com/fwlink/?LinkId=301865">Learn more »</a></p> </div> <div class="col-md-4"> <h2>Get more libraries</h2> <p>NuGet is a free Visual Studio extension that makes it easy to add, remove, and update libraries and tools in Visual Studio projects.</p> <p><a class="btn btn-default" href="http://go.microsoft.com/fwlink/?LinkId=301866">Learn more »</a></p> </div> <div class="col-md-4"> <h2>Web Hosting</h2> <p>You can easily find a web hosting company that offers the right mix of features and price for your applications.</p> <p><a class="btn btn-default" href="http://go.microsoft.com/fwlink/?LinkId=301867">Learn more »</a></p> </div> </div> </div>
      
      





会社概要を紹介するには、メインディレクトリに新しいAbout.htmlファイルを追加します。



 <div> <h2>About Us</h2> <h3>Message</h3> <p>Use this area to provide additional information.</p> </div>   «Contact us»    Contact.html   Main. <div> <h2>Contact Us</h2> <h3>Message</h3> <address> One Microsoft Way<br /> Redmond, WA 98052-6399<br /> <abbr title="Phone">P:</abbr> 425.555.0100 </address> <address> <strong>Support:</strong> <a href="mailto:Support@example.com">Support@example.com</a><br /> <strong>Marketing:</strong> <a href="mailto:Marketing@example.com">Marketing@example.com</a> </address> </div>
      
      





これで、角度に関するインターフェースの設計が完了しました。



node.jsでバックエンドを書きましょう



Routesディレクトリにauthentication.jsと呼ばれる認証要求に基づいて新しいルートを作成します。



 var express = require('express'); var router = express.Router(); module.exports = function(passport){ //          (angular) router.get('/success',function(req,res){ res.send({state: 'success', user: req.user ? req.user: null}); }); //          (angular) router.get('/failure',function(req,res){ res.send({state: 'failure',user:null,message:"Invalid username or password"}); }); //     router.post('/login',passport.authenticate('login',{ successRedirect: '/auth/success', failureRedirect: '/auth/failure' })); //      router.post('/signup', passport.authenticate('signup', { successRedirect: '/auth/success', failureRedirect: '/auth/failure' })); //      router.get('/signout', function(req, res) { req.session.user = null; req.logout(); res.redirect('/'); }); return router; }
      
      





同じディレクトリにrouter.jsを作成します。



 var express = require('express'); var router = express.Router(); var mongoose = require( 'mongoose' ); router.get('/',function(req,res,next){ res.render('Starter',{title:"Super App"}); }); module.exports = router;
      
      





Passportという新しいディレクトリを作成し、passport-init.jsという名前の新しいファイル(API)を追加してから、次のコードを追加します。 認証ルートでは、これは認証APIと呼ばれます。



 var mongoose = require('mongoose'); var User = mongoose.model('User'); var LocalStrategy = require('passport-local').Strategy; var bCrypt = require('bcrypt-nodejs'); module.exports = function(passport){ // Passport       ,       passport.serializeUser(function(user, done) { console.log('serializing user:',user.username); done(null, user._id); }); passport.deserializeUser(function(id, done) { User.findById(id, function(err, user) { console.log('deserializing user:',user.username); done(err, user); }); }); passport.use('login', new LocalStrategy({ passReqToCallback : true }, function(req, username, password, done) { //   mongo,       User.findOne({ 'username' : username }, function(err, user) { //         done if (err) return done(err); //    ,       if (!user){ console.log('User Not Found with username '+username); return done(null, false); } //  ,    .   if (!isValidPassword(user, password)){ console.log('Invalid Password'); return done(null, false); //      } //     ,     done //      return done(null, user); } ); } )); passport.use('signup', new LocalStrategy({ passReqToCallback : true //         }, function(req, username, password, done, email, role) { //   mongo     User.findOne({ 'username' : username }, function(err, user) { //        done if (err){ console.log('Error in SignUp: '+ err); return done(err); } //   if (user) { console.log('User already exists with username: '+username); return done(null, false); } else { //    –   var newUser = new User(); //      newUser.username = username; newUser.password = createHash(password); newUser.email = req.body.email; newUser.role = req.body.role; //   newUser.save(function(err) { if (err){ console.log('Error in Saving user: '+err); throw err; } console.log(newUser.username + ' Registration succesful'); return done(null, newUser); }); } }); }) ); var isValidPassword = function(user, password){ return bCrypt.compareSync(password, user.password); }; //     bCrypt var createHash = function(password){ return bCrypt.hashSync(password, bCrypt.genSaltSync(10), null); }; };
      
      





このファイルから開始するため、新しいserver.jsファイルをルートディレクトリに追加します。



 //server.js //     var express = require('express'); //express var path = require('path'); //       var logger = require('morgan'); var cookieParser = require('cookie-parser'); //   var bodyParser = require('body-parser'); //   json var bcrypt = require('bcrypt-nodejs'); var passport = require('passport'); // passportjs   var LocalStrategy = require('passport-local').Strategy; //   var session = require('express-session'); //    var mongoose = require('mongoose'); // mongodb,   var models_user = require('./Angular/Models/user.js'); //     server.js //     mongoose.connect('mongodb://localhost/AngularizeApp'); //   var router = require('./Routes/router'); var authenticate = require('./Routes/authentication')(passport); //   express     var app = express(); // ,  My application    ejs  ,    app.set('views', path.join(__dirname, 'Views')); app.set('view engine', 'ejs'); //    parser, logger  passport app.use(cookieParser()); app.use(logger('dev')); app.use(session({ secret: 'keyboard cat' })); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: false })); app.use(passport.initialize()); //   app.use(passport.session()); //    //     ,       app.use('/', router); app.use('/auth', authenticate); app.use(express.static(path.join(__dirname, 'scripts'))); app.use(express.static(path.join(__dirname, 'Content'))); app.use(express.static(path.join(__dirname, 'Angular'))); app.use(express.static(path.join(__dirname, 'Views/Main'))); app.use(express.static(path.join(__dirname, 'Views/Authentication'))); // auth-api  , ,     . var initPassport = require('./Passport/passport-init'); initPassport(passport); //    var server = app.listen(3000, function () { var host = server.address().address; var port = server.address().port; console.log('Example app listening at http://%s:%s', host, port); }); //       module.exports = app;
      
      





したがって、コードを使用すれば、すべての準備が整います。 このアプリケーションは、コマンドラインからnode server.jsコマンドを使用して起動できますが、最初にcd c:// MeanAppなどのコマンドを使用してMEANAppルートディレクトリに移動します。



また、mongodbサーバーを起動する必要があります。 これを行うには、新しいcmdウィンドウを開き、mongod -dbpathと入力します。 mongodbデータベースがインストールされ、変数名が追加されている場合、このコマンドはmongodbサーバーを正常に起動します。 このコマンドラインウィンドウを閉じないでください。閉じると、サーバーが動作しなくなるためです。



mongod -dbpath











上記のコマンドを実行した後、コマンドプロンプトでデータベースを確認できます。 これを行うには、別のコマンドウィンドウを開き、そこにmongodbと入力します。接続しているクライアントの中で、興味のあるデータベースのクライアントが表示され、それに切り替えることができます。 ここにあるドキュメントでmongodbについて読むことができます



次のコマンドを使用して、アプリケーションを開始できます。



MeanApp>node server.js











ログイン後、すべての呼び出しを確認できます。



そのため、サーバー側でデータを保存するための認証とセッションをサポートする実用的なアプリケーションがあります。



すべてのコードは、 ここの githubにあります



All Articles