<turbo-stream action="append" target="posts_list"><template>    <div class="postbit" id="136118" data-post-id="136118">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="peerreynders" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/peerreynders/120/5826_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  peerreynders
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>For future reference:</p>
<pre><code class="lang-plaintext">$ mix phx.new react_demo --no-ecto

* creating react_demo/config/config.exs
...
* creating react_demo/assets/static/robots.txt

Fetch and install dependencies? [Yn] Y
* running mix deps.get
* running cd assets &amp;&amp; npm install &amp;&amp; node node_modules/webpack/bin/webpack.js --mode development
* running mix deps.compile

We are almost there! The following steps are missing:

    $ cd react_demo

Start your Phoenix app with:

    $ mix phx.server

You can also run your app inside IEx (Interactive Elixir) as:

    $ iex -S mix phx.server

$ cd react_demo

react_demo$ mix phx.server
Compiling 12 files (.ex)
Generated react_demo app
[info] Running ReactDemoWeb.Endpoint with cowboy 2.6.3 at 0.0.0.0:4000 (http)
[info] Access ReactDemoWeb.Endpoint at http://localhost:4000

Webpack is watching the files…

Hash: 1fc94cc9b786e491ad40
Version: webpack 4.4.0
Time: 513ms
Built at: 7/12/2019 1:08:54 PM
                Asset       Size       Chunks             Chunk Names
       ../css/app.css   10.6 KiB  ./js/app.js  [emitted]  ./js/app.js
               app.js   7.26 KiB  ./js/app.js  [emitted]  ./js/app.js
       ../favicon.ico   1.23 KiB               [emitted]  
../images/phoenix.png   13.6 KiB               [emitted]  
        ../robots.txt  202 bytes               [emitted]  
   [0] multi ./js/app.js 28 bytes {./js/app.js} [built]
[../deps/phoenix_html/priv/static/phoenix_html.js] 2.21 KiB {./js/app.js} [built]
[./css/app.css] 39 bytes {./js/app.js} [built]
[./js/app.js] 493 bytes {./js/app.js} [built]
    + 2 hidden modules
Child mini-css-extract-plugin node_modules/css-loader/dist/cjs.js!css/app.css:
    [./node_modules/css-loader/dist/cjs.js!./css/app.css] 284 bytes {mini-css-extract-plugin} [built]
    [./node_modules/css-loader/dist/cjs.js!./css/phoenix.css] 10.9 KiB {mini-css-extract-plugin} [built]
        + 1 hidden module
</code></pre>
<p>Check in the browser <a href="http://localhost:4000/" rel="noopener nofollow ugc">http://localhost:4000/</a> to see the “Phoenix Framework” page.</p>
<pre><code class="lang-plaintext">^C
BREAK: (a)bort (c)ontinue (p)roc info (i)nfo (l)oaded
       (v)ersion (k)ill (D)b-tables (d)istribution
a

react_demo $ cd assets

assets $ npm i -g npm-check-updates
.npm-global/bin/npm-check-updates -&gt; .npm-global/lib/node_modules/npm-check-updates/bin/npm-check-updates
.npm-global/bin/ncu -&gt; .npm-global/lib/node_modules/npm-check-updates/bin/ncu
+ npm-check-updates@3.1.18
added 260 packages from 118 contributors in 8.122s

assets $ ncu -u

Upgrading react_demo/assets/package.json
[====================] 12/12 100%

 @babel/core                          ^7.0.0  →  ^7.5.4 
 @babel/preset-env                    ^7.0.0  →  ^7.5.4 
 babel-loader                         ^8.0.0  →  ^8.0.6 
 copy-webpack-plugin                  ^4.5.0  →  ^5.0.3 
 css-loader                           ^2.1.1  →  ^3.0.0 
 mini-css-extract-plugin              ^0.4.0  →  ^0.7.0 
 optimize-css-assets-webpack-plugin   ^4.0.0  →  ^5.0.3 
 uglifyjs-webpack-plugin              ^1.2.4  →  ^2.1.3 
 webpack                               4.4.0  →  4.35.3 
 webpack-cli                         ^2.0.10  →  ^3.3.5 

Run npm install to install new versions.

assets $ npm i

npm WARN assets No description

added 119 packages from 103 contributors, removed 596 packages, updated 72 packages, moved 3 packages and audited 8034 packages in 17.606s
found 63 high severity vulnerabilities
  run `npm audit fix` to fix them, or `npm audit` for details

assets $ npm i -D  @babel/preset-react

npm WARN assets No description

+ @babel/preset-react@7.0.0
added 7 packages from 1 contributor and audited 8056 packages in 4.55s
found 63 high severity vulnerabilities
  run `npm audit fix` to fix them, or `npm audit` for details

assets $ npm i -P react react-dom

npm WARN assets No description

+ react@16.8.6
+ react-dom@16.8.6
added 5 packages and audited 8082 packages in 4.779s
found 63 high severity vulnerabilities
  run `npm audit fix` to fix them, or `npm audit` for details
assets $ 
</code></pre>
<p>Delete <code>assets/.babelrc</code></p>
<pre><code class="lang-plaintext">assets $ rm .babelrc

</code></pre>
<p>Create <code>assets/babel.config.js</code></p>
<pre><code class="lang-plaintext">module.exports = function (api) {
  api.cache(true);

  const presets = [
    '@babel/preset-env',
    '@babel/preset-react',
  ]
  const plugins = [
  ]

  return {
    presets,
    plugins
  };
}
</code></pre>
<p>Modify <code>assets/webpack.config.js</code></p>
<pre data-code-wrap="javascript"><code class="lang-javascript">const path = require('path');
const glob = require('glob');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');

module.exports = (env, options) =&gt; ({
  optimization: {
    minimizer: [
      new UglifyJsPlugin({ cache: true, parallel: true, sourceMap: false }),
      new OptimizeCSSAssetsPlugin({})
    ]
  },
  entry: {
    './js/app.js': glob.sync('./vendor/**/*.js').concat(['./js/app.js'])
  },
  output: {
    filename: 'app.js',
    path: path.resolve(__dirname, '../priv/static/js')
  },
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/, /* add jsx */
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader'
        }
      },
      {
        test: /\.css$/,
        use: [MiniCssExtractPlugin.loader, 'css-loader']
      }
    ]
  },
  plugins: [
    new MiniCssExtractPlugin({ filename: '../css/app.css' }),
    new CopyWebpackPlugin([{ from: 'static/', to: '../' }])
  ]
});
</code></pre>
<p>Modify <code>assets/js/app.js</code>:</p>
<pre data-code-wrap="javascript"><code class="lang-javascript">// We need to import the CSS so that webpack will load it.
// The MiniCssExtractPlugin is used to separate it out into
// its own CSS file.
import css from "../css/app.css"

// webpack automatically bundles all modules in your
// entry points. Those entry points can be configured
// in "webpack.config.js".
//
// Import dependencies
//
import "phoenix_html"

// Import local files
//
// Local files can be imported directly using relative paths, for example:
// import socket from "./socket"

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

const App = ({ title }) =&gt;
  &lt;div&gt;{title}&lt;/div&gt;

const title = "Hello World!"

ReactDOM.render(
    &lt;App title={title} /&gt;,
  document.getElementById('app')
)
</code></pre>
<p>Replace contents of  <code>react_demo/lib/react_demo_web/templates/page/index.html.eex</code> with</p>
<pre><code class="lang-plaintext">&lt;div id="app"&gt;&lt;/div&gt;

</code></pre>
<pre><code class="lang-plaintext">$ cd ..

react_demo $ mix phx.server

Compiling 1 file (.ex)
[info] Running ReactDemoWeb.Endpoint with cowboy 2.6.3 at 0.0.0.0:4000 (http)
[info] Access ReactDemoWeb.Endpoint at http://localhost:4000

webpack is watching the files…

Hash: 422aabb9c911039eccdd
Version: webpack 4.35.3
Time: 683ms
Built at: 07/12/2019 2:00:54 PM
                Asset       Size       Chunks             Chunk Names
       ../css/app.css   10.6 KiB  ./js/app.js  [emitted]  ./js/app.js
       ../favicon.ico   1.23 KiB               [emitted]  
../images/phoenix.png   13.6 KiB               [emitted]  
        ../robots.txt  202 bytes               [emitted]  
               app.js    911 KiB  ./js/app.js  [emitted]  ./js/app.js
Entrypoint ./js/app.js = ../css/app.css app.js
[0] multi ./js/app.js 28 bytes {./js/app.js} [built]
[../deps/phoenix_html/priv/static/phoenix_html.js] 2.21 KiB {./js/app.js} [built]
[./css/app.css] 39 bytes {./js/app.js} [built]
[./js/app.js] 790 bytes {./js/app.js} [built]
[./node_modules/webpack/buildin/global.js] (webpack)/buildin/global.js 472 bytes {./js/app.js} [built]
    + 13 hidden modules
Child mini-css-extract-plugin node_modules/css-loader/dist/cjs.js!css/app.css:
    Entrypoint mini-css-extract-plugin = *
    [./node_modules/css-loader/dist/cjs.js!./css/app.css] 282 bytes {mini-css-extract-plugin} [built]
    [./node_modules/css-loader/dist/cjs.js!./css/phoenix.css] 10.9 KiB {mini-css-extract-plugin} [built]
        + 1 hidden module

</code></pre>
<p>Looking at <a href="http://localhost:4000/" rel="noopener nofollow ugc">http://localhost:4000/</a> you should see:</p>
<p></p><div class="lightbox-wrapper"><a class="lightbox" href="https://forum.elixirforum.com/uploads/default/original/3X/1/7/176c78d34cc99c62927374c9ab65a7ff77bed51c.png" data-download-href="https://forum.elixirforum.com/uploads/default/176c78d34cc99c62927374c9ab65a7ff77bed51c" title="react_demo" rel="nofollow"><img src="https://forum.elixirforum.com/uploads/default/optimized/3X/1/7/176c78d34cc99c62927374c9ab65a7ff77bed51c_2_517x111.png" alt="react_demo" data-base62-sha1="3ldnGe8Jf315BLWX3h6PxUqNkoA" width="517" height="111" srcset="https://forum.elixirforum.com/uploads/default/optimized/3X/1/7/176c78d34cc99c62927374c9ab65a7ff77bed51c_2_517x111.png, https://forum.elixirforum.com/uploads/default/optimized/3X/1/7/176c78d34cc99c62927374c9ab65a7ff77bed51c_2_775x166.png 1.5x, https://forum.elixirforum.com/uploads/default/optimized/3X/1/7/176c78d34cc99c62927374c9ab65a7ff77bed51c_2_1034x222.png 2x" data-dominant-color="DEDCDC"><div class="meta"><svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use href="#far-image"></use></svg><span class="filename">react_demo</span><span class="informations">2178×472 56.9 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use href="#discourse-expand"></use></svg></div></a></div><p></p>
<p>The resulting <code>assets/package.json</code>:</p>
<pre><code class="lang-plaintext">{
  "repository": {},
  "license": "MIT",
  "scripts": {
    "deploy": "webpack --mode production",
    "watch": "webpack --mode development --watch"
  },
  "dependencies": {
    "phoenix": "file:../deps/phoenix",
    "phoenix_html": "file:../deps/phoenix_html",
    "react": "^16.8.6",
    "react-dom": "^16.8.6"
  },
  "devDependencies": {
    "@babel/core": "^7.5.4",
    "@babel/preset-env": "^7.5.4",
    "@babel/preset-react": "^7.0.0",
    "babel-loader": "^8.0.6",
    "copy-webpack-plugin": "^5.0.3",
    "css-loader": "^3.0.0",
    "mini-css-extract-plugin": "^0.7.0",
    "optimize-css-assets-webpack-plugin": "^5.0.3",
    "uglifyjs-webpack-plugin": "^2.1.3",
    "webpack": "4.35.3",
    "webpack-cli": "^3.3.5"
  }
}
</code></pre> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="136118" data-batch-url="/posts/batch_likers">
                        5
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/connecting-react-with-phoenix/23935/22">Post #21</a>
	                </div>
	            </div>
              <div id="likers-container-136118" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="136118"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #21"></div>
  </section>
</div>
    <div class="postbit" id="136120" data-post-id="136120">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="kokolegorille" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/kokolegorille/120/4784_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  kokolegorille
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I thought babel 7 needed also in webpack.config.js, js loader as mentionned in the previous link to babel config… but it seems not.</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">options: {
  rootMode: "upward",
}
</code></pre> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="136120" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/connecting-react-with-phoenix/23935/23">Post #22</a>
	                </div>
	            </div>
              <div id="likers-container-136120" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="136120"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #22"></div>
  </section>
</div>
    <div class="postbit" id="136133" data-post-id="136133">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="peerreynders" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/peerreynders/120/5826_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  peerreynders
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="onebox allowlistedgeneric" data-onebox-src="https://babeljs.io/docs/options/">
  <header class="source">
      <img src="https://babeljs.io/img/favicon.png" class="site-icon" alt="" width="32" height="32">

      <a href="https://babeljs.io/docs/options/" target="_blank" rel="noopener nofollow ugc">babeljs.io</a>
  </header>

  <article class="onebox-body">
    

<h3><a href="https://babeljs.io/docs/options/" target="_blank" rel="noopener nofollow ugc">Options · Babel</a></h3>

  <p>- Primary options</p>


  </article>

  <div class="onebox-metadata">
    
    
  </div>

  <div style="clear: both"></div>
</aside>

<p>If I understand it correctly:</p>
<ul>
<li><code>webpack</code> is using <code>assets/</code> as the root directory</li>
<li>therefore <code>assets/babel.config.js</code> is in the root directory</li>
<li>the default is <code>rootMode: "root"</code></li>
<li>so it “just works”</li>
</ul>
<p><code>"upward"</code> is necessary when your configuration file in a parent directory is controlling the configuration of multiple Node.js projects below it.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="136133" data-batch-url="/posts/batch_likers">
                        2
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/connecting-react-with-phoenix/23935/24">Post #23</a>
	                </div>
	            </div>
              <div id="likers-container-136133" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="136133"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #23"></div>
  </section>
</div>
    <div class="postbit" id="136350" data-post-id="136350">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="OvermindDL1" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/OvermindDL1/120/2677_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  OvermindDL1
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="Yama" data-post="19" data-topic="23935">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/y/c89c15/48.png" class="avatar"> Yama:</div>
<blockquote>
<p>An example was when I had to bind every function I was making before but now just needing to <code>name = () =&gt; {}</code></p>
</blockquote>
</aside>
<p>The purpose of binding is to get <code>this</code> to point to the class object rather than the global <code>this</code>.  That’s part of Javascript’s weird <code>this</code> handling and has nothing to do with React.  ^.^;</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="136350" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/connecting-react-with-phoenix/23935/25">Post #24</a>
	                </div>
	            </div>
              <div id="likers-container-136350" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="136350"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-last-post cat-last-post" title="Last post!"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <span class="all-loaded">— All posts loaded —</span>
</div></template></turbo-stream>