title: How to fix Webpack 'You may need an appropriate loader to handle this file type' when running inside a container?
body: <p><strong>Issue:</strong></p>
  
  <p>The issue is that the moment we start Webpack in a docker container it's not able to find the 'babel-loader` to parse the jsx even though we install the node modules in the container.</p>
  
  <p><strong>Context:</strong></p>
  
  <p>I have a docker-compose setup where I have a set of containers including a website where I run Express that renders a React website.</p>
  
  <p>In the current situation we run de docker-compose and run Webpack on our local develop machines and the build.js files get mapped into the container and nodemon restarts the server. <em>This works</em>.</p>
  
  <p>Because sometimes freelancers/new teammembers join this project their local node/npm versions may result in errors when running on the local machine.</p>
  
  <p>This is why we want to spin up a develop container where we run Webpack and map the build files back to the local machine and into the website container.</p>
  
  <p>Note that I'm not trying to have a webpack-dev-server running, it should just listen for changes in src files and output the build files.</p>
  
  <p><strong>Attempts:</strong></p>
  
  <ul>
  <li>Change the node version of the container</li>
  <li>Updated the node modules to the latest version</li>
  <li>Install webpack/babel globally in the container</li>
  </ul>
  
  <p><strong>Dockerfile-dev</strong></p>
  
  <pre><code>###############################################################################
  # Step 1 : Create a base image
  #
  FROM node:12.6 as base
  WORKDIR /var/www
  
  ###############################################################################
  # Step 2 : Create all files needed to run the app
  #
  FROM base as builder
  ARG SSH_KEY
  
  COPY ./ /var/www
  
  RUN mkdir /root/.ssh/
  RUN echo "$SSH_KEY" &gt; /root/.ssh/id_rsa
  RUN chmod 600 /root/.ssh/id_rsa
  
  RUN ssh-keyscan gitlab.com &gt; /root/.ssh/known_hosts
  
  # configure the npm env
  RUN npm set progress=false
  RUN npm i --no-optional
  
  ###############################################################################
  # Step 3 : Final image to export
  #
  FROM base
  
  # Copy files from the build step
  COPY --from=builder /var/www/ /var/www
  
  CMD [ "npm", "run", "dev" ]
  </code></pre>
  
  <p><strong>Docker-compose entry</strong></p>
  
  <pre><code>  develop:
      build:
        context: './site'
        dockerfile: Dockerfile-dev
      image: 'boilerplate-develop'
      container_name: 'boilerplate-develop'
      env_file:
        - ./config/local/.env
      restart: 'unless-stopped'
      volumes:
        - ./site/src:/var/www/src
  </code></pre>
  
  <p><strong>webpack.config.js</strong></p>
  
  <pre><code>const path = require('path')
  const nodeExternals = require('webpack-node-externals')
  const {resolve, loaders, plugins,} = require('./webpack/common.config')
  
  const PROD = process.argv.indexOf(`-p`) &gt; 0
  
  const getModule = type =&gt; ({
      rules: [
          {
              test: /\.js|jsx?$/,
              exclude: /(node_modules|bower_components|www\/)/,
              use: {
                  loader: `babel-loader`,
                  options: {
                      babelrc: false,
                      configFile: false,
                      presets: [
                          [
                            '@babel/preset-env',
                            {
                              forceAllTransforms: PROD,
                              modules: false,
                              useBuiltIns: false,
                              debug: false,
                            },
                          ],
                          ['@babel/preset-react', { development: !PROD }],
                      ],
                      plugins: [
                          "@babel/plugin-transform-async-to-generator",
                          "@babel/plugin-proposal-class-properties",
                          "@babel/plugin-transform-destructuring",
                          "@babel/plugin-proposal-object-rest-spread",
                          "@babel/plugin-transform-runtime",
                          ...(!PROD ? [] : ['@babel/transform-react-inline-elements']),
                          ...(!PROD ? [] : ['transform-react-remove-prop-types']),
                          [
                              "module-resolver",
                              {
                                  "alias": {
                                      "_scrollPercentage": [
                                          "./src/components/vendor/react-scroll-percentage/react-scroll-percentage.esm.js"
                                      ],
                                      "_components": ["./src/components/components.js"],
                                      "_actionTypes": ["./src/redux/actionTypes.js"],
                                      "_routes": ["./src/components/views/routes.js"],
                                      "_utils": ["./src/utils/utils.js"],
                                      "_view": ["./src/components/views/View.jsx"]
                                  }
                              }
                          ]
                      ]
                  }
              },
          },
          ...loaders[type],
      ],
  })
  
  const client = {
      entry: {
          "js/bundle": [`whatwg-fetch`, `core-js/features/promise`, `./src/client.jsx`,],
          "js/intro": `./src/intro.js`,
          serviceWorker: `./src/service-worker.js`,
      },
      output: {
          path: path.join(__dirname, `src`, `static`),
          filename: PROD ? `[name].[chunkhash].min.js` : `[name].js`,
      },
      resolve,
      module: getModule(`client`),
      plugins: plugins.client,
      stats: 'verbose'
  }
  
  const server = {
      target: `node`,
      node: {
          __dirname: false,
      },
      externals: [
          nodeExternals({
              modulesFromFile: true,
          }),
      ],
      entry: {
          js: `./src/server.js`,
      },
      output: {
          path: path.join(__dirname, `src/server/build`),
          filename: PROD ? `server.min.js` : `server.js`,
          libraryTarget: `commonjs2`,
      },
      resolve,
      module: getModule(`client`),
      plugins: plugins.server,
  }
  
  module.exports = [client, server,]
  
  </code></pre>
  
  <p><strong>Error:</strong></p>
  
  <pre><code>boilerplate-develop |     ERROR in ./src/client.jsx 37:4
  boilerplate-develop |     Module parse failed: Unexpected token (37:4)
  boilerplate-develop |     You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
  boilerplate-develop |     |
  boilerplate-develop |     | const Client = props =&gt; (
  boilerplate-develop |     &gt;     &lt;Provider store={store}&gt;
  boilerplate-develop |     |         &lt;Router history={history}&gt;
  boilerplate-develop |     |             &lt;App {...props} history={history} /&gt;
  boilerplate-develop |      @ multi whatwg-fetch core-js/features/promise ./src/client.jsx js/bundle[2]
  </code></pre>