Webpack to simply compile a bunch of Pug templates to HTML
Asked Answered
L

2

5

Im getting started with webpack but one thing I cannot for the life of me work out is how to take a folder (with possible nested folders), full of .pug templates, and simply compile them to static html and put them in the output folder, maintaining any nested folder structure for each output html file that was in the source templates folder...

I dont want to have to manually specify each individual .pug file, and I definitely dont want webpack to try and parse the .pugs into JS and then attempt to require/import any of the imgs/fonts etc in the pug files and then complain about it, Im just after a basic, static 1:1 compile, pug file in, html file out. Why is it so hard to do that?

Landscape answered 19/2, 2017 at 20:4 Comment(7)
it is possible with webpack but it is easier to use gulp if you are not mainly dealing with js filesChilli
id rather not add gulp and its dependencies into every project as well... you say its possible with webpack, could you elaborate?Landscape
show your existing webpack config. you can use function requireAll (r) { r.keys().forEach(r); } requireAll(require.context('./src', true, /\.pug$/)); to require every .pug files under src folder and configure file-loader to do the copyChilli
i dont have to use extract text plugin in there somewhere?Landscape
how does extract text plugin related to your question at all?Chilli
Heres a gist of my config: webpack config gist linkLandscape
i want to save static html files from each pug file, i thought the extract text plugin was the way to do this? just like you have to use the extract text plugin to save .css files from the sass-loader, dont you have to use extract text to save .html files from pug-loader?Landscape
C
11

Use pug-html-loader to convert .pug to .html file. Use file-loader to copy the file to desired location. Don't use html-loader as you don't want to process resources used by the generated file.

You will end up something like this in your loader rules (untested, webpack 1 syntax, you may need to tweak it for webpack 2)

{
    test: /\.pug$/,
    loaders: ['file-loader?name=[path][name].html', 'pug-html-loader?pretty&exports=false']
}

Next you need to require all your pug files in your entry file

function requireAll (r) { r.keys().forEach(r); }
requireAll(require.context('./', true, /\.pug$/));
Chilli answered 20/2, 2017 at 3:12 Comment(10)
I have one other question - say i use this require.context('./pug/', true, /\.pug$/) so its looking in the pug folder, currently when i use the file-loader with the name=[path][name].html query parameter, the templates are getting put into a pug folder in my build directory. eg if a certain source pug template lives in /pug/home/template.pug I end up with /dist/pug/home/template.html, but I want it to be dist/home/template.html is there a way to control what [path] will output in the file-loader query string?Landscape
try file-loader?name=[path][name].html&context=./pug, you may need to change the context parameter to make it workChilli
Im back again with something else - using this method, in my main bundle.js I now have a bunch of entries for the pug files, even though they dont need to be in there - eg (function(module, exports, __webpack_require__) { module.exports = __webpack_require__.p + "layouts/default.html"; /***/ }) how do i get rid of these?Landscape
You can put the requireAll call to a new entry file and ignore the js output of itChilli
ye i have a separate entry file for the pug stuff, how do i ignore the output of that entry file in the webpack.config.js?Landscape
you can't really ignore it with webpack, but you can set it output path to some ignored folder or have a extra step to remove that file. but that won't be inside webpackChilli
out of curiosity, when i use the ExtractTextPlugin for my scss/sass files, even though I have my main scss file as an entry point, no output bundle for that is generated... so it seems that plugins can take entry points and not emit a bundle for any imports/requires that match it? is there perhaps some kind of null plugin that I can use to stop webpack emitting a bundle file for the pug requires?Landscape
It is possible but I never used anything like before. You can ask a new question and maybe someone else can help you.Chilli
thanks, yea i asked a new question. also im an idiot - the extract text plugin was outputting a bundle.css :/Landscape
@ByranChen, sorry to bother you again, I have one other question with the pug templates - Im trying to pass the webpack hash into the pug templates so it can be used in script(src="bunde.${HASH}.js") etc... I have a separate question posted here but its got no comments for ages, any advice?Landscape
E
1

This can be done very simply with only html-webpack-plugin and pug-loader.

webpack.config.js

const HTMLWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  // No javascript entrypoint to evaluate. Let the plugin do the heavy lifting
  entry: {},
  // Define how to translate Pug to HTML
  module: { rules: [ { test: /\.pug$/, use: 'pug-loader' } ] },
  // Generate the HTML file from template
  plugins: [ new HTMLWebpackPlugin({ template: './src/index.pug' }) ]
};

./src/index.pug

doctype html
html(lang="en")
  head
    include path/to/another.pug
...

Got this information from https://extri.co/2017/05/23/using-htmlwebpackplugin-and-pug/ and you can also go further to import css and javascript as normally done with html-webpack-plugin.

Epigenesis answered 9/1, 2022 at 7:31 Comment(1)
You saved my life I'm trying something like this. But when I didn't define the entry: {} it kept trying to find an index.pug file in the src because of the loader and the resolve .pugNuss

© 2022 - 2024 — McMap. All rights reserved.