'Webpack alias not working when deploying to Heroku

I have set up a small demo app for a library we are working on at my company. We are using Vue CLI with webpack and node. I have managed to deploy it to Heroku just fine using their git deployment setup.

Recently I found the need for a translations file to be generated after build. I use a node command and triggers a small script that compiles an array of all the properties needed to render the app. The file is stored in a folder called /dist. Then I have set up an alias to the root of the application to be able to find the properties file once we are in the webpack handled files.

My vue.config.js looks like this:

const path = require('path');
const ROOT = path.resolve(__dirname, '.');

module.exports = {
  configureWebpack: {
    resolve: {
      alias: {
        '@root': ROOT,
        '@dist': path.resolve(ROOT, '/dist')
      }
    },
    devServer: { ... }
  }
};

And in my ./src/translationLoader.js I have the following lines to import the generated file:

import translations from '@dist/properties/translations-require.js';

// ...

AJS.I18n.keys = translations.en_UK;

It all works perfectly fine locally, but when I deploy to Heroku I get the following error message:

remote:        > vue-cli-service build ./src/main
remote:
remote:
remote: -  Building for production...
remote:         ERROR  Failed to compile with 1 errors7:09:01 AM
remote:
remote:        This dependency was not found:
remote:
remote:        * @dist/properties/translations-require.js in ./src/translation-loader.js
remote:
remote:        To install it, you can run: npm install --save @/../dist/properties/translations-require.js
remote:  ERROR  Build failed with errors.
remote: npm ERR! code ELIFECYCLE
remote: npm ERR! errno 1
remote: npm ERR! @refinedwiki/[email protected] build: `vue-cli-service build ./src/main`
remote: npm ERR! Exit status 1

I have verified that the file is correctly generated by logging in to Heroku using their bash tool to find it in the file structure. Any ideas of what I could have left out?


For reference, here's the package.json for the project:

{
  "name": "ui-docs",
  "engines": {
    "node": "14.15.x",
    "npm": "6.14.x"
  },
  "scripts": {
    "serve": "node i18nParser.js && vue-cli-service serve ./src/main --port 8100",
    "build": "vue-cli-service build ./src/main",
    "heroku-postbuild": "scripts/build-heroku.sh",
    "pipelines-setup": "scripts/setup-pipelines.sh",
    "pipelines-build": "scripts/build-pipelines.sh",
    "pipelines-merge-master": "node_modules/.bin/merge-master",
    "pipelines-config": "node_modules/.bin/config-setup",
    "start": "node server.js",
    "deploy": "node_modules/.bin/deploy-core",
    "deploy-heroku": "scripts/deploy-heroku.sh"
  },
  "repository": "bitbucket:refinedwikiteam/core-ui-docs",
  "license": "UNLICENSED",
  "dependencies": {
    "connect-history-api-fallback": "^1.6.0",
    "express": "^4.16.4",
    "fs-extra": "^9.0.1",
    "properties-reader": "^2.1.1",
    "serve-favicon": "^2.5.0",
    "serve-static": "^1.13.2",
    "vue": "^2.6.12",
    "vue-router": "^3.4.3",
    "webpack": "~4.41.6"
  },
  "devDependencies": {
    "@vue/cli-plugin-babel": "^3.4.0",
    "@vue/cli-service": "^3.4.0",
    "eslint-plugin-vue": "~6.0.1",
    "node-sass": "^4.14.1",
    "sass-loader": "^8.0.2",
    "vue-template-compiler": "^2.5.21"
  }
}


Solution 1:[1]

I was having a very similar problem and finally figured it out. So Ill post here my solution (even though is not exactly the same), just in case its useful for somebody.

The problem isnt with your alias config, the problem is that heroku is not copying the /dist folder into the temporary directory it uses to build the application. Therefore, when it tries to build it, it cant find it and fails. In order to achieve that Ive had to produce my own buildpack.

In my case, my folder structure was as follows:

electron_app/
 src/
web_app/
  src/
common_src/
  myfile.js
  ..etc

So, in order to just build the web_app in heroku, and for it also use the sources of the common_src folder we need to use the following buildpack:

  1. Add the buildpack to heroku
heroku buildpacks:add --index 1 https://github.com/GMolini/heroku-buildpack-subdir-to-root-extra-dirs.git --app <YOUR_APP>
  1. Tell the buildpack where the main sources of the app heroku needs to build are
heroku config:set PROJECT_RELATIVE_PATH=web_app --app <YOUR_APP>
  1. Tell the buildpack to copy to the build dir any extra directories your app needs
heroku config:set EXTRA_DIR_0=common_src --app <YOUR_APP>
heroku config:set EXTRA_DIR_1=another_needed_folder --app <YOUR_APP>
  1. Lastly, modify the webpack config so that the alias looks for the sources in the correct folder in development and in production (in heroku the folder will be at the same level as your src files)
  
const path = require('path');

let common_src_path = process.env.NODE_ENV === 'development' ? path.resolve(__dirname, '..', 'src_common') : path.resolve(__dirname, 'src_common');

module.exports = {
  configureWebpack: {
    resolve: {
      alias: {
        "@common_src": common_src_path,
      },
      extensions: ['.js', '.vue']
    },
    devtool: 'source-map'
  },
}

And thats it, if you push to heroku the build should find the necessary files.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 gumlym