Search code examples
webpack-dev-serverelmwebpack-2

how to load images used in elm code with webpack 2?


Suppose i have this view function:

view: Model -> Html Msg
view model = 
    img [ src "static/img/elm.jpg" ] []

How to make sure webpack 2 knows about it and loads it inside the dist folder as expected?

I found elm-asssets-loader package here - which is build for this scenario - but i don't understand how to use it. my webpack.config.js is:

module: {
   rules: [
        ...
       {
           test: /\.elm$/,
            exclude: [/elm-stuff/, /node_modules/],
            use: [{
                    loader: 'elm-hot-loader'
                  },
                  {
                      loader: 'elm-webpack-loader?verbose=true&warn=true&debug=true'
                  },
                  {
                      loader: 'elm-assets-loader?module=MyAssets&tagger=AssetPath'
                  },

            ]
        },


  ] 

}

I've seen elmAssetsLoader and fileLoader custom functions mentioned inside the docks - but is not clear where to put them. I tried placing them inside module.exports object, inside modules, inside plugins.. every time i get this error: Webpack has been initialized using a configuration object that does not match the API schema...

I also tried placing the elm-assets-loader before and after the elm--webpack-loader. When placed after elm-webpack-loader - i get an error inside the Main.elm file - which is wired because the Main.elm is just fine. Nothing wrong with it.

And when i place it before elm-webpack-loader absolutely nothing happens. Not even a warning message.

I also have the 2 modules as instructed:

-- module MyAssets exposing (..)
--
-- type AssetPath
--     = AssetPath String
--
-- elmImage : AssetPath
-- elmImage =
--     AssetPath "../static/img/elm.jpg" -- this is the location of my image, and it's correct.
--

and a view module with the image:

module View exposing (..)
view = 
   img [ src "what to put in here?" ] []

I'm new to webpack and that's probably why is not obvious to me what should i do. I want to understand the big picture. How things are wired.

What should i have inside my Html.Attributes.src function ?

I blindly tried many things. None of them worked. I lack the intuition.

Can somebody please provide a clear implementation of how this elm image/assets loading actually works in webpack 2? Thanks :)


Solution

  • I also tried placing the elm-assets-loader before and after the elm--webpack-loader

    elm-assets-loader takes the output of elm-webpack-loader and looks for asset paths in the compiled JavaScript. As webpack applies loaders in the use config from bottom to top, you want something like

    use: [{
            loader: 'elm-hot-loader'
        },
        {
            loader: 'elm-assets-loader?module=MyAssets&tagger=AssetPath'
        },
        {
            loader: 'elm-webpack-loader?verbose=true&warn=true&debug=true'
        },
    ]
    

    And when i place it before elm-webpack-loader absolutely nothing happens. Not even a warning message.

    This could be from not specifying the correct package in the loader config. If your elm-package.json's repository is something that is not "https://github.com/user/project.git", you need to specify the package:

    // when the repository is "https://github.com/alon/elmapp.git"
    loader: 'elm-assets-loader?module=MyAssets&tagger=AssetPath&package=alon/elmapp'    
    

    This is needed because elm-assets-loader looks for JavaScript code that looks like:

    _<package-user>$<package-project>$<module>$<tagger>("../static/img/elm.jpg")
    

    and if the package isn't correctly configured, it fails to find what it's supposed to find.

    img [ src "what to put in here?" ] []

    You need a helper function to pull out the string value contained in the AssetPath variable.

    module MyAssets exposing(AssetPath(..), path, elmImage)
    
    path : AssetPath -> String
    path (AssetPath str) =
        str
    
    -- 
    
    view = 
        img [ src <| MyAssets.path <| MyAssets.elmImage ] []