Your email address will not be published. Save my name, email, and website in this browser for the next time I comment. How to Visualize Data with D3 [Video]. However, the latest version available for npm is 5. Installation Node can be installed via direct download, installers, or the Node version manager:. You can install Node by directly downloading the source code or a pre- built installer specific to your workspace platform.
Downloads are available at nodejs. Cloud development services may come with Node preinstalled, such as in Cloud9, or will have specific instructions for adding and updating Node. To test if the installation was successful, you can open the command line and run node -v to see if it correctly returns the version number. Upgrading npm versions In order to install npm version 5. You have to install nvm separately. Instructions for setup can be found at: github.
These include key modules, such as React and Express, which are required to run each MERN application, and also modules that will be necessary during development. In this section, we list and discuss the modules, then see how to use the modules in a working project in the following section.
Key modules To integrate the MERN stack technologies and run your applications, we will need the following npm modules:. As a consequence, and also to aid the development process, we will use the following additional npm modules to compile and bundle the code and to automatically reload the server and browser app as the code is updated during development:.
The modules needed to get Babel working are: babel-core babel-loader for transpiling JavaScript files with Webpack babel-preset-env, babel-preset-react, and babel-preset-stage-2 to provide support for React, the latest JS features, and some stage-x features such as declaring class fields that are not currently covered under babel-preset-env. Webpack modules will help bundle the compiled JavaScript, both for the client-side and server-side code.
Modules needed to get Webpack working are: webpack webpack-cli to run Webpack commands webpack-node-externals to ignore external Node module files when bundling in Webpack webpack-dev-middleware to serve the files emitted from Webpack over a connected server during development of the code webpack-hot-middleware to add hot module reloading into an existing server by connecting a browser client to a Webpack server and receiving updates as code changes during development nodemon to watch server-side changes during development, so the server can be reloaded to put changes into effect.
Although react-hot-loader is meant for aiding development flow, it is safe to install this module as a regular dependency rather than a devDependency. It automatically ensures hot reloading is disabled in production and the footprint is minimal. Checking your development setup In this section, we will go through the development workflow and write code step-by-step to ensure the environment is correctly set up to start developing and running MERN applications.
You can clone this code and run it as you go through the code. Initializing package. It is a best practice to add a package. The package. Perform the steps outlined in the following to generate a package. You will be asked a series of questions and then a package. The file path mentioned before a code block indicates the location of the code in the project directory. This convention has been maintained throughout the book to provide better context and guidance as you follow along with the code.
Configuring Babel, Webpack, and Nodemon Before we start coding up the web application, we need to configure Babel, Webpack, and Nodemon to compile, bundle, and auto reload the changes in the code during development. Babel Create a. Webpack We will have to configure Webpack for bundling both the client and server code and the client code separately for production code.
Create webpack. The config JSON object will differ with values specific to the client or server-side code, and development versus production code. Client-side Webpack configuration for development Update the config object with the following in your webpack.
HotModuleReplacementPlugin , new webpack. If not explicitly set, it defaults to the value 'production'. It can also be set via the command line by passing the value as a CLI argument.
The transpilation tool to be used here is babel-loader. HotModuleReplacementPlugin enables hot module replacement for react-hot- loader.
NoEmitOnErrorsPlugin allows skipping emitting when there are compile errors. Server-side Webpack configuration Modify the code to require nodeExternals, and update the config object with the following in your webpack.
The mode option is not set here explicitly but will be passed as required when running the Webpack commands with respect to running for development or building for production. Webpack starts bundling from the server folder with server. Client-side Webpack configuration for production For preparing the client-side code for production, update the config object with the following code in your webpack. This will configure Webpack for bundling the React code to be used in production mode, where the hot reloading plugin or debug configuration will no longer be required.
Nodemon Create a nodemon. This configuration will set up nodemon to watch for changes in the server files during development, then execute compile and build commands as necessary. Frontend views with React In order to start developing a frontend, first create a root template file called template. The main. To see the React component rendered in the browser when the server receives a request to the root URL, we need to use the Webpack and Babel setup to compile and bundle this code, and add server-side code that responds to the root route request with the bundled code.
Server with Express and Node In the project folder, create a folder called server, and add a file called server. Then, add another file called devBundle. Express app In server. Then we will use this Express app to build out the rest of the Node server application. Bundle React app during development In order to keep the development flow simple, we will initialize Webpack to compile the client-side code when the server is run.
In devBundle. We will call this compile method in server. Serving static files from the dist folder Webpack will compile client-side code in both development and production mode, then place the bundled files in the dist folder.
To make these static files available on requests from the client side, we will add the following code in server. In server. PORT app. In this code example, MongoClient is the driver that connects to the running MongoDB instance using its url and allows us to implement the database related. Run the application from the command line: npm run development.
Develop code and debug live: Change the HelloWorld. Save the changes to see the instantaneous update in the browser, and also check the command line output to see that bundle. Similarly, you can also see instant updates when you change the server-side code, increasing productivity during development. If you have made it this far, congratulations, you are all set to start developing exciting MERN applications.
Summary In this chapter, we discussed development tool options and how to install MERN technologies, and then we wrote code to check whether the development environment is set up correctly.
We began by looking at the recommended workspace, IDE, version control software, and browser options suitable for web development. You can select from these options based on your preferences as a developer. Before moving on to writing code to check this setup, we configured Webpack and Babel to compile and bundle code during development, and to build production ready code.
Additionally, we made the development flow efficient by including React Hot Loader for frontend development, configuring Nodemon for backend development, and compiling both the client and server code in one command when the server is run during development.
In the next chapter, we use this setup to start building a skeleton MERN application that will function as a base for full-featured applications. Building a Backend with MongoDB, Express, and Node During the development of most web applications, there are common tasks, basic features, and implementation code repeated across the process.
The same is true for the MERN applications developed in this book. Taking these similarities into consideration, we will first lay the foundations for a skeleton MERN application that can be easily modified and extended to implement a variety of MERN applications.
We will build the skeleton essentially as a basic but fully functioning MERN web application with user create, update, delete CRUD , and authentication-authorization auth capabilities, which will also lay out how to develop, organize, and run code for general web applications built using this stack. The aim is to keep the skeleton as simple as possible so it is easy to extend, and can be used as a base application for developing different MERN applications.
Feature breakdown In the skeleton application, we will add the following use cases with user CRUD and auth functionality implementations:. The completed backend will be a standalone server-side application that can handle HTTP requests to create a user, list all users, and view, update, or delete a user in the database while taking user authentication and authorization into consideration.
User model The user model will define user details to be stored in the MongoDB database, and also handle user-related business logic such as password encryption and user data validation. The user model for this skeletal version will be basic with support for the following attributes: Field Type Description name.
Required unique field to store user's email and email String identify each account only one account allowed per unique email Required field for authentication, the database will password String store the encrypted password and not the actual string for security purposes.
Automatically generated timestamp when a new created Date user account is created. The last two routes are for authentication and will allow the user to sign in and sign out. Auth with JSON Web Tokens To restrict and protect access to the user API endpoints according to the skeleton features, the backend will need to incorporate authentication and authorization mechanisms.
There are a number of options when it comes to implementing user auth for web applications. The most common and time tested option is the use of sessions to store user state on both the client and server side. Both approaches have strengths for relevant real-world use cases.
However, for the purpose of keeping the code simple in this book, and because it pairs well with the MERN stack and our example applications, we will use JWT for auth implementation. Additionally, the book will also suggest security enhancement options in future chapters. How JWT works When a user successfully signs in using their credentials, the server side generates a JWT signed with a secret key and a unique user detail.
Then, this token is returned to the requesting client to be saved locally either in localStorage, sessionStorage, or a cookie in the browser, essentially handing over the responsibility of maintaining user state to the client side:. When the server receives a request for a protected API endpoint, it checks the Authorization header of the request for a valid JWT, then verifies the signature to identify the sender and ensures the request data was not corrupted. If the token is valid, the requesting client is given access to the associated operation or resource, otherwise an authorization error is returned.
In the skeleton application, when a user signs in with email and password, the backend will generate a signed JWT with the user's ID and with a secret key available only on the server.
This token will then be required for verification when a user tries to view any user profiles, update their account details, or delete their user account. Implementing the user model to store and validate user data, then integrating it with APIs to perform CRUD operations based on auth with JWT, will produce a functioning standalone backend.
In the rest of the chapter, we will look at how to achieve this in the MERN stack and setup. Implementing the skeleton backend To start developing the backend part of the MERN skeleton, we will first set up the project folder, install and configure the necessary npm modules, and then prepare the run scripts to aid development and run the code.
Then, we will go through the code step by step to implement the user model, API endpoints, and JWT-based auth to meet the specifications we defined earlier for the user-oriented features.
The code discussed in this chapter, and for the complete skeleton application is available on GitHub in the repository at github. The code for just the backend is available at the same repository in the branch named mern-skeleton- backend. You can clone this code and run the application as you go through the code explanations in the rest of this chapter. Folder and file structure The following folder structure only shows the files that are relevant for the MERN skeleton backend.
This structure will be further expanded in the next chapter, where we complete the skeleton application by adding a React frontend. Setting up the project If the development environment is already set up, we can initialize the MERN project to start developing the backend. First, we will initialize package. To initialize a package. With package. Development dependencies In order to begin with development and to run the backend server code, we will configure and install Babel, Webpack, and Nodemon as discussed in Cha pter 2, Preparing the Development Environment, with some minor.
Babel Since we will be using ES6 to write the backend code, we will configure and install Babel modules to convert ES6. First, we configure Babel in the. Next, we install the Babel modules as devDependencies from the command line: npm install --save-dev babel-core babel-loader babel-preset-env babel-preset- stage Once the module installations are done, you will notice that the devDependencies list has been updated in the package.
Webpack We will need Webpack to compile and bundle the server-side code using Babel, and for configuration we can use the same webpack. From the command line, run the following command to install webpack, webpack-cli, and the webpack-node-externals module:.
This will install the Webpack modules and update the package. Nodemon To automatically restart the Node server as we update the code during development, we will use Nodemon to monitor the server code for changes. We can use the same installation and configuration guidelines discussed in C hapter 2, Preparing the Development Environment. PORT , jwtSecret: process. For the complete skeleton application, we will use the same run scripts defined in Chapter 2, Preparing the Development Environment.
The configuration instructs Nodemon to monitor the server files. Preparing the server In this section, we will integrate Express, Node, and MongoDB to run a completely configured server before we start implementing the user specific features. From the command line, run the following command to install the express module with the --save flag, so the package. Once Express is installed, we can import it into the express. To handle HTTP requests and serve responses properly, we will use the following modules to configure Express:.
After the preceding modules are installed, we can update express. We first import the config variables to set the port number that the server will listen on, and then the configured Express app to start the server.
If the code has no errors, the server should start running with Nodemon monitoring for code changes. Setting up Mongoose and connecting to MongoDB We will be using the Mongoose module to implement the user model in this skeleton, and also all future data models for our MERN applications. Here, we will start by configuring Mongoose, and utilizing it to define a connection with the MongoDB database. First, to install the mongoose module, run the following command: npm install mongoose --save.
Then, update the server. If you have the code running in development, saving this update should restart the server that is now integrated with Mongoose and MongoDB. Mongoose is a MongoDB object modeling tool that provides a schema-based solution to model application data. It includes built-in type casting, validation, query building, and business logic hooks.
Using Mongoose with this backend stack provides a higher layer over MongoDB with more functionality including mapping object models to database documents. Thus, making it simpler and more productive to develop with a Node and MongoDB backend. To learn more about Mongoose, visit mongoosejs. In the template.
To serve this template at the root URL, update the express. We will begin by importing the mongoose module and use it to generate a UserSchema. The mongoose. Schema function takes a schema definition object as a parameter to generate a new Mongoose schema object that can be used in the rest of the backend code. User schema definition The user schema definition object needed to generate the new Mongoose schema will declare all the user data fields and associated properties.
Name The name field is a required field of type String. The actual password string is not stored directly in the database for security purposes and is handled separately. Password for auth The password field is very crucial for providing secure user authentication in any application, and it needs to be encrypted, validated, and authenticated securely as a part of the user model.
As a virtual field The password string provided by the user is not stored directly in the user document. Instead, it is handled as a virtual field. Additionally, the authenticate method is also defined as a UserSchema method, which is used when a user supplied password must be authenticated for sign-in. If validation fails, the logic will return the relevant error message. Once the UserSchema is defined, and all the password related business logic is added as discussed previously, we can finally export the schema at the bottom of the user.
To handle these validation errors and other errors that the database may throw when we make queries to it, we will define a helper method to return a relevant error message that can be propagated in the request-response cycle as appropriate. This method will parse and return the error message associated with the specific validation error or other error that occurred while querying MongoDB using Mongoose. Errors that are not thrown because of a Mongoose validator violation will contain an error code and in some cases need to be handled differently.
For example, errors caused due to a violation of the unique constraint will return a different error object than Mongoose validation errors. The unique option is not a validator but a convenient helper for building MongoDB unique indexes, and thus we will add another getUniqueErrorMessage method to parse the unique constraint related error object and construct an appropriate error message.
To implement these working endpoints, we will write Express routes and corresponding controller callback functions that should be executed when HTTP requests come in for these declared routes. In this section, we will look at how these endpoints will work without any auth restrictions. User routes The user routes defined in the user. Router to declare the route paths with relevant HTTP methods, and assign the corresponding controller function that should be called when these requests are received by the server.
The resulting user. The user. The controller will make use of the errorHandler helper to respond to the route requests with meaningful messages when a Mongoose error occurs.
It will also use a module called lodash when updating an existing user with changed values. To install lodash, run npm install lodash --save from command line. Each of the controller functions defined previously are related to a route request, and will be elaborated on in relation to each API use case. Creating a new user The API endpoint to create a new user is declared in the following route. Listing all users The API endpoint to fetch all the users is declared in the following route.
The list controller function finds all the users from the database, populates only the name, email, created and updated fields in the resulting user list, and then returns this list of users as JSON objects in an array to the requesting client. Loading a user by ID to read, update, or delete All three API endpoints for read, update, and delete require a user to be retrieved from the database based on the user ID of the user being accessed.
We will program the Express router to do this action first before responding to the specific request to read, update, or delete. Loading Whenever the Express app receives a request to a route that matches a path containing the :userId param in it, the app will first execute the userByID controller function before propagating to the next function specific to the request that came in.
If a matching user is found in the database, the user object is appended to the request object in the profile key. Then, the next middleware is used to propagate control to the next relevant controller function. For example, if the original request was to read a user profile, the next call in userById would go to the read controller function.
Reading The API endpoint to read a single user's data is declared in the following route. The read function retrieves the user details from req. Updating The API endpoint to update a single user is declared in the following route. The update function retrieves the user details from req. Before saving this updated user to the database, the updated field is populated with the current date to reflect the last updated at timestamp. Deleting The API endpoint to delete a user is declared in the following route.
The remove function retrieves the user from req. On successful deletion, the requesting client is returned the deleted user object in the response. With the implementation of the API endpoints so far, any client can perform CRUD operations on the user model, but we want to restrict access to some of these operations with authentication and authorization. User auth and protected routes To restrict access to user operations such as user profile view, user update, and user delete, we will implement sign-in authentication with JWT, then protect and authorize the read, update, and delete routes.
Auth routes The two auth APIs are defined in the auth. These applications include a social media, an online marketplace, a media streaming, and a web-based game application with virtual reality features. While learning to set up the stack and developing a diverse range of applications with this Full-Stack React Projects book, you will grasp the inner workings of the MERN stack, extend its capabilities for complex features, and gain actionable knowledge of how to prepare MERN-based applications to meet the growing demands of real-world web applications.
Your email address will not be published. This book guides you through preparing the development environment for MERN stack-based web development, to creating a basic skeleton application and extending it to build four different web applications. These applications include a social media, an online marketplace, a media streaming, and a web-based game application with virtual reality features. While learning to set up the stack and developing a diverse range of applications with this book, you will grasp the inner workings of the MERN stack, extend its capabilities for complex features, and gain actionable knowledge of how to prepare MERN-based applications to meet the growing demands of real-world web applications.
Full-Stack React Web Development Projects is for JavaScript developers who have some experience with React, but no previous experience with full-stack development involving Node, Express, and MongoDB, and who want practical guidelines to start building different types of real-world web applications with this stack.
0コメント