Elm files are not compiled by Webpack in Phoenix framework

I have a problem using Elm with Phoenix framework. I have described the problem in more detail on Stackoverflow: https://stackoverflow.com/questions/67779387/elm-files-are-not-compiled-by-webpack-in-phoenix-framework

I’m just guessing: try with HardSourceWebpackPlugin disabled.

1 Like

That did make it better. Now it compiles, but I still have to restart the server for it to recompile.

what’s your npm run watch definition in package.json like?

Here’s mine:
"watch": "webpack watch --mode development --watch-options-stdin",

I have these lines:

"scripts": {
  "deploy": "webpack --mode production",
  "watch": "webpack --mode development --watch"

I tried your line, but didn’t seem to change anything. I still need to restart for file changes to take effect.

I’m not a webpack guru, but I cannot see HMR configured in your config, like:

(1) devServer.hot = true
(2) HotModuleReplacementPlugin (HotModuleReplacementPlugin | webpack)
(3) elm-hot-webpack-loader (GitHub - klazuka/elm-hot-webpack-loader: Webpack loader providing hot code swapping for Elm)

Here’s my webpack config:

const path = require('path');
const glob = require('glob');
const TerserPlugin = require('terser-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');

module.exports = (env, options) => {
  const devMode = options.mode !== 'production';

  return {
    optimization: {
      minimizer: [
        new TerserPlugin({
          terserOptions: {
            ecma: 5,
            compress: {
              pure_funcs: [
              pure_getters: true,
              keep_fargs: false,
              unsafe_comps: true,
              unsafe: true,
              passes: 2
            mangle: true
    entry: {
      'app': glob.sync('./vendor/**/*.js').concat(['./js/app.js'])
    output: {
      filename: '[name].js',
      path: path.resolve(__dirname, '../priv/static/js'),
      publicPath: '/js/'
    devtool: devMode ? 'eval-cheap-module-source-map' : undefined,
    module: {
      rules: [
          test: /\.js$/,
          exclude: /node_modules/,
          use: {
            loader: 'babel-loader'
          test: /\.elm$/,
          exclude: [/elm-stuff/, /node_modules/],
          use: {
            loader: 'elm-webpack-loader',
            options: {
              cwd: __dirname + '/elm/',
              debug: false, //options.mode === "development",
              optimize: options.mode === "production"
    plugins: [
      new CopyWebpackPlugin([{ from: 'static/', to: '../' }])

If you change some HTML in app_web/templates/layout/app.html.eex do you see the changes without having to manually reload the page?

Also, are you digesting your assets? I found that digesting in dev mode prevented changes to assets being picked up.

I don’t know what this means.

Yes. Although it’s immediately overwritten by Elm.

In endpoint.ex there is a block of code starting plug Plug.Static,, there should be some comments above it about running phx.digest. Check this block of code for gzip, and try setting it to false if it’s not already.

OK. It’s already set to false.

I’m not an expert, so i hope i’m not getting things mixed up, but i also encountered this problem and in my case it’s apparently already an issue on github as Version 7.01 doesn’t observe source code changes anymore.

Coud you be affected by this?

Some more questions:

Do you do something in particular in app.js or do you just include the Main.elm file?

What versions of Webpack and Webpack-cli are you running?

Webpack: v4.41.5
Webpack-cli: v3.3.12

Nope, just include Main.elm.

import { Elm } from "../elm/Main.elm";

You could have a look here and compare, its an example app for elm-phoenix-websocket.