Skip to content

Commit

Permalink
Initial "broken" commit 💔
Browse files Browse the repository at this point in the history
  • Loading branch information
Jean M. Lescure authored and Jean M. Lescure committed Dec 2, 2016
0 parents commit bd89aeb
Show file tree
Hide file tree
Showing 11 changed files with 344 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .babelrc
@@ -0,0 +1,3 @@
{
"presets": ["es2015", "es2016", "stage-0", "react"]
}
76 changes: 76 additions & 0 deletions .gitignore
@@ -0,0 +1,76 @@
# Created by https://www.gitignore.io/api/node,osx

### Node ###
# Logs
logs
*.log
npm-debug.log*

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage

# nyc test coverage
.nyc_output

# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# node-waf configuration
.lock-wscript

# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules
jspm_packages

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity



### OSX ###
*.DS_Store
.AppleDouble
.LSOverride

# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
41 changes: 41 additions & 0 deletions README.md
@@ -0,0 +1,41 @@
# Webpack CORS Sample

This is a sample React.js app created to exemplify the concepts detailed in the following article:

* [Coming Soon](http://gorillalogic.com/blog)

It is a simple `hello world` application which includes:

* a WebPack Dev Server sample implementation
* an Express.js API sample implementation
* a sample `HelloWorld` React.js component

All of the previous put together in order to show how CORS affects development of React.js apps.

## Dependencies

Run the following to install dependencies:

```
$ npm install
```

## Running DEV

This sample uses the npm package [concurrently](https://github.com/kimmobrunfeldt/concurrently) to run both the front-end dev server ([webpack-dev-server](https://github.com/webpack/webpack-dev-server)) and the back-end API ([Express.js](https://github.com/expressjs/express)) at the same time.

So, spinning up the `DEV` server and API is as easy as running:

```
$ npm run dev
```

## Packaging and running PROD

For simplicity's sake I have made packaging and running the `PROD` server into a single command:

```
$ npm start
```

This packages the production bundle into the `bundle` directory and spins up a single **Express.js** server that servers both the static bundle files as well as the API.
11 changes: 11 additions & 0 deletions api/api.js
@@ -0,0 +1,11 @@
module.exports = {
defineApi: function(app){
app.get('/api/v1/hello', function (req, res) {
res.send('Hello');
});

app.get('/api/v1/world', function (req, res) {
res.send('World');
});
}
}
Empty file added bundle/.keep
Empty file.
11 changes: 11 additions & 0 deletions index.html
@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hello, world</title>
</head>
<body>
<div id="root"></div>
<script type="text/javascript" src="bundle.js" charset="utf-8"></script>
</body>
</html>
37 changes: 37 additions & 0 deletions package.json
@@ -0,0 +1,37 @@
{
"name": "webpack-cors-sample",
"version": "1.0.0",
"description": "Sample code for article: Webpack and CORS - Demystifying Cross-server communications in React.js",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev-server": "NODE_ENV=dev-server node server.js",
"dev-api": "NODE_ENV=dev-api node server.js",
"dev": "concurrently --kill-others \"npm run dev-server\" \"npm run dev-api\"",
"start": "webpack -p && node server.js"
},
"author": "",
"license": "MIT",
"dependencies": {
"express": "^4.14.0"
},
"devDependencies": {
"babel-loader": "^6.2.8",
"babel-plugin-transform-class-properties": "^6.19.0",
"babel-plugin-transform-runtime": "^6.15.0",
"babel-polyfill": "^6.16.0",
"babel-preset-es2015": "^6.18.0",
"babel-preset-es2016": "^6.16.0",
"babel-preset-react": "^6.16.0",
"babel-preset-stage-0": "^6.16.0",
"babel-register": "^6.18.0",
"concurrently": "^3.1.0",
"cors": "^2.8.1",
"file-loader": "^0.9.0",
"react": "^15.4.1",
"react-dom": "^15.4.1",
"webpack": "^1.13.3",
"webpack-dev-server": "^1.16.2",
"whatwg-fetch": "^2.0.1"
}
}
69 changes: 69 additions & 0 deletions server.js
@@ -0,0 +1,69 @@
// External libraries
var webpack = require('webpack');
var webpackDevServer = require('webpack-dev-server');
var express = require('express');

// Local files
var config = require('./webpack.config.js');
var api = require('./api/api');

if (process.env.NODE_ENV === 'dev-server') {
// = DEV =
// This stands up the webpack-dev-server
// with Hot Module Reloading enabled.

// The following is needed in order for
// Hot Module Reloading to work.
config.entry.app.unshift('webpack-dev-server/client?http://localhost:8080/', 'webpack/hot/dev-server');

// #########################################
// ############## IMPORTANT ################
// Here we are injecting the API_URL env var
// to be used by the `HelloWorld` component
config.plugins.unshift(new webpack.DefinePlugin({
'process.env':{
'API_URL': JSON.stringify('http://localhost:8081')
}
}));
// ############## /IMPORTANT ###############
// #########################################

// Initiate webpack-dev-server with the
// config we created in `webpack.config.js`
var compiler = webpack(config);
var server = new webpackDevServer(compiler, {
hot: true
});

server.listen(8080);
} else if (process.env.NODE_ENV === 'dev-api') {
// = DEV =
// This stands up the express.js API
var app = express();

// We define the API routes here
api.defineApi(app);

app.listen(8081, function () {
console.log('API is up!')
});
} else {
// = PROD =
// This is here for simplicity's sake,
// in a real-world application none of
// the development code should be copied
// over to the production server.
var app = express();

// We serve the bundle folder, which
// should contain an `index.html` and
// a `bundle.js` file only.
app.use('/', express.static('bundle'));

// We define the API routes here
api.defineApi(app);

app.listen(8080, function () {
console.log('Both front-end and API are up!')
});
}
13 changes: 13 additions & 0 deletions src/app.js
@@ -0,0 +1,13 @@
// We require the `index.html` file here so that
// WebPack packages it within the `PROD` bundle
require('file?name=[name].[ext]!../index.html');

import React from 'react';
import ReactDOM from 'react-dom';

import HelloWorld from './components/hello-world';

ReactDOM.render(
<HelloWorld />,
document.getElementById('root')
);
57 changes: 57 additions & 0 deletions src/components/hello-world.js
@@ -0,0 +1,57 @@
import React, { Component } from 'react';

// #####################################
// ############ IMPORTANT ##############
// Here the `API_URL` env var is being
// injected by the `server.js` file
const api_url = process.env.API_URL || '';
// ############ /IMPORTANT #############
// #####################################

// This is an over-simplified component
// which loads two strings via common
// `fetch` (ajax) calls.
//
// It is not meant to illustrate how
// react components should be built,
// in a real-world scenario data would
// be handled by a `Store` and managed
// by `Actions`.
class HelloWorld extends Component {
constructor(props) {
super(props);

this.state = {
hello: '',
world: ''
};
}

componentDidMount(){
const self = this;

fetch(api_url + '/api/v1/hello')
.then(function(response) {
return response.text();
}).then(function(text) {
self.setState({
hello: text
});
});

fetch(api_url + '/api/v1/world')
.then(function(response) {
return response.text();
}).then(function(text) {
self.setState({
world: text
});
});
}

render() {
return <h1>{this.state.hello} {this.state.world}!</h1>;
}
}

export default HelloWorld;
26 changes: 26 additions & 0 deletions webpack.config.js
@@ -0,0 +1,26 @@
var webpack = require('webpack');

module.exports = {
entry: {
app: ['whatwg-fetch', './src/app.js']
},
output: {
path: __dirname + '/bundle',
filename: 'bundle.js'
},
module: {
loaders: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader'
}
]
},
resolve: {
extensions: ['', '.js']
},
plugins: [
new webpack.HotModuleReplacementPlugin()
]
};

0 comments on commit bd89aeb

Please sign in to comment.