{"id":11898,"date":"2025-01-29T10:14:21","date_gmt":"2025-01-29T10:14:21","guid":{"rendered":"https:\/\/www.bacancytechnology.com\/qanda\/?p=11898"},"modified":"2025-01-29T10:14:21","modified_gmt":"2025-01-29T10:14:21","slug":"react-redux-and-rails-using-webpack-without-gem","status":"publish","type":"post","link":"https:\/\/www.bacancytechnology.com\/qanda\/ruby-on-rails\/react-redux-and-rails-using-webpack-without-gem","title":{"rendered":"React + Redux + Rails and Webpack Without Gem"},"content":{"rendered":"<h2>Ensure Installed Dependencies<\/h2>\n<p>Presuming logic for the Item model and endpoint already exists along with CORS allowed, we should start by installing necessary dependencies.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"ruby\">\r\nnpm install --save-dev webpack webpack-cli webpack-dev-server\r\nnpm install react react-dom redux axios\r\nnpm install --save-dev @babel\/core @babel\/preset-env @babel\/preset-react babel-loader\r\n<\/pre>\n<h2>Setup Webpack Configuration<\/h2>\n<p>Create a webpack.config.js file in the root directory so that we can start the server from the root directory by performing npm start.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"ruby\">\r\nconst path = require('path');\r\nmodule.exports = {\r\n  entry: '.\/frontend\/index.js', \/\/ Entry file for React\r\n  output: {\r\n    \/\/ Name pattern for build files\r\n    filename: 'bundle.js',\r\n    \/\/ Output location\r\n    path: path.resolve(__dirname, 'app\/assets\/javascripts'),\r\n  },\r\n  module: {\r\n    rules: [\r\n      {\r\n        test: \/\\.js?$\/, \/\/ Matches .js or .jsx files\r\n        exclude: \/node_modules\/,\r\n        use: {\r\n          loader: 'babel-loader',\r\n          options: {\r\n            \/\/ Transpile ES6+\r\n            presets: ['@babel\/preset-env', '@babel\/preset-react'],\r\n          },\r\n        },\r\n      },\r\n    ],\r\n  },\r\n  resolve: {\r\n    extensions: ['.js']\r\n  },\r\n  devtool: 'source-map',\r\n  devServer: {\r\n    contentBase: path.join(__dirname, 'public'),\r\n    \/\/ Enable hot module replacement\r\n    hot: true,\r\n    \/\/ React app will run on port 8080\r\n    port: 8080,\r\n    \/\/ Proxy API requests to Rails server\r\n    proxy: {\r\n      '\/api': 'http:\/\/localhost:3000',\r\n    },\r\n  },\r\n};\r\n<\/pre>\n<h2>Babel Configuration<\/h2>\n<p>Add .babelrc file at root directory.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"ruby\">\r\n{\r\n  \"presets\": [\r\n    \"@babel\/preset-env\",\r\n    \"@babel\/preset-react\"\r\n  ]\r\n}\r\n<\/pre>\n<h2>Create React Components<\/h2>\n<p>Create react components in a directory named frontend.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"ruby\">\r\n\/\/ index.js\r\n\r\nimport React from 'react';\r\nimport ReactDOM from 'react-dom';\r\nimport ItemList from '.\/ItemList;\r\nReactDOM.render(\r\n    <ItemList \/>\r\n  document.getElementById('root')\r\n);\r\n\/\/ItemList.js\r\n\r\nimport React, { useState, useEffect } from 'react';\r\nimport axios from 'axios';\r\n\r\nconst ItemList = () => {\r\n  const [items, setItems] = useState([]);\r\n  const [isLoading, setIsLoading] = useState(true);\r\nuseEffect(() => {\r\n    \/\/ Fetch the list of items upon component mount\r\n    (async () => {\r\n      try {\r\n        const response = await axios.get('\/api\/items');\r\n        setItems(res.data);\r\n        setIsLoading(false);\r\n      } catch (err) {\r\n        console.error(\"Error fetching items:\", err);\r\n        setIsLoading(false);\r\n      }\r\n    })();\r\n  }, []);\r\n\r\n  if (isLoading) {\r\n    return <div>Loading...<\/div>;\r\n  }\r\n  return (\r\n    <>\r\n      <h1>Items<\/h1>\r\n      <ul>\r\n        {\r\n          items.map(\r\n            item => (\r\n              <li key={item.id}>{item.name}<\/li>\r\n            )\r\n          )\r\n        }\r\n      <\/ul>\r\n    <\/>\r\n  );\r\n};\r\nexport default ItemList;\r\n<\/pre>\n<h2>Integrate React bundle in Rails View<\/h2>\n<p>In the Rails app, we will need to include the generated webpack bundle bundle.js in layout file app\/views\/layouts\/application.html.erb before closing the <\/body> tag.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"ruby\">\r\n<%= javascript_include_tag 'bundle.js' %>\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Ensure Installed Dependencies Presuming logic for the Item model and endpoint already exists along with CORS allowed, we should start by installing necessary dependencies. npm install &#8211;save-dev webpack webpack-cli webpack-dev-server npm install react react-dom redux axios npm install &#8211;save-dev @babel\/core @babel\/preset-env @babel\/preset-react babel-loader Setup Webpack Configuration Create a webpack.config.js file in the root directory so [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":11899,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"footnotes":""},"categories":[11],"tags":[],"class_list":["post-11898","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ruby-on-rails"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.bacancytechnology.com\/qanda\/wp-json\/wp\/v2\/posts\/11898"}],"collection":[{"href":"https:\/\/www.bacancytechnology.com\/qanda\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.bacancytechnology.com\/qanda\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.bacancytechnology.com\/qanda\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.bacancytechnology.com\/qanda\/wp-json\/wp\/v2\/comments?post=11898"}],"version-history":[{"count":1,"href":"https:\/\/www.bacancytechnology.com\/qanda\/wp-json\/wp\/v2\/posts\/11898\/revisions"}],"predecessor-version":[{"id":11900,"href":"https:\/\/www.bacancytechnology.com\/qanda\/wp-json\/wp\/v2\/posts\/11898\/revisions\/11900"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.bacancytechnology.com\/qanda\/wp-json\/wp\/v2\/media\/11899"}],"wp:attachment":[{"href":"https:\/\/www.bacancytechnology.com\/qanda\/wp-json\/wp\/v2\/media?parent=11898"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.bacancytechnology.com\/qanda\/wp-json\/wp\/v2\/categories?post=11898"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.bacancytechnology.com\/qanda\/wp-json\/wp\/v2\/tags?post=11898"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}