riot / webpack-loader

Riot official webpack loader

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

unable use "file-loader" for the static images embedded in side the riot component

go2sujeet opened this issue · comments

Please help me on how can I use file-loader module for the static images embedded inside a riot.tag.

Here is my webpack.config.js and test.cmp.tag

<test>
    <div class="top-left-part">
        <!-- Logo -->
        <a class="logo" href="index.html">
            <!-- Logo icon image, you can use font-icon also -->
            <b>
                        <!--This is dark logo icon-->
                        <img src="../plugins/images/admin-logo.png" alt="home" class="dark-logo">
                        <!--This is light logo icon-->
                        <img src="../plugins/images/admin-logo-dark.png" alt="home" class="light-logo">
                    </b>
            <!-- Logo text image you can use text also -->
            <span class="hidden-xs">
                        <!--This is dark logo text-->
                        <img src="../plugins/images/admin-text.png" alt="home" class="dark-logo">
                        <!--This is light logo text-->
                        <img src="../plugins/images/admin-text-dark.png" alt="home" class="light-logo">
                    </span>
        </a>
    </div>
</test>
const path = require('path')
const webpack = require('webpack')
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require("extract-text-webpack-plugin");


module.exports = {
    entry: {
        home: path.resolve(__dirname, './src/apps/home/home.app.js')
            // home2: path.resolve(__dirname, './src/apps/home/home.app.js')

    },
    output: {
        path: path.resolve(__dirname, "./public"),
        filename: 'js/[name].bundle.js'
    },
    node: {
        fs: 'empty'
    },
    // devtool: 'inline-source-map',
    module: {
        rules: [{
            test: /\.tag$/,
            exclude: /node_modules/,
            use: [{
                loader: 'riot-tag-loader'
            }
              ]
        }, {
            test: /\.css$/,
            loader: ExtractTextPlugin.extract({
                use: 'css-loader',
                fallback: 'style-loader'
            })
        }, {
            test: /\.less$/,
            loader: ExtractTextPlugin.extract({
                use: [{
                    loader: 'css-loader',
                    options: {
                        url: false,
                        paths: [path.resolve(__dirname, "node_modules")]
                    },
                }, {
                    loader: 'less-loader',
                    options: {
                        url: false,
                        paths: [path.resolve(__dirname, "node_modules")]
                    }
                }],
                fallback: 'style-loader'
                    // ,publicPath:publicPath_Css
            })
        }, {
            test: /\.(png|jpg|gif|svg)$/,
            use: [{
                loader: 'file-loader',
                options: {
                    name: '[name].[ext]',
                    outputPath: "images"
                }
            }]
        }, {
            test: /\.(eot|com|json|ttf|woff|woff2)(\?v=\d+\.\d+\.\d+)?$/,
            loader: 'url-loader?emitFile=false'
        }]
    },
    plugins: [
        new ExtractTextPlugin({
            filename: "/css/[name].css"

        }), new HtmlWebpackPlugin({
            hash: true,
            chunks: ["home"],
            filename: path.resolve(__dirname, "./public/pages/home.html"),
            title: "home1",
            template: path.resolve(__dirname, "./src/pages/home.page.html"),
            minify: {
                // collapseWhitespace: true
            }
        })
    ]
}

you should use the file loader in your javascript and not in your riot templates

<my-component>
  <img src={myImage}/>
  <script>
      import img from './file.png';
      export default {
        myImage: img
      }
  </script>
</my-component>

I am closing this issue since it's not a riot problem

This is history but for whomever might come across this issue like I did:

Because Riot.js only uses plain HTML syntax (and here we again have an example why this was a great choice), you can apply the usual webpack loader chain before invoking the Riot loader (here with webpack 4 and Riot 5):

        {
          test: /\.riot$/,
          exclude: /\/(node_modules)\//,
          use: [
            '@riotjs/webpack-loader',
            'extract-loader',
            'html-loader',
            },
          ]
        },

@GianlucaGuarini to me that approach seems preferable to importing / declaring a variable: it is a clear separation of concerns and allows all webpack tools to be used for images (or other non-code source types). Reply appreciated in case you see drawbacks to that approach 🙂

Note: not being a big webpack fan I am just unsure whether 'html-loader' + 'extract-loader' is the ideal combination to achieve this, but it certainly works.

@geonanorch I don't comment on closed issues but this time I will make an exception.

To me loading assets in the bundle is a hack to avoid, I rather prefer <img src='path/to/your/image.jpg'/> for better caching and simplicity.

If the extract-loader works for you feel free to use it, I wouldn't recommend such complex solutions to embed an image in a HTML file though.

@GianlucaGuarini exception appreciated 🙂 Maybe I wasn't clear though, what I am suggesting results in just that (caching and simplicity):
with the above config, webpack resolves <img src="./myproject/src/img/image.jpg" /> to <img src="/img/image.jpg" /> while outputting the image file to the build target. It saves the extra declaration in the riot component and allows to use webpack's plugins (resize, compression, etc...)