Skip to content

Instantly share code, notes, and snippets.

@r6203
Last active October 14, 2018 06:49
Show Gist options
  • Save r6203/757f1aebaa9bd59e2afb76b0145f1912 to your computer and use it in GitHub Desktop.
Save r6203/757f1aebaa9bd59e2afb76b0145f1912 to your computer and use it in GitHub Desktop.
Phoenix + React + Webpack
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="">
<title>Hello PhoenixReactStarter!</title>
<link rel="stylesheet" href="<%= static_path(@conn, "/css/app.css") %>">
</head>
<body>
<%= render @view_module, @view_template, assigns %>
<%= if Mix.env == :dev do %>
<script src='http://localhost:3000/index.bundle.js'></script>
<% else %>
<script src="<%= static_path(@conn, "/js/index.bundle.js") %>"></script>
<% end %>
</body>
</html>
import React from 'react';
const App = (props) => (
<div className="container">
<header className="header">
<nav role="navigation">
<ul className="nav nav-pills pull-right">
<li><a href="http://www.phoenixframework.org/docs">Get Started</a></li>
</ul>
</nav>
<span className="logo"></span>
</header>
{props.children}
</div>
);
export default App;
use Mix.Config
# For development, we disable any cache and enable
# debugging and code reloading.
#
# The watchers configuration can be used to run external
# watchers to your application. For example, we use it
# with brunch.io to recompile .js and .css sources.
config :phoenix_react_starter, PhoenixReactStarter.Endpoint,
http: [port: 4000],
debug_errors: true,
code_reloader: true,
check_origin: false,
watchers: [node: ["./node_modules/.bin/webpack-dev-server", "--watch-stdin", "--colors",
cd: Path.expand("../", __DIR__)]]
# Watch static and templates for browser reloading.
config :phoenix_react_starter, PhoenixReactStarter.Endpoint,
live_reload: [
patterns: [
~r{priv/static/.*(js|css|png|jpeg|jpg|gif|svg)$},
~r{priv/gettext/.*(po)$},
~r{web/views/.*(ex)$},
~r{web/templates/.*(eex)$}
]
]
# Do not include metadata nor timestamps in development logs
config :logger, :console, format: "[$level] $message\n"
# Set a higher stacktrace during development. Avoid configuring such
# in production as building large stacktraces may be expensive.
config :phoenix, :stacktrace_depth, 20
# Configure your database
config :phoenix_react_starter, PhoenixReactStarter.Repo,
adapter: Ecto.Adapters.Postgres,
username: "postgres",
password: "postgres",
database: "phoenix_react_starter_dev",
hostname: "localhost",
pool_size: 10
import 'react-hot-loader/patch';
import React from 'react';
import ReactDOM from 'react-dom';
import { AppContainer } from 'react-hot-loader';
import Root from './app/Root';
const rootEl = document.getElementById('root');
ReactDOM.render(
<AppContainer>
<Root />
</AppContainer>,
rootEl
);
if (module.hot) {
module.hot.accept('./app/Root', () => {
const NextRoot = require('./app/Root').default;
ReactDOM.render(
<AppContainer>
<NextRoot />
</AppContainer>,
rootEl
);
});
}
<div id="root"></div>
import React from 'react';
const Main = () => (
<h1>Hello, React &amp; Phoenix!</h1>
);
export default Main;
{
"name": "phoenix_react_starter",
"version": "1.0.0",
"description": "To start your Phoenix app:",
"main": "index.js",
"directories": {
"test": "test"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "Robin Altay <info@robinaltay.com> (http://robinaltay.com)",
"license": "ISC",
"dependencies": {
"react": "^15.2.1",
"react-dom": "^15.2.1",
"react-router": "^2.5.2"
},
"devDependencies": {
"babel-core": "^6.10.4",
"babel-eslint": "^6.1.2",
"babel-loader": "^6.2.4",
"babel-preset-es2015": "^6.9.0",
"babel-preset-react": "^6.11.1",
"eslint": "^3.0.1",
"eslint-config-airbnb": "^9.0.1",
"eslint-plugin-import": "^1.10.3",
"eslint-plugin-jsx-a11y": "^2.0.1",
"eslint-plugin-react": "^5.2.2",
"react-hot-loader": "^3.0.0-beta.2",
"webpack": "^1.13.1",
"webpack-cli": "^1.0.0",
"webpack-dev-server": "^1.14.1"
}
}
import React from 'react';
import { Router, browserHistory } from 'react-router';
import routes from './routes';
const Root = () => (
<Router history={browserHistory}>
{routes}
</Router>
);
export default Root;
import React from 'react';
import { Route, IndexRoute } from 'react-router';
import App from './App';
import Main from '../main/Main';
const routes = (
<Route path="/" component={App}>
<IndexRoute component={Main} />
</Route>
);
export default routes;
var path = require('path');
var webpack = require('webpack');
var publicPath = 'http://localhost:3000/';
module.exports = {
devtool: 'source-map',
entry: [
path.join(__dirname, 'web/static/js/entry.jsx'),
'webpack-dev-server/client?http://localhost:3000',
'webpack/hot/only-dev-server',
],
output: {
path: path.join(__dirname, '/priv/static/js'),
filename: 'index.bundle.js',
publicPath: publicPath,
},
module: {
loaders: [
{
test: /\.jsx?$/,
loaders: ['babel'],
include: path.join(__dirname, 'web/static/js'),
exclude: /node_modules/,
},
],
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin(),
],
resolve: {
root: path.join(__dirname, ''),
modulesDirectories: [
'node_modules',
'web/static/js',
],
extensions: ['', '.js', '.jsx'],
alias: {
phoenix: path.join(__dirname, '/deps/phoenix/priv/static/phoenix.js'),
},
},
devServer: {
hot: true,
port: 3000,
historyApiFallback: true,
},
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment