14

I am trying to deploy my app on Github to Heroku but getting error:

ERROR in ./src/Index.tsx Module not found: Error: Can't resolve './ConfigureStore' in '/app/src' @ ./src/Index.tsx 9:23-50

Seems like Typescript issue when I deploy on Heroku.

Although, works perfect in my local and webpack generates bundles and app runs fine. Below is my webpack.config:

const path = require('path');
const webpack = require('webpack');
const merge = require('webpack-merge');
const CheckerPlugin = require('awesome-typescript-loader').CheckerPlugin;
const rootModulePath = "./src/";

module.exports = {
    stats: { modules: false },
    resolve: {
        extensions: ['.js', '.jsx', '.ts', '.tsx', '.css']
    },
    entry: {
        'DIG': rootModulePath + "Index.tsx"
    },
    externals: {
        jQuery: 'jQuery'
      },
      node: {
        fs: 'empty'
      },
    plugins: [
        new webpack.ProvidePlugin({
            '$': 'jquery',
            'jQuery': 'jquery'
          }),
        new webpack.IgnorePlugin(/\.\/locale$/),
        new CheckerPlugin()        
    ],
    devtool: 'source-map',
    output: {
        path: __dirname,
        filename: './public/dig.js'
    },
    module: {
        rules: [
            { test: /\.tsx?$/, include: /src/, use: ['awesome-typescript-loader?silent=true'] },
            //{ test: /\.ts$/, include: /src/, use: 'awesome-typescript-loader?silent=true' },
            { test: /\.html$/, use: 'html-loader?minimize=false' },
            {
                test: /\.less$/,
                use: [{
                    loader: "style-loader" // creates style nodes from JS strings
                }, {
                    loader: "css-loader" // translates CSS into CommonJS
                }, {
                    loader: "less-loader" // compiles Less to CSS
                }]
            },
            { test: /\.css$/, use: ['style-loader','css-loader'] },
            { test: /\.(png|jpg|jpeg|gif|svg)$/, use: 'url-loader?limit=25000' }
            // { test: /\.js/, loader: 'imports-loader?define=>false'}
        ]
    }    
};

package.json

{
  "name": "digeratia",
  "version": "1.0.0",
  "description": "",
  "main": "webpack.config.js",
  "scripts": {
    "build": "webpack --mode production",
    "start": "npm run build && node server.js"
  },
  "author": "Vivek Singh",
  "dependencies": {
    "@types/history": "4.6.2",
    "@types/numeral": "0.0.22",
    "@types/react": "16.1.0",
    "@types/react-bootstrap": "^0.32.6",
    "@types/react-dom": "16.0.4",
    "@types/react-hot-loader": "3.0.6",
    "@types/react-redux": "5.0.15",
    "@types/react-router": "4.0.23",
    "@types/react-router-dom": "4.2.6",
    "@types/react-router-redux": "5.0.13",
    "@types/webpack": "4.1.3",
    "@types/webpack-env": "1.13.5",
    "awesome-typescript-loader": "4.0.1",
    "axios": "^0.18.0",
    "bootstrap": "^4.0.0-alpha.6",
    "chai": "^4.1.2",
    "create-react-class": "^15.6.2",
    "datatables.net": "^1.10.16",
    "datatables.net-dt": "^1.10.16",
    "domain-task": "^3.0.3",
    "event-source-polyfill": "0.0.12",
    "express": "^4.16.2",
    "extract-text-webpack-plugin": "3.0.2",
    "file-loader": "1.1.11",
    "history": "4.7.2",
    "html-to-react": "1.3.3",
    "it": "^1.1.1",
    "json-loader": "0.5.7",
    "less": "^3.0.1",
    "less-loader": "^4.0.5",
    "lodash": "^4.17.4",
    "node-noop": "1.0.0",
    "numeral": "^2.0.6",
    "react": "^16.2.0",
    "react-bootstrap": "^0.32.1",
    "react-dom": "^16.2.0",
    "react-element-to-jsx-string": "^13.0.0",
    "react-hot-loader": "4.0.1",
    "react-image": "^1.0.1",
    "react-intl": "^2.4.0",
    "react-moment": "^0.7.0",
    "react-popper": "^0.9.2",
    "react-redux": "5.0.7",
    "react-router-dom": "4.2.2",
    "react-router-redux": "5.0.0-alpha.6",
    "redux": "3.7.2",
    "redux-thunk": "2.2.0",
    "shelljs": "^0.8.1",
    "style-loader": "^0.20.3",
    "to-string-loader": "^1.1.5",
    "typescript": "2.8.1",
    "url-loader": "1.0.1",
    "webpack": "4.4.1",
    "webpack-hot-middleware": "2.21.2",
    "webpack-merge": "4.1.2",
    "xit": "^0.2.0",
    "abort-controller": "^1.0.0",
    "babel-plugin-syntax-optional-chaining": "^7.0.0-alpha.13",
    "babel-runtime": "^6.26.0",
    "core-js": "^2.5.1",
    "css-loader": "^0.28.4",
    "css-to-string-loader": "^0.1.3",
    "react-render-html": "^0.6.0",
    "toastr": "^2.1.2",
    "webpack-cli": "^2.0.12"
  },
  "devDependencies": {
    "abort-controller": "^1.0.0",
    "babel-plugin-syntax-optional-chaining": "^7.0.0-alpha.13",
    "babel-runtime": "^6.26.0",
    "core-js": "^2.5.1",
    "css-loader": "^0.28.4",
    "css-to-string-loader": "^0.1.3",
    "react-render-html": "^0.6.0",
    "toastr": "^2.1.2",
    "webpack-cli": "^2.0.12"
  }
}

The github code url is here

Please help as am stuck on this issue since long time.

User3250
  • 2,961
  • 5
  • 29
  • 61

6 Answers6

16

So the issue is not what you posted it is. The issue got fixed because you assume Index.ts or Index.tsx is equivalent to index.ts or index.tsx. If you look at the below thread

webpack: fine on MacOS, loader errors on linux

It explains that building on Mac you wont face the issue. And I assume the same case with Windows as well. But with Linux you will face the issue. That is what is happening here. If you ssh to the heroku box

$ heroku ps:exec
Establishing credentials... done
Connecting to web.1 on ⬢ sleepy-sea-65699...
~ $ webpack -p --verbose
Hash: 8c20236f8268ce043077
Version: webpack 3.10.0
Time: 24904ms
            Asset     Size  Chunks                    Chunk Names
    ./docs/dig.js   608 kB       0  [emitted]  [big]  DIG
./docs/dig.js.map  4.25 MB       0  [emitted]         DIG
Entrypoint DIG [big] = ./docs/dig.js ./docs/dig.js.map
chunk    {0} ./docs/dig.js, ./docs/dig.js.map (DIG) 1.38 MB [entry] [rendered]
...
...
ERROR in ./src/configureStore.ts
Module not found: Error: Can't resolve './Stores' in '/app/src'
resolve './Stores' in '/app/src'
  using description file: /app/package.json (relative path: ./src)
    Field 'browser' doesn't contain a valid alias configuration
  after using description file: /app/package.json (relative path: ./src)
    using description file: /app/package.json (relative path: ./src/Stores)
      no extension
        Field 'browser' doesn't contain a valid alias configuration
        /app/src/Stores is not a file
      .js
        Field 'browser' doesn't contain a valid alias configuration
        /app/src/Stores.js doesn't exist
      .jsx
        Field 'browser' doesn't contain a valid alias configuration
        /app/src/Stores.jsx doesn't exist
      .ts
        Field 'browser' doesn't contain a valid alias configuration
        /app/src/Stores.ts doesn't exist
      .tsx
        Field 'browser' doesn't contain a valid alias configuration
        /app/src/Stores.tsx doesn't exist
      .css
        Field 'browser' doesn't contain a valid alias configuration
        /app/src/Stores.css doesn't exist
      as directory
        existing directory
          using path: /app/src/Stores/index
            using description file: /app/package.json (relative path: ./src/Stores/index)
              no extension
                Field 'browser' doesn't contain a valid alias configuration
                /app/src/Stores/index doesn't exist
              .js
                Field 'browser' doesn't contain a valid alias configuration
                /app/src/Stores/index.js doesn't exist
              .jsx
                Field 'browser' doesn't contain a valid alias configuration
                /app/src/Stores/index.jsx doesn't exist
              .ts
                Field 'browser' doesn't contain a valid alias configuration
                /app/src/Stores/index.ts doesn't exist
              .tsx
                Field 'browser' doesn't contain a valid alias configuration
                /app/src/Stores/index.tsx doesn't exist
              .css
                Field 'browser' doesn't contain a valid alias configuration
                /app/src/Stores/index.css doesn't exist

As you can see the case of the file in error is index and not Index

Also if you check you repo config

$ cat .git/config
[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
    ignorecase = true
    precomposeunicode = true

You can see the ignorecase is set to true, which is not good, because then git won't look at the file renames and cases changes and push renamed files.

So essentially the error is that your Index.ts should index.ts to make your build Cross-OS compatible

Case sensitive plugin

You should enable the case sensitive plugin for you development to avoid such issues

$ npm install --save-dev case-sensitive-paths-webpack-plugin

> fsevents@1.1.3 install /Users/tarun.lalwani/Desktop/tarunlalwani.com/tarunlalwani/workshop/ub16/so/DigeratiGlobalReact/node_modules/fsevents
> node install

[fsevents] Success: 
+ case-sensitive-paths-webpack-plugin@2.1.2
added 117 packages from 85 contributors and removed 3 packages in 9.661s

Update your webpack.config.js like below

const path = require('path');
const webpack = require('webpack');
const merge = require('webpack-merge');
const CheckerPlugin = require('awesome-typescript-loader').CheckerPlugin;
const rootModulePath = "./src/";
const rootBundlePath = "./src/bundle/";
const isDevBuild = true;
var CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');


module.exports = {
    stats: { modules: false },
    resolve: {
        extensions: ['.js', '.jsx', '.ts', '.tsx', '.css']
    },
    entry: {
        'DIG': rootModulePath + "Index.tsx"
    },
    externals: {
        jQuery: 'jQuery'
      },
      node: {
        fs: 'empty'
      },
    plugins: [
        new CaseSensitivePathsPlugin(),
        new webpack.ProvidePlugin({
            '$': 'jquery',
            'jQuery': 'jquery'
          }),
 ....

Now when you build you will see these issues directly in Windows/Mac as well

sh-3.2$ npm run build

> digeratiaglobal@1.0.0 build /Users/tarun.lalwani/Desktop/tarunlalwani.com/tarunlalwani/workshop/ub16/so/DigeratiGlobalReact
> webpack -p

Hash: 3762a6deb22d9fabd37b
Version: webpack 3.10.0
Time: 12279ms
            Asset     Size  Chunks                    Chunk Names
    ./docs/dig.js   511 kB       0  [emitted]  [big]  DIG
./docs/dig.js.map  3.56 MB       0  [emitted]         DIG

ERROR in ./src/configureStore.ts
Module not found: Error: [CaseSensitivePathsPlugin] `/Users/tarun.lalwani/Desktop/tarunlalwani.com/tarunlalwani/workshop/ub16/so/DigeratiGlobalReact/src/Stores/index.ts` does not match the corresponding path on disk `Index.ts`.
 @ ./src/configureStore.ts 6:15-34
 @ ./src/Index.tsx
npm ERR! code ELIFECYCLE
npm ERR! errno 2
Tarun Lalwani
  • 142,312
  • 9
  • 204
  • 265
  • Awesome! Thanks for digging in. So, eventually it comes out to be casing issue. I have a question though, so when I was doing directory import like `./Stores` and ignoring the Index, it should have worked coz there wasn't any case issue then. – User3250 Apr 06 '18 at 08:41
  • What OS are you using? – Tarun Lalwani Apr 06 '18 at 08:50
  • Mine is windows. It didn't work on Heroku when I tried directory import – User3250 Apr 06 '18 at 08:51
  • You need to rename each `Index.ts` to `index.ts` and then it work on Heroku. Also you should use a new repo now, to avoid the `ignorecase` config issue and messing up the history. I would suggest start with a fresh repo and don't enable `ignorecase` in git config – Tarun Lalwani Apr 06 '18 at 08:52
  • Also you should add the plugin to make sure such things don't happen in future https://github.com/Urthen/case-sensitive-paths-webpack-plugin – Tarun Lalwani Apr 06 '18 at 08:58
  • I faced this issue though. I had to re-rename my files to what is supposed to be before my change. That was my quicker solution. But, I'll need to figure this out later. Thank you, at least you gave me light on the road – Jean Manzo Jul 16 '22 at 14:10
2

I got it working.. Seems on Heroku Directory Import is not working.

Hence, when I qualified my import with 'Index.ts' or 'Index.tsx' the bundle got created perfect and app started to work as below:

From

import * as Store from './ConfigureStore'

To

import * as Store from './ConfigureStore/Index';

Might be helpful to someone in future.

User3250
  • 2,961
  • 5
  • 29
  • 61
1

Your file is called configureStore, while you try to import ConfigureStore, it should be with lowerCase "c".

It works on your machine but Heroku is case sensitive.

Nir Ben-Yair
  • 1,566
  • 3
  • 14
  • 18
0

Is the missing module is a dev-dependancy? In such case you won't see any problem locally, whilst Heroku doesn't install dev-dependancies, and you get "Module not found" error. To fix this, simply uninstall the dev-dependancy and reinstall the module with --save flag

Nati Kamusher
  • 533
  • 5
  • 9
0

For some reason i just added this

"heroku-prebuild": "export NPM_CONFIG_PRODUCTION=false; export NODE_ENV=; NPM_CONFIG_PRODUCTION=false NODE_ENV=development npm install --only=dev --dev",
"heroku-postbuild": "export NPM_CONFIG_PRODUCTION=true; export NODE_ENV=production;

I got it from this answer

by default, heroku removes your packages under devDependencies after build. Something in your app probably depends on the packages specified on devDependencies. The npm scripts above skips purging the devDependencies.

The.Wolfgang.Grimmer
  • 1,172
  • 2
  • 9
  • 32
0

I had an issue like this with a school assignment when I was deploying to Heroku. If anyone else has any issues in the future, make sure you create a file in your root directory called .npmrc. add production=false to that file then push to Heroku.