简体   繁体   中英

How to run a node.js REST API application in production

Ok, so right off the bat I feel a little dumb asking this question, but I'm a bit new to node.js apps so bear with me. I've written this REST API in node.js and it runs just fine on my local machine. But, when I build it using webpack, I am not quite sure how it's supposed to actually run in the wild. Locally, I have a server.js using Express file that I start using node. But how would I run the build version? I'm sure the answer is obvious I'm just not seeing it.

My goal is to be able to run this on a subdomain on my shared hosting solution, so I'd have something like an example endpoint of https://myapi.mydomain.com/getAListOfSomething/

So bottom line - I wanna use Webpack to build my app, then deploy it somewhere and use it like a normal API. I'm just not sure how to do about it. With something like a React app, it's completely obvious to me (an index.html file with a script tag to my app, very simple) but with something like this I'm lost.

So here's some code...

SERVER.JS

const routes = require('./routes/appRoutes.js');
const express = require('express');
const cors = require('cors');

process.env.NODE_ENV = process.env.NODE_ENV || 'development';
const envPath = process.env.NODE_ENV !== 'production' ? `.env.${process.env.NODE_ENV}` : '.env';
const config = require('dotenv').config({path: envPath});

 bodyParser = require('body-parser');
 app = express();
 port = process.env.PORT || 3001;
 app.use(cors());
 app.listen(port);
 console.log(process.env.APP_NAME + ' started on port ' + port +' (yay!)');

 app.use(bodyParser.urlencoded({ extended: true }));
 app.use(bodyParser.json());

 routes(app); //register the route

* WEBPACK.CONFIG.JS *

const path = require('path');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const webpack = require('webpack');
const nodeExternals = require('webpack-node-externals');
process.env.NODE_ENV = process.env.NODE_ENV || 'development';

const envPath = process.env.NODE_ENV !== 'production' ? `.env.${process.env.NODE_ENV}` : '.env';
const config = require('dotenv').config({path: envPath});


module.exports = (env) => {
    const isProduction = env==='production';

    return {
        entry: './routes/appRoutes.js',
        output: {
            path: path.join(__dirname,'public','dist'),
            filename: 'bundle.js'
        },
        target: 'node',
        node: {
            // Need this when working with express, otherwise the build fails
            __dirname: false,   // if you don't put this is, __dirname
            __filename: false,  // and __filename return blank or /
          },        
        externals: [nodeExternals()],
        module: {
            rules: [{
                loader: 'babel-loader',
                test: /\.js$/,
                exclude: /node_modules/
            }]
        },
        plugins: [
            new webpack.DefinePlugin({
             'process.env.APP_NAME': JSON.stringify(process.env.APP_NAME),
             'process.env.DB_HOST': JSON.stringify(process.env.DB_HOST),
             'process.env.DB_USERNAME': JSON.stringify(process.env.DB_USERNAME),
             'process.env.DB_PASSWORD': JSON.stringify(process.env.DB_PASSWORD),
             'process.env.DB_PASSWORD': JSON.stringify(process.env.DB_PASSWORD),
             'process.env.PORT': JSON.stringify(process.env.PORT)      
            })
         ],
        devtool: isProduction ? 'source-map' : 'inline-source-map',
        devServer: {
            contentBase: path.join(__dirname,'public'),
            port: 3300,
            historyApiFallback: true,
            publicPath: '/dist/'
        }    
    }
};  

PACKAGE.JSON

{
    "name": "spinder-api",
    "version": "1.0.0",
    "description": "",
    "main": "index.js",
    "scripts": {
        "build:dev": "webpack -p --env development",
        "build:prod": "webpack -p --env production",
        "dev-webpack": "webpack-dev-server --env development",
        "dev-server": "node app.js --env development"
    },
    "keywords": [],
    "author": "",
    "license": "ISC",
    "dependencies": {
        "@babel/cli": "^7.0.0",
        "@babel/core": "^7.0.0",
        "@babel/preset-env": "^7.0.0",
        "babel-watch": "^7.0.0",
        "bcrypt": "^3.0.4",
        "body-parser": "^1.18.3",
        "cors": "^2.8.5",
        "db-migrate-mysql": "^1.1.10",
        "dotenv": "^6.2.0",
        "express": "^4.16.4",
        "extract-text-webpack-plugin": "^3.0.2",
        "multer": "^1.4.2",
        "mysql": "^2.16.0",
        "type-of-is": "^3.5.1"
    },
    "devDependencies": {
        "@babel/core": "^7.6.2",
        "@babel/preset-env": "^7.6.2",
        "babel-loader": "^8.0.6",
        "html-loader": "^0.5.5",
        "html-webpack-plugin": "^3.2.0",
        "nodemon": "^1.18.10",
        "webpack": "^4.41.0",
        "webpack-cli": "^3.3.9",
        "webpack-dev-middleware": "^3.7.2",
        "webpack-dev-server": "^3.8.2",
        "webpack-hot-middleware": "^2.25.0",
        "webpack-node-externals": "^1.7.2"
    }
}

.ENV[.DEVELOPMENT] EXAMPLE (Note: I have a development and a production version, of course...)

APP_NAME=spinder_api
DB_HOST=localhost
DB_USERNAME=db_username
DB_PASSWORD=my_strong_passwrod
DB_DATABASE=my_app_database
PORT=3300

in your webpack config you are building to public/dist/ there should be a bundle.js in there to run. Then simply node bundle.js

That seems like an odd location for a node project but it's easy to change.

This question is very difficult to answer given that there are so many ways to deploy an application. There are entities like Google Cloud Platform, Amazon Web Services, Microsoft Azure, ZEIT Now, Heroku, and many more. All of those have capabilities to add your endpoints and certificates for the domain that you have bought. Here's a few examples:

You can then use whatever endpoint it's configured for to access your app, API, etc.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM