15

I realise there is some debate about using webpacker in Rails engines but I have a simple usecase and currently have a workaround. Would like to know of a better (the best?) solution.

In this rails engine I have webpacker setup in the "spec/dummy" directory and everything works well in dev: https://github.com/RealEstateWebTools/property_web_scraper/tree/master/spec/dummy/config/webpack

When the engine is used by a rails app however it will not find the compiled webpack files so each time I have a release ready I compile the webpack files and manually copy them to the vendor directory: https://github.com/RealEstateWebTools/property_web_scraper/tree/master/vendor/assets/javascripts

I then require that file here: https://github.com/RealEstateWebTools/property_web_scraper/blob/master/app/assets/javascripts/property_web_scraper/spp_vuetify.js

In my layout I use the above file using the good old sprockets "javascript_include_tag": https://github.com/RealEstateWebTools/property_web_scraper/blob/master/app/views/layouts/property_web_scraper/spp_vuetify.html.erb

In the layout there is a check to see if I'm running the "spec/dummy" app in which case I will user webpacker as it would normally be used in dev.

There must be a better way than this.

PropertyWebBuilder
  • 1,286
  • 2
  • 12
  • 18
  • 2
    I would also like to know the answer to this. – Angel Garcia Jun 13 '19 at 04:20
  • 1
    I've struggled with this exact issue. Essentially, there isn't a good solution using webpacker. The only solution I've found (which is how DHH has agreed as the best approach) is to add a package.json file to your engine, and load it in your main project as an NPM package. This way the JS dependencies are resolved correctly when installing the package in your target app. – Jon Oct 19 '20 at 14:24
  • 1
    Had this same issue time ago for implementing Cocoon gem inside an engine. I was desperate and I found out that there isn't a "clean" or simple solution. Finally I solved it following [this tutorial](http://ben.vandgrift.com/posts/rails-engine-webpacker-1/), hope it helps – anonymus_rex Jan 21 '21 at 18:33

1 Answers1

1

Webpacker has been retired

https://github.com/rails/webpacker

Going forward, it's better to switch to jsbundling-rails with webpack.

(I would rather suggest esbuild as it's "10×-100× faster")

But let's do it with webpack:

rails new webpack-in-engine --javascript webpack --css tailwind --database postgresql

In app/javascript/application.js I do:

console.log("hello from application.js")                                                                    

And it works.

Now with an engine:

rails plugin new admin --mountable

Then depends:

Separate JS

Add an entry to your webpack.config.js:

const path    = require("path")
const webpack = require("webpack")

module.exports = {
  mode: "production",
  devtool: "source-map",
  entry: {
    application: "./app/javascript/application.js",
    admin: "./admin/app/javascript/admin.js"
  },
  output: {
    filename: "[name].js",
    sourceMapFilename: "[name].js.map",
    path: path.resolve(__dirname, "app/assets/builds"),
  },
  plugins: [
    new webpack.optimize.LimitChunkCountPlugin({
      maxChunks: 1
    })
  ]
}
    <%= javascript_include_tag "admin", "data-turbo-track": "reload", defer: true %>

Shared JS

    <%= javascript_include_tag "application", "data-turbo-track": "reload", defer: true %>

And in your app/javascript/application.js:

import "./../../admin/app/javascript/admin"

See full repo https://github.com/dorianmariefr/webpack-in-engine

Aside: Also I would rather namespace in the main app than have engines. I think engines are for very specific use cases not namespacing.

Dorian
  • 7,749
  • 4
  • 38
  • 57