# Optimize elm compilation with webpack

**URL:** <https://discourse.elm-lang.org/t/optimize-elm-compilation-with-webpack/2191>\
**Category:** Learn\
**Created:** [October 12, 2018, 9:32am UTC](https://discourse.elm-lang.org/t/optimize-elm-compilation-with-webpack/2191 "2018-10-12T09:32:41Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![joecorkerton](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/joecorkerton/32/1346_2.png) [@joecorkerton](https://discourse.elm-lang.org/u/joecorkerton)\
**Post date:** [October 12, 2018, 9:32am UTC](https://discourse.elm-lang.org/t/optimize-elm-compilation-with-webpack/2191/1 "2018-10-12T09:32:41Z")

</div>

I am using Elm with webpack, and trying to reduce the compiled file size using the steps described here [https://elm-lang.org/0.19.0/optimize](https://elm-lang.org/0.19.0/optimize).

The issue is that I cannot seem to get webpack to treat the elm code any differently than the rest of the js I have. Would anyone mind sharing their config if they managed to achieve something similar? Particularly if they have a codebase with a mix of elm and non elm code to be uglified.

I found the following issue [https://github.com/elm-community/elm-webpack-loader/issues/140](https://github.com/elm-community/elm-webpack-loader/issues/140) but didn’t get anywhere after trying that config and tweaking it

---

<div class="post-metadata">

**Author:** ![pdamoc](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/pdamoc/32/36_2.png) [@pdamoc](https://discourse.elm-lang.org/u/pdamoc)\
**Post date:** [October 12, 2018, 9:36am UTC](https://discourse.elm-lang.org/t/optimize-elm-compilation-with-webpack/2191/2 "2018-10-12T09:36:25Z")

</div>

Have you seen Simon’s [elm-webpack-starter](https://github.com/simonh1000/elm-webpack-starter)?

---

<div class="post-metadata">

**Author:** ![rupert](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/rupert/32/1775_2.png) [@rupert](https://discourse.elm-lang.org/u/rupert)\
**Post date:** [October 12, 2018, 12:19pm UTC](https://discourse.elm-lang.org/t/optimize-elm-compilation-with-webpack/2191/3 "2018-10-12T12:19:00Z")

</div>

Perfect timing, as this is also the topic in which I am interested today.

In the elm-webpack-starter, the rule for handling the Elm code in production mode seems to be:

```
test: /\.elm$/,
exclude: [/elm-stuff/, /node_modules/],
use: [
    { loader: "elm-webpack-loader" }
]

```

Does this ‘loader’ also carry out the uglify/minify step? I suspect not, does that need to be added somewhere else within the webpack config?

In another ‘webpack.config.js’ that I have, which is very similar to the starter, I also have these 2 plugins in the production section:

```
  new UglifyJsPlugin(),
  new CompressionPlugin(),

```

I haven’t even tried this yet, I copied my build from somewhere else to get me started, but that seems likely to be what is needed?

---

<div class="post-metadata">

**Author:** ![joecorkerton](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/joecorkerton/32/1346_2.png) [@joecorkerton](https://discourse.elm-lang.org/u/joecorkerton)\
**Post date:** [October 12, 2018, 12:36pm UTC](https://discourse.elm-lang.org/t/optimize-elm-compilation-with-webpack/2191/4 "2018-10-12T12:36:45Z")

</div>

No, elm-webpack-loader does not uglify code by default ([https://github.com/elm-community/elm-webpack-loader/blob/master/index.js#L15](https://github.com/elm-community/elm-webpack-loader/blob/master/index.js#L15)). By default webpack will uglify your code, but it will not apply the flags which are optimal for Elm.

You need to use [https://github.com/webpack-contrib/uglifyjs-webpack-plugin](https://github.com/webpack-contrib/uglifyjs-webpack-plugin) (at least for webpack 4) with custom config. The problem for me is I am not sure what that config should be

---

<div class="post-metadata">

**Author:** ![rupert](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/rupert/32/1775_2.png) [@rupert](https://discourse.elm-lang.org/u/rupert)\
**Post date:** [October 12, 2018, 2:07pm UTC](https://discourse.elm-lang.org/t/optimize-elm-compilation-with-webpack/2191/5 "2018-10-12T14:07:05Z")

</div>

This guide:

[https://guide.elm-lang.org/optimization/asset\_size.html](https://guide.elm-lang.org/optimization/asset_size.html)

Says to use:

```auto
elm make src/Main.elm --optimize --output=elm.js
uglifyjs elm.js --compress 'pure_funcs="F2,F3,F4,F5,F6,F7,F8,F9,A2,A3,A4,A5,A6,A7,A8,A9",pure_getters,keep_fargs=false,unsafe_comps,unsafe' | uglifyjs --mangle --output=elm.min.js

```

But that is 2 passes of uglify. So yeah, how to set this up right with webpack?

---

<div class="post-metadata">

**Author:** ![klazuka](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/klazuka/32/862_2.png) [@klazuka](https://discourse.elm-lang.org/u/klazuka)\
**Post date:** [October 12, 2018, 5:52pm UTC](https://discourse.elm-lang.org/t/optimize-elm-compilation-with-webpack/2191/6 "2018-10-12T17:52:09Z")

</div>

There was some discussion about this on the PR to upgrade elm-webpack-loader to 0.19. Here you go: [https://github.com/elm-community/elm-webpack-loader/pull/142#issuecomment-416584398](https://github.com/elm-community/elm-webpack-loader/pull/142#issuecomment-416584398)

---

<div class="post-metadata">

**Author:** ![rupert](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/rupert/32/1775_2.png) [@rupert](https://discourse.elm-lang.org/u/rupert)\
**Post date:** [October 12, 2018, 7:03pm UTC](https://discourse.elm-lang.org/t/optimize-elm-compilation-with-webpack/2191/7 "2018-10-12T19:03:07Z")

</div>

I guess give this a go:

```
new UglifyJsPlugin({
  uglifyOptions: {
    compress: {
      pure_funcs: ['F2','F3','F4','F5','F6','F7','F8','F9','A2','A3','A4','A5','A6','A7','A8','A9'],
      pure_getters: true,
      keep_fargs: false,
      unsafe_comps: true,
      unsafe: true,
      passes: 3
    }
  }
})

```

I see it takes a ‘passes’ option.

---

<div class="post-metadata">

**Author:** ![Latty](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/latty/32/130_2.png) [@Latty](https://discourse.elm-lang.org/u/Latty)\
**Post date:** [October 16, 2018, 5:23am UTC](https://discourse.elm-lang.org/t/optimize-elm-compilation-with-webpack/2191/8 "2018-10-16T05:23:15Z")

</div>

It is also worth noting that if you have a mixture of Elm and other JS code, it’ll be dangerous to run the whole thing through uglify like that - unless I’m mistaken those options could potentially result in your JS getting messed up.

You can use [dynamic imports](https://webpack.js.org/guides/code-splitting/#dynamic-imports) to get around this. E.g:

```
import(/* webpackChunkName: "elm" */ "../elm/Main").then(
  ({ Elm: elm }) => {
    const app = elm.Main.init({ flags: null });
  }
);

```

That will split your code into two files - one with your elm, one with everything else. you can then have two uglify runs with different options - one over each file:

```
optimization: {
    minimizer: [
        new UglifyJsPlugin({
            test: /index\.js$/
        }),
        new UglifyJsPlugin({
            test: /elm\.js$/
            uglifyOptions: {
                compress: {
                    pure_funcs: ['F2','F3','F4','F5','F6','F7','F8','F9','A2','A3','A4','A5','A6','A7','A8','A9'],
                    pure_getters: true,
                    keep_fargs: false,
                    unsafe_comps: true,
                    unsafe: true,
                    passes: 3
                }
            }
        })
    ]
}
```

---

<div class="post-metadata">

**Author:** ![joecorkerton](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/joecorkerton/32/1346_2.png) [@joecorkerton](https://discourse.elm-lang.org/u/joecorkerton)\
**Post date:** [October 16, 2018, 9:51am UTC](https://discourse.elm-lang.org/t/optimize-elm-compilation-with-webpack/2191/9 "2018-10-16T09:51:36Z")

</div>

That was very helpful, I didn’t understand how to use dynamic imports previously.

I just tried it out now and it seems that creating separate chunks and uglifying the code as you suggested actually generated a slightly larger total file size! I am not sure why that is the case, but seems that we will stick with the default settings for now then.

Perhaps this is because the elm component is only a small part of the total js for that page

Without chunking + default uglify  
247,787 bytes

With chunking + elm compression settings  
226,032 + 22,088 = 248,120 bytes

(all gziped)

---

<div class="post-metadata">

**Author:** ![opvasger](https://avatars.discourse-cdn.com/v4/letter/o/8e8cbc/32.png) [@opvasger](https://discourse.elm-lang.org/u/opvasger)\
**Post date:** [October 16, 2018, 5:00pm UTC](https://discourse.elm-lang.org/t/optimize-elm-compilation-with-webpack/2191/10 "2018-10-16T17:00:55Z")

</div>

I’m working on Elm minification for Webpack.

> <https://github.com/opvasger/elm-minify/pull/13>

---

<div class="post-metadata">

**Author:** ![opvasger](https://avatars.discourse-cdn.com/v4/letter/o/8e8cbc/32.png) [@opvasger](https://discourse.elm-lang.org/u/opvasger)\
**Post date:** [October 17, 2018, 4:25pm UTC](https://discourse.elm-lang.org/t/optimize-elm-compilation-with-webpack/2191/11 "2018-10-17T16:25:00Z")

</div>

You can now use `elm-minify` as part of Webpack with [this plugin](https://github.com/opvasger/elm-minify#webpackplugin).

An example can be found [here](https://github.com/opvasger/elm-minify/tree/master/examples/withWebpack).

Let me know if you have any problems with the package ☀

---

<div class="post-metadata">

**Author:** ![system](https://canada1.discourse-cdn.com/flex035/uploads/elm_lang/original/1X/50a05e53677a2c3b47776d7abd0f113eb50193a1.png) [@system](https://discourse.elm-lang.org/u/system)\
**Post date:** [October 27, 2018, 4:25pm UTC](https://discourse.elm-lang.org/t/optimize-elm-compilation-with-webpack/2191/12 "2018-10-27T16:25:01Z")

</div>

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.
