Where i am going wrong? I am unable to deploy my app to heroku even after running $ npm install --save-dev webpack
When i try to deploy my app to heroku i get the below:
remote: Compiling...
remote: Compilation failed:
remote:
remote: webpack not installed
remote:
remote: Install webpack to start bundling:
remote: $ npm install --save-dev webpack
remote:
remote:
remote:
remote: !
remote: ! Precompiling assets failed.
remote: !
remote: ! Push rejected, failed to compile Ruby app.
remote:
remote: ! Push failed
remote: Verifying deploy...
i have run npm install --save-dev webpack
, i have also run bundle exec rails webpacker:install
but when i deploy to heroku i get the same above message
This my application.js file in which i have defined webpack:
// This file is automatically compiled by Webpack, along with any other files
// present in this directory. You're encouraged to place your actual application logic in
// a relevant structure within app/javascript and only use these pack files to reference
// that code so it'll be compiled.
require("@rails/ujs").start()
require("turbolinks").start()
require("@rails/activestorage").start()
require("channels")
require("custom/alert")
var jQuery = require('jquery')
console.log("--- ALL JS FILES LOADED ---")
// Uncomment to copy all static images under ../images to the output folder and reference
// them with the image_pack_tag helper in views (e.g <%= image_pack_tag 'rails.png' %>)
// or the `imagePath` JavaScript helper below.
//
// const images = require.context('../images', true)
// const imagePath = (name) => images(name, true)
//include jQuery in global and window scope (so it can be accessed globally)
global.$ = global.jQuery = jQuery;
window.$ = global.jQuery = jQuery;
//include moment in global and window scope (so it can be accessed globally)
global.moment = moment;
window.moment = moment;
this is my environment.js file
const { environment } = require('@rails/webpacker')
const webpack = require('webpack')
environment.plugins.append(
'Provide',
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery'
})
)
module.exports = environment
this is my production.js file
process.env.NODE_ENV = process.env.NODE_ENV || 'production'
const environment = require('./environment')
module.exports = environment.toWebpackConfig()
and this is my package.json
{
"name": "sample_app",
"private": true,
"dependencies": {
"@rails/actioncable": "^6.0.0",
"@rails/activestorage": "^6.0.0",
"@rails/ujs": "^6.0.0",
"@rails/webpacker": "4.3.0",
"jquery": "^3.6.0",
"turbolinks": "^5.2.0"
},
"version": "0.1.0",
"devDependencies": {
"webpack": "^5.53.0",
"webpack-dev-server": "^3.11.2"
}
}
If you need nodejs (which is the runtime wepacks runs on), you have to tell Heroku about it, otherwise it will only have the ruby runtime.
In Heroku, these runtimes are called buildpacks and they are usually detected by default as long as there is one clear winner. For instance, whenever Heroku finds a Gemfile
, it will use the ruby buildpack.
You need to add the nodejs buildpack, which is achieved by running
heroku buildpacks:add --index 1 heroku/nodejs
Once this is set up, you will be able to push, and each buildpack will do its work, first nodejs
will install everything that is declared in package.json
, and then ruby
will install its own dependencies and finaly compile and start the app.