Giter Site home page Giter Site logo

taboca / doc-js-webpack-dev-with-proxy-for-express Goto Github PK

View Code? Open in Web Editor NEW
2.0 3.0 0.0 483 KB

Technote / ReactJS / A react-based application served from webpack with a proxy to local express server app for serving JSON

JavaScript 88.99% HTML 11.01%

doc-js-webpack-dev-with-proxy-for-express's Introduction

Study notes - Webpack and a proxy for Express

In this example, we will learn how to setup a React-based web app that is served from a local development server, and, at the same time, to have this application to load JSON data from another local server using Express. The logical issue that arises relates to cross-domain access; because your app is first served by the Webpack development server — let's say it comes from the localhost:8080. With that, XMLHTTPRequest access to other server-port is not allowed.

In this proposed solution, we will simply setup a proxy server using Webpack's configuration, which is intended to allow both the development environment and the API server working at the same time.

What are the sources and repositories here for?

The source in this repository is just kept for the sake of referencing the history of the project changes. Throughout this page you will be able to see links to positions in the history of changes.

Making sure certain files are not to be in the version control

First, make sure your .gitignore does not include the ./myProject/node_modules and ./myProject/dist. Dist is where files will be automatically generated by Webpack (and Babel).

myProject/node_modules/
myProject/dist/

Setup myProject

mkdir myProject
cd myProject

Initialize package.json

The setup here assumes NodeJS 8.6.0.

npm init  

Install React, React-DOM, Webpack, Webpack-dev-server

And other preset definitions so that Babel can transpile ES2015, and React-based code.

npm install react react-dom --save
npm install webpack webpack-dev-server babel-core babel-loader babel-preset-es2015 babel-preset-react babel-preset-stage-2 --save-dev

Setup scripts in the ./myProject/package.json

Check so far tree at this stage

"scripts": {
  "start": "node app.js",
  "babel-start": "npm run build",
  "build": "webpack --mode development && cp src/index.html dist/index.html && webpack-dev-server --mode development --content-base src/ --inline --hot --history-api-fallback",
  "build:prod": "webpack --mode production && cp src/index.html dist/index.html"
},

Preparing your React-based app with Webpack and Babel (for ES6 and React support)

Create your webpack.config.js

var path = require("path");
var DIST_DIR = path.resolve(__dirname, "dist");
var SRC_DIR = path.resolve(__dirname, "src");
var config = {
    entry: SRC_DIR + "/app/index.js",
    output: {
        path: DIST_DIR + "/app",
        filename: "bundle.js",
        publicPath: "/app/"
    },
    module: {
        rules: [
            {
                test: /\.js?/,
                include: SRC_DIR,
                loader: "babel-loader",
                query: {
                    presets: ["react", "es2015", "stage-2"]
                }
            }
        ]
    }
};
module.exports = config;

As you try to execute with "npm run build", in the first time, you should be prompted to install a cli tool.

Do an initial test to check if the Webpack "npm run babel-start" script it properly generating your React code:

npm run babel-start

And test in the browser

http://localhost:8080

Let's make a Node-based Express-based app.js server for serving the API

Check the tree at this stage

'use strict';

const express    = require('express');
const path       = require('path');
const bodyParser = require('body-parser');

const app = express();

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

app.post('/api/test', (req, res, next) => {

  var outputJSON = {
    'status' : null
  }

  console.log("Data received from client: ")
  console.log(req.body);

  res
    .status(200)
    .set('Content-Type', 'application/json')
    .send(JSON.stringify(outputJSON))
    .end();

});

// This cab be used in case you are serving production
//app.use('/', express.static(path.join(__dirname, 'dist')));

// [START listen]
const PORT = process.env.PORT || 8090;
app.listen(process.env.PORT || 8090, () => {
  console.log(`App listening on port ${PORT}`);
  console.log('Press Ctrl+C to quit.');
});
// [END listen]
// [END app]

module.exports = app;

Patching webpack.config.js to have a proxy

Check tree at this stage

devServer: {
  proxy: {
    "/a/*": {
      target: "http://localhost:8090",
      secure: false,
      rewrite: function(req, options) {
        //you can handle rewrite here if you need to
      }
    },

  }
},

Test your node.js app

node app.js  

Setup the new AJAX component to load from the app.js express

npm install axios --save  

Add the component to the ./src/app directory

import React, { Component } from 'react';
import axios from 'axios';

class APITester extends Component {

  constructor(props) {
    super(props);
    this.state = {
      loading    : false,
      status     : 'no data yet'
    };
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleSubmit(event) {
    event.preventDefault();

    this.setState({loading:true})

    var data = {
      "argumentToJSON": "foo"
    }

    //     axios.post('/app_send', {data}) // this is like data:data ..
    axios.post('/api/test', data)
        .then(res => {
          if(res.data.status=='ok') {
            this.setState({loading: false, status: 'ok'});
          };
        });

  }

  render() {
      if(!this.state.loading) {
        return (
          <div className="">
            <form onSubmit={this.handleSubmit}>
              <p>
                Result: {this.state.status} <br />
                <input type="submit" value="Call server" />
              </p>
            </form>
          </div>
        );
      } else {
        return (
          <div className="">
              <p>
                loading...
              </p>
          </div>
        );
      }
  }

}

export default APITester;

Update the App.js to include it :

import React, { Component } from 'react';
import APITester from './APITester';

class App extends Component {
  render() {
    return (
      <div className="App">
          <h1 className="App-title">
            Webpack development and API JSON via Proxy
          </h1>

          <APITester />
      </div>
    );
  }
}

export default App;

Run the Dev server

npm run babel-start

Test

http://localhost:8080

In a nutshell:

  • You are calling your app from localhost:8080
  • Webpack generates all the output files (index.html, index.js etc in the dist directory)
  • Webpack will proxy to localhost:8090
  • Your app.js will answer /api/test

doc-js-webpack-dev-with-proxy-for-express's People

Contributors

taboca avatar

Stargazers

Atlas avatar

Watchers

 avatar James Cloos avatar  avatar

doc-js-webpack-dev-with-proxy-for-express's Issues

In new attempt, possibly related to new webpack got Plugin/Preset files are not allowed to export objects, only functions."

Which relates to :

babel/babel#6808

I did follow the approach presets: ["@babel/preset-env", "@babel/react"] in a webpack.config.js being

var path = require("path");
var DIST_DIR = path.resolve(__dirname, "dist");
var SRC_DIR = path.resolve(__dirname, "src");
var config = {
    entry: SRC_DIR + "/index.js",
    output: {
        path: DIST_DIR + "/",
        filename: "bundle.js",
        publicPath: "/"
    },
    module: {
        rules: [
            {
                test: /\.js?/,
                include: SRC_DIR,
                loader: "babel-loader",
                query: {
                    presets: ["@babel/preset-env", "@babel/react"]
                }
            }
        ]
    }
};
module.exports = config;

With the install being:

  • npm install @babel/preset-react --save-dev
  • npm install babel-loader @babel/core @babel/preset-env --save-dev
  • npm install babel --save-dev
  • npm install webpack-dev-server --save-dev
  • npm install webpack --save-dev

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.