mcmath / ejs-html-loader

Webpack loader for rendering HTML from EJS templates
MIT License
47 stars 9 forks source link

Get compiled asset path #11

Closed eltiare closed 7 years ago

eltiare commented 7 years ago

Hi, I can't seem to figure out how to get the compiled path for JavaScript, CSS, images, etc with the cache-busting hash and insert it into my HTML. Any pointers?

DamianPereira commented 7 years ago

This loader just outputs plain HTML, according to the ejs templates. To get the compiled paths you need to chain it with other loaders. For images you can use file-loader, for css css-loader, etc.

For images the steps I use go like this:

  1. The <img> tags that you have in the template are unchanged by ejs-html-loader
  2. The produced html is loaded with html-loader, which converts them to require()
  3. The require() calls go to file-loader, which places them in dist/ with a hash
  4. html-webpack-plugin, grabs all assets, and generates a final html, with everything linked

Theres a similar process for CSS or other static assets. For JS it's more direct, you just require your code and it gets bundled and imported into the HTML by html-webpack-plugin. here is my webpack config, which does:

const path = require('path');
var HtmlWebpackPlugin = require('html-webpack-plugin');

const ExtractTextPlugin = require("extract-text-webpack-plugin");
const extractSass = new ExtractTextPlugin({
    filename: "css/[name].[contenthash].css",
});

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist')
  },
  devServer: {
    contentBase: path.join(__dirname, "dist"),
  },
  plugins: [
    new HtmlWebpackPlugin({
      filename: 'index.html',
      template: 'src/index.ejs'
    }),
    extractSass
  ],
  module: {
    rules: [
      {
        test: /\.scss$/,
        use: extractSass.extract({
          use: [{
            loader: "css-loader"
          }, {
            loader: "sass-loader"
          }],
        })
      },
      {
        test: /\.ejs$/,
        loader: [
          'html-loader',
          'ejs-html-loader'
        ]
      },
      {
        test: /\.(jpe?g|png|gif|svg)$/i,
        loader: [
          'file-loader?hash=sha512&digest=hex&name=./img/[hash].[ext]',
          'image-webpack-loader?bypassOnDebug'
        ]
      }
    ]
  }
};
eltiare commented 7 years ago

Dang, I was hoping to avoid the HTML plugin you are listing here. I prefer to avoid having a SPA and multiple HTML files, and don't like the automatic injection. I'll close this as this library isn't designed to do what I want. Thank you for the information.

DamianPereira commented 7 years ago

If you want to avoid html-loader you could use html-webpack-plugin with handlebars loader, and if you want to avoid html-webpack plugin you can use ejs-html-loader > html-loader > extract-loader > file-loader. If you want to avoid both then yeah, I don't really know how it could be done.

eltiare commented 7 years ago

Just the plugin. I seem to work against it more than it works for me.

mcmath commented 7 years ago

Thanks for addressing this issue @DamianPereira. And sorry this loader couldn't be more useful for your purposes @eltiare. While I could add this feature, it would just mimic the functionality of html-loader, which would seem to violate Webpack's guidelines. This loader is really meant to be chained with something like html-loader. Maybe I should put an example in the Readme.

DamianPereira commented 7 years ago

No problem! Loved your loader, I'm starting to learn webpack and tried to chain esl-loader with html loader, and spent hours trying to make it work. Thanks for your work.

Some examples would be nice, maybe add an examples/ folder with common use-cases? I could do a pull request with my example above if you're interested., I would clean it up a bit first, and add a few ejs files/images/css. Don't know if my usecase is that common though, I use webpack to generate a html+css+img site without a line of JS, which is weird for webpack (I get an empty bundle, that I can just delete with no effect).

mcmath commented 7 years ago

@DamianPereira Don't worry about doing a PR. I'll be updating the docs shortly anyway, so I think it's easiest if I just add an example or two while I'm at it. Thanks for offering though.