AIon
AIon

Reputation: 13071

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 :)

Upvotes: 2

Views: 863

Answers (3)

ento
ento

Reputation: 5889

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 ] []

Upvotes: 2

AIon
AIon

Reputation: 13071

I've ended up using CopyWebpackPlugin from here.

 plugins: [ 
    ...
    new CopyWebpackPlugin([
       { from: './src/static/img', to: 'img' }
    ])
 ]

I doesn't work with async stuff form what i've read - but is good enough for what i needed here.

I will wait for another answer to mark it as accepted - if it can provide a solution using a loader. Until then, folks having this issue can try using this copy plugin.

Upvotes: 0

botika
botika

Reputation: 503

I would simply copy these images with Copy Webpack Plugin. In your webpack config plugins list push this:

new CopyWebpackPlugin({
    from: '',
    to: ''
})

Another way is to manage images from CSS and use file-loader:

{
   test: /\.(jpg|png)$/,
   use: `file-loader?${ objToUrlParameters({

          name: 'assets/img/[name].[hash:6].[ext]',
          publicPath: options.publicPath

        })
      }`
},

Upvotes: 3

Related Questions