Code Monkey home page Code Monkey logo

pug-loader's Introduction

Webpack loader to render Pug templates

npm node node Test codecov node

The Pug Loader renders Pug templates into HTML or compiles it into a template function.

๐Ÿ’ก Highlights

  • Resolves paths and aliases for extends, include.
  • Resolves source asset files in tag attributes via require() function.
  • Resolves source JS/JSON files in Pug code via require() function.
  • Resolves alias from webpack resolve.alias or tsconfig.json.
  • Renders Pug template into pure HTML string.
  • Compiles Pug template into template function for render template in the browser.
  • Generates a template function with both CommonJS and ESM syntax.
  • Pass data into template from the loader options.
  • Build-in Pug filters: :escape :code :highlight :markdown with highlighting of code blocks
  • Supports an indent in Vue template, see source of an example.
  • Watching of changes in all dependencies.

Warning

Until today, 2024, only this Pug loader is maintained. Please support this project by giving it a star โญ.
All other Pug loaders are dead and have not been maintained for a long time:

Note

Instead of html-webpack-plugin recommended to use pug-plugin or html-bundler-webpack-plugin .

The Pug Plugin allow to use a template as an entrypoint and generates static HTML or template function from Pug template containing source files of scripts, styles, images, fonts and other resources, similar to how it works in Vite.

Please see usage examples and the demo app Hello World.

Contents

  1. Install and Quick start
  2. Options
  3. Using modes
  4. Using Pug filters
  5. Passing data into Pug template
  6. Using resources
  7. Path Resolving
  8. Using with Angular
  9. Using with Vue
  10. Recipes
  11. Example Hello World!
  12. Example Pug filters
  13. More examples

Install and Quick start

Choose your way:

  • Using the pug-plugin. It is a very easy intuitive way.
  • Using the html-webpack-plugin with the pug-loader. It is a very complex non-intuitive way.

Using only the pug-plugin

The pug-plugin contains already the pug and pug-loader packages. For details and examples please see the pug-plugin site.

Install the pug-plugin:

npm install pug-plugin --save-dev

Install additional packages for styles:

npm install css-loader sass-loader sass --save-dev

Start with a Pug template. Add the link and script tags. You can include asset source files such as SCSS, JS, images, and other media files directly in a Pug template.

The plugin resolves script(src="...") link(href="...") and img(src="..." srcset="...") that references your script, style and image source files.

For example, there is the template ./src/views/home.pug:

html
  head
    //- variable from Webpack config
    title= title
    //- relative path to favicon source file
    link(href="./favicon.ico" rel="icon")
    //- relative path to SCSS source file
    link(href="./style.scss" rel="stylesheet")
    //- relative path to JS source file -->
    script(src="./main.js" defer="defer")
  body
    h1 Hello World!
    //- relative path to image source file
    img(src="./picture.png")

All source filenames should be relative to the entrypoint template, or you can use Webpack alias. The references are rewritten in the generated HTML so that they link to the correct output files.

The generated HTML contains URLs of the output filenames:

<html>
  <head>
    <title>Homepage</title>
    <link href="img/favicon.3bd858b4.ico" rel="icon" />
    <link href="css/style.05e4dd86.css" rel="stylesheet" />
    <script src="js/main.f4b855d8.js" defer="defer"></script>
  </head>
  <body>
    <h1>Hello World!</h1>
    <img src="img/picture.58b43bd8.png" />
  </body>
</html>

If the entry plugin option is a path, the plugin finds all templates automatically and keep the same directory structure in the output directory.

If the entry plugin option is an object, the key is an output filename without .html extension and the value is a template file.

Very simple and clear webpack.config.js, all relevant settings are in one place, in plugin options:

const path = require('path');
const PugPlugin = require('pug-plugin');

module.exports = {
  output: {
    path: path.join(__dirname, 'dist/'),
  },

  plugins: [
    new PugPlugin({
      // automatically processing all templates in the path
      entry: 'src/views/',
      // - OR - define many pages manually (key is output filename w/o `.html`)
      entry: {
        // simple page config w/o variables
        index: 'src/views/home.pug', // => dist/index.html
        // advanced page config with variables
        'news/sport': { // => dist/news/sport.html
          import: 'src/views/news/sport/index.pug', // template file
          data: { title: 'Sport news' }, // pass variables into template
        },
      },
      data: {...}, // pass global data into all templates
      js: {
        // JS output filename, used if `inline` option is false (defaults)
        filename: 'js/[name].[contenthash:8].js',
        //inline: true, // inlines JS into HTML
      },
      css: {
        // CSS output filename, used if `inline` option is false (defaults)
        filename: 'css/[name].[contenthash:8].css',
        //inline: true, // inlines CSS into HTML
      },
    })
  ],

  module: {
    rules: [
      {
        test: /\.(s?css|sass)$/,
        use: ['css-loader', 'sass-loader']
      },
      {
        test: /\.(ico|png|jp?g|webp|svg)$/,
        type: 'asset/resource',
        generator: {
          filename: 'img/[name].[hash:8][ext][query]',
        },
      },
    ],
  },
};

Note

No additional plugins or loader required.

Warning

This way is not recommended!

Install the @webdiscus/pug-loader only if you use the html-webpack-plugin.

npm install @webdiscus/pug-loader html-webpack-plugin --save-dev

Install additional packages for styles:

npm install css-loader sass-loader sass --save-dev

Install additional plugin to extract CSS:

npm install mini-css-extract-plugin --save-dev

Using the html-webpack-plugin you should require a source asset file in the Pug template.

For example, there is the template ./src/views/home.pug:

html
  head
    //- variable from plugin options, very ugly access
    title= htmlWebpackPlugin.options.data.title
    //- relative path to favicon source file
    link(href=require("./favicon.ico") rel="icon")
    //- JS and CSS will be injected into HTML automatically, anywhere here
    //- Note: you have no control over the position or order of injected files
  body
    h1 Home
    //- relative path to image source file
    img(src=require("./picture.png"))

Very complex webpack.config.js:

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = {
  output: {
    path: path.join(__dirname, 'dist/'),
    // JS output filename must be defined only here
    filename: 'js/[name].[contenthash:8].js',
  },

  entry: {
    // Source files of styles and scripts must be defined here, separately from their templates.
    // How to bind each generated bundle to the HTML page?
    // Answer: using the `chunks` plugin option.
    index: ['./src/views/home/main.js', './src/views/home/style.scss'],
    'news/sport': ['./src/views/news/sport/main.js', './src/views/news/sportstyle.scss'],
  },

  plugins: [
    // For one page must be initialized the plugin instance.
    new HtmlWebpackPlugin({
      template: path.join(__dirname, 'src/views/home/index.pug'),
      // HTML output filename
      filename: 'index.html',
      // bind the generated JS and CSS files to this template via chunks,
      // this is a very terrible "crutch"
      chunks: ['index'],
      // pass variables into template,
      // access in template is very ugly: `htmlWebpackPlugin.options.data.title`
      data: { title: 'Home' }
    }),

    // For other page must be initialized yet one plugin instance.
    // It's very very bad practice and ugly syntax!
    new HtmlWebpackPlugin({
      template: path.join(__dirname, 'src/views/news/sport/index.pug'),
      // HTML output filename
      filename: 'news/sport.html',
      // bind the generated JS and CSS files to this template via chunks option,
      // you're not confused yet using chunks?
      chunks: ['news/sport'],
      // access in template is very ugly: `htmlWebpackPlugin.options.data.title`,
      // using `pug-plugin`, the variable in Pug is accessible w/o any scope: `title` 
      // (of cause, in `pug-plugin` you can define a variable scope, if you want)
      data: { title: 'Sport news' }
    }),
    
    // ... Do you have the joy of adding yet one page using the HtmlWebpackPlugin?
    // No? Then try to use the `pug-plugin`.

    // Yet one plugin to extract CSS and inject one into HTML.
    new MiniCssExtractPlugin({
      // CSS output filename defined in another place, here
      filename: 'css/[name].[contenthash:8].css',
    }),
  ],

  module: {
    rules: [
      // requires to define the pug loader
      {
        test: /\.pug$/,
        loader: '@webdiscus/pug-loader',
      },
      {
        test: /\.(s?css|sass)$/,
        // requires additional MiniCssExtractPlugin loader
        use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader'],
      },
      {
        test: /\.(png|jpe?g|ico)/,
        type: 'asset/resource',
        generator: {
          filename: 'img/[name].[hash:8][ext]',
        },
      },
    ],
  },
};

Why do many developers switch from Webpack to other bundlers? One of the reasons they cite is the complex configuration many different plugins and loaders for one simple thing - rendering an HTML page with assets.

The pug-plugin "changes the rule of the game". Just one plugin replaces the functionality of many plugins and loaders and makes configuration very simple and clear.

Using in JavaScript

A Pug template can be used in JavaScript code as template function with custom data.

Install the pug-loader.

npm install @webdiscus/pug-loader --save-dev

Change your webpack.config.js according to the following minimal configuration:

const path = require('path');

module.exports = {
  output: {
    path: path.join(__dirname, 'public/'),
    publicPath: '/', // must be defined any path, `auto` is not supported yet
  },
  entry: {
    index: './src/index.js', // load a Pug template in JS
  },
  module: {
    rules: [
      {
        test: /\.pug$/,
        loader: '@webdiscus/pug-loader',
      },
    ],
  },
};

Load a Pug template in JavaScript. Optional you can pass any data into generated template function.

./src/index.js

const tmpl = require('template.pug');
const html = tmpl({
  myVar: 'value',
});

Original options

See original description of options

basedir

Type: string Default: /
The root directory of all absolute inclusion.

doctype

Type: string Default: html
Specifies the type of document. See available doctypes.

self

Type: boolean Default: false
Use the self as namespace for the local variables in template. It will speed up the compilation, but for access to variable, e.g. myVariable, you must write self.myVariable.

globals

Type: Array<string> Default: []
Add a list of global names to make accessible in templates.

filters

Type: object Default: undefined
Filters let to use other languages in Pug templates. You can add your own custom filters to Pug. See the build-in filters.

plugins

Type: Array<Object> Default: []
Plugins allow to manipulate Pug tags, template content in compile process. How it works see in source of pug.

compileDebug

Type: boolean Default: false
Includes the function source in the compiled template to improve error reporting.

pretty

Type: boolean Default: false
This option is deprecated by pugjs and always is false. Don't use it.

Additional options

mode

Warning

Since the version 2.11.0, the method option name is renamed into mode.
The method option is DEPRECATED.

The method values are renamed:

  • pug-compile => compile
  • pug-render => render

The method option name and old values can be used until the next major version.

Type: string Default: compile
Values:

  • compile the Pug template compiles into a template function and in JavaScript can be called with variables to render into HTML at runtime.
    The query parameter is ?compile. Can be used if the mode is render.
    Use this mode, if the template have variables passed from JavaScript at runtime. see usage
  • render the Pug template renders into HTML at compile time and exported as a string. All required resource will be processed by the webpack and separately included as added strings wrapped to a function.
    The query parameter is ?render. Can be used if the mode is compile or is not defined in options.
    Use this mode, if the template does not have variables passed from JavaScript at runtime. The mode generates the most compact and fastest code. see usage
  • html the template renders into a pure HTML string at compile time. The mode need an addition loader to handles the HTML.
    Use this mode if the rendered HTML needs to be processed by additional loader, e.g. by html-loader see usage

Asset resources such as img(src=require('./image.jpeg')) are handled at compile time by the webpack using asset/resource.

esModule

Type: Boolean Default: false
Enable / disable ESM syntax in generated JS modules.
Values:

  • true The pug-loader generates JS modules with the ESM syntax.
    For example: import html from 'template.pug';.
    For smaller and faster JS code, it is recommended to use this mode.
  • false defaults. The pug-loader generates JS modules with the CommonJS modules syntax.
    For example, const html = require('template.pug').
    The default value is false for compatibility with the JS modules that is generated by the original pug-loader.

Note: The option esModule is irrelevant for the html mode, because it returns a pure HTML string.

๐Ÿ’ก For generates smaller and faster template function, it is recommended to use following options:

{
  mode: 'render',
  esModule: true,
}

data

Type: Object Default: {}
The custom data will be passed in all Pug templates, it can be useful by pass global data.

โš ๏ธ Limitation with the compile mode.
A string representing the source code of the function is limited by the function.toString(), see examples.
For native work of the function passed via the data loader option, use the render mode.

embedFilters

Type: Object Default: undefined
Enable embedded Pug filters. To enable a filter, add the following to the pug-loader options:

{
  embedFilters: {
    <FILTER_NAME> : <FILTER_OPTIONS> | <TRUE>,
  }
}

Where <FILTER_NAME> is the name of a built-in filter, the available filters see below. The filter can have options <FILTER_OPTIONS> as an object. If the filter has no options, use true as an option to enable the filter.

See the complete information on the pug filter site and in the sources.

watchFiles

Type: Array<RegExp|string> Default: [ /\.(pug|jade|js.{0,2}|.?js|ts.?|md|txt)$/i ]
This option allows you to configure watching of individual resolved dependencies.
The default value enables watching of Pug, scripts, markdown, etc. and ignores images, styles to avoid double processing via Webpack and via Pug's ist own compiler.

In some cases, you may want to use one SCSS file for styling and include another SCSS file with a Pug filter for code syntax highlighting. The first SCSS file is watched via Webpack, but changes in the second will be ignored.
For example, we want to watch for changes in all source examples such as main.c, colors.scss, etc. from the /code-samples/ folder, to do this, add to the watchFiles option:

{
  watchFiles: [
    /\\/code-samples\\/.+$/,
  ]
}

For watching of a file, add full path, for example:

{
  watchFiles: [
    path.join(__dirname, './src/config.yml'),
  ]
}

Note: Default value of watchFiles will be extends, not overridden.


Using compile mode

This mode is used by default.
In JavaScript the required template will be compiled into template function.
In webpack config add to module.rules:

{
  test: /\.pug$/,
    loader: '@webdiscus/pug-loader',
    options: {
    mode: 'compile' // default mode `compile` can be omitted
  }
}

In JavaScript, the result of require() is a template function. Call the template function with some variables to render it to HTML.

const tmpl = require('template.pug');
const html = tmpl({ key: 'value' }); // the HTML string

To render the Pug direct into HTML, use the query parameter ?render.

// compile into template function, because loader option 'mode' defaults is 'compile'
const tmpl = require('template.pug');
const html = tmpl({ key: 'value' });

// render the Pug file into HTML, using the parameter 'render'
const html2 = require('template2.pug?render');

Note: If the query parameter render is set, then will be used rendering for this template, independent of the loader option mode. Variables passed in template with mode render will be used at compile time.


Using render mode

This mode will render the Pug into HTML at compile time.
In webpack config add to module.rules:

{
  test: /\.pug$/,
    loader: '@webdiscus/pug-loader',
    options: {
      mode: 'render',
    },
}

In JavaScript the result of require() is an HTML string.

const html = require('template.pug'); // the HTML string

To generate a template function for passing the data in Pug at realtime, use the query parameter ?compile.

// render into HTML, because loader option 'mode' is 'render'
const html = require('template.pug');

// compile into template function, using the parameter 'compile'
const tmpl2 = require('template2.pug?compile');
const html2 = tmpl2({ ... });

Using html mode

This mode will render the Pug to pure HTML and should be used with an additional loader to handle HTML.
In webpack config add to module.rules:

{
  test: /\.pug$/,
    use: [
    {
      loader: 'html-loader',
      options: {
        esModule: false, // allow to use the require() for load a template in JavaScript
      },
    },
    {
      loader: '@webdiscus/pug-loader',
      options: {
        mode: 'html',
      },
    },
  ],
}

In JavaScript the result of require() is an HTML string:

const html = require('template.pug'); // the HTML string

Built-in filters

The goal of built-in filters is to use most useful lightweight filters without installation. The built-in filters are custom filters that are collected in one place. These filters can be simply enabled via an option.
See the complete information on the pug filter site and in the sources.

Defaults all built-in filters are disabled. Enable only filters used in your Pug templates.

:escape

The filter replaces reserved HTML characters with their corresponding HTML entities to display these characters as text.

Filter options: none.

Enable the filter:

{
  test: /\.pug$/,
    loader: '@webdiscus/pug-loader',
    options: {
    // enable built-in filters
    embedFilters: {
      escape: true, // enable the :escape filter
    },
  },
},

Using the :escape filter in pug:

pre: code.language-html
:escape
<h1>Header</h1>

Generated HTML:

<pre>
  <code class="language-html">
    &lt;h1&gt;Header&lt;/h1&gt;
  </code>
</pre>

Inline syntax:

p.
The #[:escape <html>] element is the root element.<br>
Inside the #[:escape <html>] element there is a #[:escape <body>] element.

Generated HTML:

<p>The &lt;html&gt; element is the root element.<br>
  Inside the &lt;html&gt; element there is a &lt;body&gt; element.</p>

For more information and examples, see the :escape site.

:code

The filter wraps a content with the <code> tag.

Filter options:

  • className {string} The class name of the code tag. For example, the prismjs use the language-* as class name in <code> for styling this tag.

Enable the filter:

{
  test: /\.pug$/,
    loader: '@webdiscus/pug-loader',
    options: {
    // enable built-in filters
    embedFilters: {
      // enable the :code filter
      code: {
        className: 'language-', // class name of `<code>` tag, needed for `prismjs` theme
      },
    },
  },
},

Usage examples:

Pug: #[:code function() { return true }]
Display: function() { return true }

Pug: #[:code:escape <div>]
Display: <div>

Pug: #[:code:highlight(html) <div class="container">content</div>]
Display highlighted code: <div class="container">content</div>

For more information and examples, see the :code site.

:highlight

The filter highlights code syntax.

Filter options:

  • verbose {boolean} Enable output process info in console.
  • use {string} The name of a highlighting npm module. The module must be installed. Currently, is supported the prismjs only.

Enable the filter:

{
  embedFilters: {
    highlight: {
      verbose: true,
        use: 'prismjs',
    },
  },
}

Usage example:

pre.language-: code
  :highlight(html)
    <!-- Comment -->
    <h1>Header</h1>
    <p>Text</p>

For more information and examples, see the :highlight site.

:markdown

The filter transform markdown to HTML and highlights code syntax.

The :markdown filter require the markdown-it and prismjs modules:

npm install -D markdown-it prismjs

Enable the filter:

{
  test: /.pug$/,
    loader: '@webdiscus/pug-loader',
    options: {
    // enable built-in filters
    embedFilters: {
      // enable :markdown filter
      markdown: {
        // enable highlighting in markdown
        highlight: {
          verbose: true,
            use: 'prismjs',
        },
      },
    },
  },
},

The highlight options:

  • verbose {boolean} Enable output process info in console. Use it in development mode only. Defaults is false.
  • use {string} The name of a highlighting npm module. The module must be installed. Currently, is supported the prismjs only.

Usage example:

  :markdown
    _HTML_
    ```html
    <!-- Comment -->
    <div class="container">
      <p>Paragraph</p>
    </div>
    ```
    _JavaScript_
    ```js
    const arr = [1, 2, 'banana'];
    ```

Display highlighted code blocks:

HTML

<!-- Comment -->
<div class="container">
  <p>Paragraph</p>
</div>

JavaScript

const arr = [1, 2, 'banana'];

For more information and examples, see the :markdown site.


Passing data into template

In JavaScript

By default, the Pug file is compiled as template function, into which can be passed an object with template variables.

const tmpl = require('template.pug');
const html = tmpl({
  myVar: 'value',
  foo: 'bar'
});

But how pass variables in template which is rendered into HTML?
Variables can be passed with query parameters.

const html = require('template.pug?myVar=value&foo=bar');

or as a JSON object:

const html = require('template.pug?' + JSON.stringify({ myVar: 'value', foo: 'bar' }));

Use variables myVar and foo in Pug template.

div The value of "myVar": #{myVar}
div The value of "foo": #{foo}

Usage of query parameters is legal and official documented feature of webpack loader.

In webpack.config.js

Pass myData object via query.

entry: {
  about: './src/pages/about.pug?myData=' + JSON.stringify({ title: 'About', options: { uuid: 'abc123' } })
}

Use the object myData in Pug template.

html
head
  title= myData.title
body
  div UUID: #{myData.options.uuid}

To pass global data to all Pug templates, add the loader options data as any object.

module.exports = {
  module: {
    rules: [
      {
        test: /\.pug$/,
        loader: '@webdiscus/pug-loader',
        options: {
          data: {
            htmlLang: 'en-EN',
            getKeywords: () => {
              const keywords = ['webpack', 'pug', 'loader'];
              return keywords.join(',');
            }
          }
        }
      },
    ],
  },
};

Use the custom data and function in pug.

html(lang=htmlLang)
head
  meta(name="keywords" content=getKeywords())
body

Passing data in HtmlWebpackPlugin

The user data can be passed into Pug template with two ways:

  • via HtmlWebpackPlugin options
  • via query parameters of template file
module.exports = {
  plugins: [
    new HtmlWebpackPlugin({
      title: 'The some page', // avaliable in Pug as `htmlWebpackPlugin.options.title`
      template: path.join(__dirname, 'src/index.pug?' + JSON.stringify({ myVar: 'value' })), // avaliable as `myVar`
      filename: 'index.html',
    }),
  ],
  module: {
    rules: [
      {
        test: /\.pug$/,
        loader: '@webdiscus/pug-loader',
      },
    ],
  },
};

Use the passed variables htmlWebpackPlugin.options and myVar in Pug template:

html
  head
    title= htmlWebpackPlugin.options.title
  body
    div= myVar

Load a static data in the pug

You can load data directly in pug.
data.json

[
  { "id": 1, "name": "abc" },
  { "id": 2, "name": "xyz" }
]

Require the JSON file in pug.

- var myData = require('./data.json')
each item in myData
  div #{item.id} #{item.name}

Using resources

To handle resources in Pug use the require() function:

img(src=require('./path/to/images/logo.png'))

For images, add the following rule to the webpack module:

module.exports = {
  module: {
    rules: [
      {
        test: /\.(png|jpg|jpeg|svg|ico)/,
        type: 'asset/resource',
        generator: {
          filename: 'assets/images/[name].[hash:8][ext]',
        },
      },
    ]
  },
};

For fonts, add the following rule to the webpack module:

module.exports = {
  module: {
    rules: [
      {
        test: /\.(woff2|woff|ttf|svg|eot)/,
        type: 'asset/resource',
        generator: {
          filename: 'assets/fonts/[name][ext]',
        },
      },
    ]
  },
};

More information about asset-modules see here.

Example of dynamic interpolation of image src in pug:

- files = ['image1.jpeg', 'image2.jpeg', 'image3.jpeg']
each file in files
  img(src=require(`./path/to/${file})`)

Path Resolving

Path aliases with Webpack

Recommended to use the Webpack alias to avoid relative paths in Pug.
For example, use the alias Images as path to images:

module.exports = {
  resolve: {
    alias: {
      Images: path.join(__dirname, 'src/assets/images/'),
    },
  }
};

The alias may be used with prefixes ~ or @.
For example, all following aliases resolves the same path:

img(src=require('Images/logo.png'))
img(src=require('~Images/logo.png'))
img(src=require('@Images/logo.png'))

Path aliases with TypeScript

Using TypeScript you can define an alias in tsconfig.json. But for performance is recommended to use the Webpack alias.
For example, add to tsconfig.json an alias to the paths option:

tsconfig.json

{
  "compilerOptions": {
    "paths": {
      "Images/*": ["assets/images/*"]
    }
  }
}

Warning

The compile mode can resolve the filename as a string only and the filename can't be interpolated.

img(src=require('Images/logo.png')) // It works.

- const file = 'logo.png'
img(src=require('Images/' + file))  // ERROR: Can't be resolved with 'compile' mode. 

Root path with Webpack context

You can use the Webpack context for a short path in Pug.
Define in Webpack config the context as path to sources:

module.exports = {
  context: path.resolve(__dirname, 'src'),
};

For example, your images are under the path PROJECT_PATH/src/assets/images/, then using the context you can use the root path (relative by context) anywhere:

img(src=require('/assets/images/logo.png'))

Note

You can use the basedir option of pug-loader for same effect:

module.exports = {
  module: {
    rules: [
      {
        test: /\.pug$/,
        loader: '@webdiscus/pug-loader',
        options: {
          basedir: path.resolve(__dirname, 'src')
        },
      },
    ],
   },
 };

Relative path

The file in the current- or subdirectory MUST start with ./:

img(src=require('./path/to/logo.png'))

The file in the parent directory MUST start with ../:

img(src=require('../images/logo.png'))

Warning

Following relative path will be resolved with render and html modes, but NOT with compile mode:

  img(src=require('../../images/logo.png'))

This is an interpolation limitation in Webpack.

Interpolation

You can use the filename as a variable.

Usage examples work with all modes:

- const file = 'logo.png'
img(src=require('./images/' + file))
img(src=require(`./images/${file}`))
img(src=require('../images/' + file))
img(src=require('Images/' + file)) // 'Images' is webpack alias
img(src=require(`Images/${file}`)

Warning

Limitation using the compile mode:
the variable MUST NOT contain a path, only a filename, because is interpolated at compile time.
For example, the 'compile' mode can't resolve following:

  - var file = '../images/logo.png'
  img(src=require(file))

Using a variable with render or html mode, the variable MAY contain a path, because is resolved at runtime.
Following example work only with render or html mode:

- const file = '../relative/path/to/logo.png'
img(src=require(file))
img(src=require('Images/' + file))

In current directory, the filename MUST start with ./:

- const file = './logo.png'
img(src=require(file))

Using with Angular

Install:

npm i --save-dev @webdiscus/pug-loader pug-plugin-ng

In pug-loader can be used the optional pug-plugin-ng to allow unquoted syntax of Angular: [(bananabox)]="val"

Create the file webpack.config.js in root directory of angular project:

module.exports = {
  module: {
    rules: [
      {
        test: /\.pug$/,
        loader: '@webdiscus/pug-loader',
        options: {
          mode: 'render',
          doctype: 'html',
          plugins: [require('pug-plugin-ng')],
        },
      },
    ],
  },
};

Bind the file webpack.config.js in the Angular config angular.json:

{
  // ...
  "projects": {
    // ...
    "architect": {
      "build": {
        // replace architect.build.builder with this value:
        "builder": "@angular-builders/custom-webpack:browser",
          // add the options:
          "options": {
          "aot": true,
            "customWebpackConfig": {
            "path": "./webpack.config.js" // the path to webpack.config.js
          },
          // ...
        },
        // ...
      },
      "serve": {
        // replace architect.serve.builder with this value:
        "builder": "@angular-builders/custom-webpack:dev-server",
          "options": {
          "browserTarget": "<app-name>:build"
        },
        // ...
      },
      // ...
    },
  },
},

In a component file, e.g. ./src/app/app.component.ts set the templateUrl with Pug file:

import { Component } from '@angular/core';

// the variable `description` will be passed into Pug template via resource query
const templateVars = '{"description": "Use Pug template with Angular."}';

@Component({
  selector: 'app-root',
  styleUrls: ['./app.component.css'],
  templateUrl: './app.component.pug?' + templateVars,
})
export class AppComponent {
  title = 'ng-app';
}

Create a Pug template, e.g. ./src/app/app.component.pug:

h1 Hello Pug!
p Description: #{description}

See the complete source of the example.


Using with Vue

Install:

npm i --save-dev @webdiscus/pug-loader

Change your vue.config.js according to the following minimal configuration:

const { defineConfig } = require('@vue/cli-service');

// additional pug-loader options, 
// e.g. to enable pug filters such as `:highlight`, `:markdown`, etc.
// see https://github.com/webdiscus/pug-loader#options
const pugLoaderOptions = {
};

module.exports = defineConfig({
  transpileDependencies: true,

  chainWebpack: (config) => {
    // clear all existing pug loaders
    const pugRule = config.module.rule('pug');
    pugRule.uses.clear();
    pugRule.oneOfs.clear();

    // exclude `pug-loader` from the witchery of the baggy `thread-loader` that is used in production mode
    const jsRule = config.module.rule('js');
    jsRule.exclude.add(/pug-loader/);
  },

  configureWebpack: {
    module: {
      rules: [
        {
          test: /\.pug$/,
          oneOf: [
            // allow <template lang="pug"> in Vue components
            {
              resourceQuery: /^\?vue/u,
              loader: '@webdiscus/pug-loader',
              options: {
                mode: 'html', // render Pug into pure HTML string
                ...pugLoaderOptions,
              },
            },
            // allow import of Pug in JavaScript
            {
              loader: '@webdiscus/pug-loader',
              options: {
                mode: 'compile', // compile Pug into template function
                ...pugLoaderOptions,
              },
            },
          ],
        },
      ],
    },
  },
});

For additional information see please the discussion: How to configure the plugin for both Vue and non-Vue usage?

Using Pug in Vue template

<template lang='pug'>
  h1 Hello Pug!
  p Use the '@webdiscus/pug-loader'
</template>

Note

You can use an indent for Pug code in Vue template.

Using Pug in JavaScript

App.vue

<template>
  <div v-html='demo'></div>
</template>

<script>
  // import Pug as template function
  import demoTmpl from './views/demo.pug';
  
  // define custom data used in Pug template
  const locals = { colors: ['red', 'green', 'blue'] };
  // pass custom data in Pug template
  const demoHtml = demoTmpl(locals);

  export default {
    name: 'App',
    data() {
      return {
        demo: demoHtml
      }
    }
  }
</script>

demo.pug

each color in colors
  div(style=`color: ${color}`) #{color}

Note: The colors is external variable passed from App.vue.


Recipes

Resolving the attribute srcset in img tag

img(srcset=`${require('./image1.jpeg')} 320w, ${require('./image2.jpeg')} 640w` src=require('./image.jpeg'))

output

<img srcset="/assets/image1.f78b30f4.jpeg 320w, /assets/image2.f78b30f4.jpeg 640w" src="/assets/image.f78b30f4.jpeg">

Using JavaScript in Pug

Use the require() for CommonJS files in Pug templates.
The JS module say-hello.js

module.exports = function(name) {
  return `Hello ${name}!`;
}

Use the module sayHello in Pug template.

- var sayHello = require('./say-hello')
h1 #{sayHello('pug')}

Testing

npm run test will run the unit and integration tests.
npm run test:coverage will run the tests with coverage.


Also See

License

ISC

pug-loader's People

Contributors

rrundzans avatar webdiscus avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

pug-loader's Issues

`include` doesn't use dynamic `resolve.alias` (from tsconfig-paths-webpack-plugin)

Description

Sorry for my bad English as my mother tongue is not English.
I use tsconfig-paths-webpack-plugin to add resolve.alias in webpack. Other loaders like sass-loader are totally fine with the alias, but pug compilation fails which leads me to believe that the problem is in this loader.

Info

OS Windows 11
Node v14.17.1
Package manager yarn
yarn version 1.22.17
@webdiscus/pugloader version 1.5.1

Temporary solution (until fixed)

While writing this issue I tried different temporary solutions which all had a problem in a way or other thus I suggest that you manually add the needed paths to resolve.alias in your webpack config.

Build log

D:\pug-loader-bug>webpack
assets by status 10.7 KiB [cached] 2 assets
runtime modules 663 bytes 3 modules
modules by path ../node_modules/ 8.07 KiB
  modules by path ../node_modules/style-loader/dist/runtime/*.js 5.75 KiB
    ../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js 2.44 KiB [built] [code generated]
    ../node_modules/style-loader/dist/runtime/styleDomAPI.js 1.38 KiB [built] [code generated]
    ../node_modules/style-loader/dist/runtime/insertBySelector.js 1010 bytes [built] [code generated]
    ../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js 300 bytes [built] [code generated]
    ../node_modules/style-loader/dist/runtime/insertStyleElement.js 286 bytes [built] [code generated]
    ../node_modules/style-loader/dist/runtime/styleTagTransform.js 382 bytes [built] [code generated]
  modules by path ../node_modules/css-loader/dist/runtime/*.js 2.33 KiB
    ../node_modules/css-loader/dist/runtime/noSourceMaps.js 64 bytes [built] [code generated]
    ../node_modules/css-loader/dist/runtime/api.js 2.26 KiB [built] [code generated]
modules by path ./views/*.scss 1.66 KiB
  ./views/index.scss 1.22 KiB [built] [code generated]
  ../node_modules/css-loader/dist/cjs.js!../node_modules/sass-loader/dist/cjs.js!./views/index.scss 447 bytes [built] [code generated]

WARNING in configuration
The 'mode' option has not been set, webpack will fallback to 'production' for this value.
Set 'mode' option to 'development' or 'production' to enable defaults for each environment.
You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/configuration/mode/

ERROR in   Error: Child compilation failed:
  Module build failed (from ../node_modules/@webdiscus/pug-loader/src/index.js):
  NonErrorEmittedError: (Emitted value instead of an instance of Error)
  [pug-loader] Pug compilation failed.
  Error: ENOENT: no such file or directory, open 'D:\pug-loader-bug\src\views\@component\nav.pug'
      at D:\pug-loader-bug\src\views\index.pug line 1
      at processResult (D:\pug-loader-bug\node_modules\webpack\lib\NormalModule.js:748:12)
      at D:\pug-loader-bug\node_modules\webpack\lib\NormalModule.js:853:5
      at D:\pug-loader-bug\node_modules\loader-runner\lib\LoaderRunner.js:399:11
      at D:\pug-loader-bug\node_modules\loader-runner\lib\LoaderRunner.js:251:18
      at context.callback (D:\pug-loader-bug\node_modules\loader-runner\lib\LoaderRunner.js:124:13)
      at D:\pug-loader-bug\node_modules\@webdiscus\pug-loader\src\index.js:175:21
      at Object.compilePugContent (D:\pug-loader-bug\node_modules\@webdiscus\pug-loader\src\index.js:150:5)
      at Object.module.exports (D:\pug-loader-bug\node_modules\@webdiscus\pug-loader\src\index.js:174:21)
  ModuleBuildError: Module build failed (from ../node_modules/@webdiscus/pug-loader/src/index.js):
  NonErrorEmittedError: (Emitted value instead of an instance of Error)
  [pug-loader] Pug compilation failed.
  Error: ENOENT: no such file or directory, open 'D:\pug-loader-bug\src\views\@component\nav.pug'
      at D:\pug-loader-bug\src\views\index.pug line 1
      at processResult (D:\pug-loader-bug\node_modules\webpack\lib\NormalModule.js:748:12)
      at D:\pug-loader-bug\node_modules\webpack\lib\NormalModule.js:853:5
      at D:\pug-loader-bug\node_modules\loader-runner\lib\LoaderRunner.js:399:11
      at D:\pug-loader-bug\node_modules\loader-runner\lib\LoaderRunner.js:251:18
      at context.callback (D:\pug-loader-bug\node_modules\loader-runner\lib\LoaderRunner.js:124:13)
      at D:\pug-loader-bug\node_modules\@webdiscus\pug-loader\src\index.js:175:21
      at Object.compilePugContent (D:\pug-loader-bug\node_modules\@webdiscus\pug-loader\src\index.js:150:5)
      at Object.module.exports (D:\pug-loader-bug\node_modules\@webdiscus\pug-loader\src\index.js:174:21)
      at processResult (D:\pug-loader-bug\node_modules\webpack\lib\NormalModule.js:751:19)
      at D:\pug-loader-bug\node_modules\webpack\lib\NormalModule.js:853:5
      at D:\pug-loader-bug\node_modules\loader-runner\lib\LoaderRunner.js:399:11
      at D:\pug-loader-bug\node_modules\loader-runner\lib\LoaderRunner.js:251:18
      at context.callback (D:\pug-loader-bug\node_modules\loader-runner\lib\LoaderRunner.js:124:13)
      at D:\pug-loader-bug\node_modules\@webdiscus\pug-loader\src\index.js:175:21
      at Object.compilePugContent (D:\pug-loader-bug\node_modules\@webdiscus\pug-loader\src\index.js:150:5)
      at Object.module.exports (D:\pug-loader-bug\node_modules\@webdiscus\pug-loader\src\index.js:174:21)
      at LOADER_EXECUTION (D:\pug-loader-bug\node_modules\loader-runner\lib\LoaderRunner.js:132:14)
      at runSyncOrAsync (D:\pug-loader-bug\node_modules\loader-runner\lib\LoaderRunner.js:133:4)


  - NormalModule.js:748 processResult
    [pug-loader-bug]/[webpack]/lib/NormalModule.js:748:12

  - NormalModule.js:853
    [pug-loader-bug]/[webpack]/lib/NormalModule.js:853:5

  - LoaderRunner.js:399
    [pug-loader-bug]/[loader-runner]/lib/LoaderRunner.js:399:11

  - LoaderRunner.js:251
    [pug-loader-bug]/[loader-runner]/lib/LoaderRunner.js:251:18

  - LoaderRunner.js:124 context.callback
    [pug-loader-bug]/[loader-runner]/lib/LoaderRunner.js:124:13

  - index.js:175
    [pug-loader-bug]/[@webdiscus]/pug-loader/src/index.js:175:21

  - index.js:150 Object.compilePugContent
    [pug-loader-bug]/[@webdiscus]/pug-loader/src/index.js:150:5

  - index.js:174 Object.module.exports
    [pug-loader-bug]/[@webdiscus]/pug-loader/src/index.js:174:21

  - ModuleBuildError: Module build failed (from ../node_modules/@webdiscus/pug-loader/src/index.js):

  - NonErrorEmittedError: (Emitted value instead of an instance of Error)

  - [pug-loader] Pug compilation failed.

  - Error: ENOENT: no such file or directory, open 'D:\pug-loader-bug\src\views\@component\nav.pug'


  - NormalModule.js:748 processResult
    [pug-loader-bug]/[webpack]/lib/NormalModule.js:748:12

  - NormalModule.js:853
    [pug-loader-bug]/[webpack]/lib/NormalModule.js:853:5

  - LoaderRunner.js:399
    [pug-loader-bug]/[loader-runner]/lib/LoaderRunner.js:399:11

  - LoaderRunner.js:251
    [pug-loader-bug]/[loader-runner]/lib/LoaderRunner.js:251:18

  - LoaderRunner.js:124 context.callback
    [pug-loader-bug]/[loader-runner]/lib/LoaderRunner.js:124:13

  - index.js:175
    [pug-loader-bug]/[@webdiscus]/pug-loader/src/index.js:175:21

  - index.js:150 Object.compilePugContent
    [pug-loader-bug]/[@webdiscus]/pug-loader/src/index.js:150:5

  - index.js:174 Object.module.exports
    [pug-loader-bug]/[@webdiscus]/pug-loader/src/index.js:174:21

  - NormalModule.js:751 processResult
    [pug-loader-bug]/[webpack]/lib/NormalModule.js:751:19

  - NormalModule.js:853
    [pug-loader-bug]/[webpack]/lib/NormalModule.js:853:5

  - LoaderRunner.js:399
    [pug-loader-bug]/[loader-runner]/lib/LoaderRunner.js:399:11

  - LoaderRunner.js:251
    [pug-loader-bug]/[loader-runner]/lib/LoaderRunner.js:251:18

  - LoaderRunner.js:124 context.callback
    [pug-loader-bug]/[loader-runner]/lib/LoaderRunner.js:124:13

  - index.js:175
    [pug-loader-bug]/[@webdiscus]/pug-loader/src/index.js:175:21

  - index.js:150 Object.compilePugContent
    [pug-loader-bug]/[@webdiscus]/pug-loader/src/index.js:150:5

  - index.js:174 Object.module.exports
    [pug-loader-bug]/[@webdiscus]/pug-loader/src/index.js:174:21

  - LoaderRunner.js:132 LOADER_EXECUTION
    [pug-loader-bug]/[loader-runner]/lib/LoaderRunner.js:132:14

  - LoaderRunner.js:133 runSyncOrAsync
    [pug-loader-bug]/[loader-runner]/lib/LoaderRunner.js:133:4

  - child-compiler.js:169
    [pug-loader-bug]/[html-webpack-plugin]/lib/child-compiler.js:169:18

  - Compiler.js:559
    [pug-loader-bug]/[webpack]/lib/Compiler.js:559:11

  - Compiler.js:1129
    [pug-loader-bug]/[webpack]/lib/Compiler.js:1129:17


  - Hook.js:18 Hook.CALL_ASYNC_DELEGATE [as _callAsync]
    [pug-loader-bug]/[tapable]/lib/Hook.js:18:14

  - Compiler.js:1125
    [pug-loader-bug]/[webpack]/lib/Compiler.js:1125:33

  - Compilation.js:2782 finalCallback
    [pug-loader-bug]/[webpack]/lib/Compilation.js:2782:11

  - Compilation.js:3087
    [pug-loader-bug]/[webpack]/lib/Compilation.js:3087:11


  - Hook.js:18 Hook.CALL_ASYNC_DELEGATE [as _callAsync]
    [pug-loader-bug]/[tapable]/lib/Hook.js:18:14



1 ERROR in child compilations (Use 'stats.children: true' resp. '--stats-children' for more details)
webpack 5.65.0 compiled with 2 errors and 1 warning in 1819 ms

Steps to reproduce

Clone the following directory structure and file contents:

Directory structure

package.json
tsconfig.json
yarn.lock
webpack.config.js
src/
|__views
|____index.pug
|____index.scss
|__components
|____nav.pug
|____nav.scss

File contents

package.json

{
  "devDependencies": {
    "@webdiscus/pug-loader": "^1.5.1",
    "css-loader": "^6.5.1",
    "html-webpack-plugin": "^5.5.0",
    "pug": "^3.0.2",
    "sass": "^1.46.0",
    "sass-loader": "^12.4.0",
    "style-loader": "^3.3.1",
    "tsconfig-paths-webpack-plugin": "^3.5.2",
    "webpack": "^5.65.0",
    "webpack-cli": "^4.9.1"
  }
}

tsconfig.json

{
  "compilerOptions": {
    "baseUrl": "src",
    "paths": {
      "@components/*": ["components/*"],
    }
  }
}

webpack.config.js

let TsConfigPathsPlugin = require("tsconfig-paths-webpack-plugin");
let HtmlWebpackPlugin = require("html-webpack-plugin");
let path = require("path");

let helpers = {
  root(...paths) {
    return path.join(__dirname, ...paths);
  },

  src(...paths) {
    return path.join(__dirname, "src/", ...paths);
  },

  dist(...paths) {
    return path.join(__dirname, "dist/", ...paths);
  }
};

module.exports = {
  context: helpers.src(),
  entry: "views/index.scss", // Explaination below...
  resolve: {
    plugins: [
      new TsConfigPathsPlugin({
        configFile: helpers.root("tsconfig.json")
      })
    ]
  },
  output: {
    path: helpers.dist()
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: "views/index.pug"
    })
  ],
  module: {
    rules: [
      /**
        * Why scss loader?
        * If scss-loader can use the aliases defined in tsconfig.json,
        * then the issue isn't from tsconfig-path-webpack-plugin.
        */
      {
        test: /\.(?:s[ca]|c)ss$/i,
        use: ["style-loader", "css-loader", "sass-loader"]
      },
      {
        test: /\.pug$/i,
        use: "@webdiscus/pug-loader"
      }
    ]
  }
};

views/index.pug

include @components/nav

views/index.scss

@use "@components/nav.scss";

components/nav.pug

p.nav Hello World

components/nav.scss

.nav {
  color: red;
}

Failed to build when webpack alias for asset is an array of paths instead of a single path

See my full repro here: https://github.com/Rush/webdiscus-repro and run npm run reproduce.

Or to reproduce by hand, setup the resolve alias as a list of paths, instead of a single path

resolve: {
  alias: {
    assets: [ assetPath1, assetPath2 ]

and then require the asset from pug

Module not found: Error: Can't resolve '/code/webdiscus-pug-node-example/assets,/code/webdiscus-pug-node-example/assets2/fonts/ibm-plex-sans-v7-latin-regular.woff2' in '/code/webdiscus-pug-node-example/server/views'

Requiring same asset from JS/TS works fine via:

require('assets/fonts/ibm-plex-sans-v7-latin-regular.woff2');

Loading wrong file on file changes

First time build seems to run fine, but on file changes a wrong file seems to be recompiled giving me cryptic angular errors

ERROR in src/app/components/manage-page.component.pug:1:4603 - error TS2339: Property 'editorLimit' does not exist on type 'ManagePageComponent'.

1 <div class="editor" #editorDiv [class.full]="hideUI" [class.has-bottom]="showSequence" preventTouch><editor-view [class.ha

and then the code shown actually concerns a different file altogether.

[Bug] Pug error in dependency requires restart of webpack

I am facing a non reproducible issue where:

  [pug-loader] Pug compilation failed.
  Error: Error parsing body of the with expression

Doesn't go even if I comment the whole file. It requires me to restart the webpack dev server instance. My build is CPU intensive. It takes about half a minute to have something on the screen and caching is not working properly. I have to wait half a minute every time a pug error occurs. And pug errors are extremely unreadable. Making it even harder to fix the pug error.

Windows only: Incorrectly resolved webpack aliases paths

package.json

"@webdiscus/pug-loader": "^1.5.0"

webpack.config.json

const PATHS = {
  src: path.join(__dirname, '/src'),
  dist: path.join(__dirname, '/dist')
};

...

{
  test: /\.pug$/i,
  loader: '@webdiscus/pug-loader',
  options: {
    basedir: PATHS.src,
  }
},

...

resolve: {
  alias: {
    '@images': path.join( PATHS.src, '/assets/images/' ),
  }
},

I've tried to build fresh dist-kit, but got a longread full of similar errors instead:

Module build failed: UnhandledSchemeError:
Reading from "D:MaxcoderjScriptBaymetalamp-fedsec-layoutssrcassetsimages/favicon/favicon-96x96.png"
is not handled by plugins (Unhandled scheme).
Webpack supports "data:" and "file:" URIs by default.
You may need an additional plugin to handle "d:" URIs.
at D:\Max\coder\jScriptBay\metalamp-fedsec-layouts\node_modules\webpack\lib\NormalModule.js:825:25

For some reasons, webpack aliases is nothing but a plain text without any special file path characters there.

So i tried to look around the sourcecode. Here is @webdiscus/pug-loader/src/utils.js:

/**
 * Replace founded alias in require argument.
 *
 * @param {string} value The value of extends/include/require().
 * @param {{}} aliases The `resolve.alias` of webpack config.
 * @param {function(string):string} regexp The function return a regex pattern string. The argument is alias name.
 * @return {string} The string with replaced alias.
 */
const resolveAlias = (value, aliases, regexp) => {
  const patternAliases = Object.keys(aliases).join('|');

  if (!patternAliases) return value;

  const [, alias] = new RegExp(regexp(patternAliases)).exec(value) || [];

  return alias ? value.replace(new RegExp(regexp(alias)), aliases[alias]).replace('//', '/') : value;
};

But everything looks well there, so i can't find a reason of that strange problem with webpack aliases.

Hope my debut issue request is a bit helpful. Thank you for an attention!

Compile error on bad JS Syntax is confusing

The error message that is output when attempting to compile pug templates with a javascript syntax error is confusing.

  • There is no hint that the problem is a javascript syntax error or what is wrong.
  • There is no hint where the error occurred (file and line)

Example:

  1. index.pug
h1 Index
include dependency
  1. dependency.pug
h1 Dependency

//- This line is invalid and generates an error
- const str = /.+/$

Error (with stats.children: true):

ERROR in ./src/index.pug (./node_modules/html-webpack-plugin/lib/loader.js!./src/index.pug)
  Module build failed (from ./node_modules/@webdiscus/pug-loader/src/index.js):
  NonErrorEmittedError: (Emitted value instead of an instance of Error)
  [pug-loader] Pug compilation failed.
  Error: Error parsing body of the with expression
      at processResult (/path/to/project/node_modules/webpack/lib/NormalModule.js:755:12)
      at /path/to/project/node_modules/webpack/lib/NormalModule.js:860:5
      at /path/to/project/node_modules/loader-runner/lib/LoaderRunner.js:400:11
      at /path/to/project/node_modules/loader-runner/lib/LoaderRunner.js:252:18
      at context.callback (/path/to/project/node_modules/loader-runner/lib/LoaderRunner.js:124:13)
      at /path/to/project/node_modules/@webdiscus/pug-loader/src/index.js:284:21
      at Object.compile (/path/to/project/node_modules/@webdiscus/pug-loader/src/index.js:244:5)
      at Object.module.exports (/path/to/project/node_modules/@webdiscus/pug-loader/src/index.js:283:11)

  Child HtmlWebpackCompiler compiled with 1 error

ERROR in   Error: Child compilation failed:
  Module build failed (from ./node_modules/@webdiscus/pug-loader/src/index.js):
  NonErrorEmittedError: (Emitted value instead of an instance of Error)
  [pug-loader] Pug compilation failed.
  Error: Error parsing body of the with expression
      at processResult (/path/to/project/node_modules/webpack/lib/NormalModule.js:755:12)
      at /path/to/project/node_modules/webpack/lib/NormalModule.js:860:5
      at /path/to/project/node_modules/loader-runner/lib/LoaderRunner.js:400:11
      at /path/to/project/node_modules/loader-runner/lib/LoaderRunner.js:252:18
      at context.callback (/path/to/project/node_modules/loader-runner/lib/LoaderRunner.js:124:13)
      at /path/to/project/node_modules/@webdiscus/pug-loader/src/index.js:284:21
      at Object.compile (/path/to/project/node_modules/@webdiscus/pug-loader/src/index.js:244:5)
      at Object.module.exports (/path/to/project/node_modules/@webdiscus/pug-loader/src/index.js:283:11)
  ModuleBuildError: Module build failed (from ./node_modules/@webdiscus/pug-loader/src/index.js):
  NonErrorEmittedError: (Emitted value instead of an instance of Error)
  [pug-loader] Pug compilation failed.
  Error: Error parsing body of the with expression
      at processResult (/path/to/project/node_modules/webpack/lib/NormalModule.js:755:12)
      at /path/to/project/node_modules/webpack/lib/NormalModule.js:860:5
      at /path/to/project/node_modules/loader-runner/lib/LoaderRunner.js:400:11
      at /path/to/project/node_modules/loader-runner/lib/LoaderRunner.js:252:18
      at context.callback (/path/to/project/node_modules/loader-runner/lib/LoaderRunner.js:124:13)
      at /path/to/project/node_modules/@webdiscus/pug-loader/src/index.js:284:21
      at Object.compile (/path/to/project/node_modules/@webdiscus/pug-loader/src/index.js:244:5)
      at Object.module.exports (/path/to/project/node_modules/@webdiscus/pug-loader/src/index.js:283:11)
      at processResult (/path/to/project/node_modules/webpack/lib/NormalModule.js:758:19)
      at /path/to/project/node_modules/webpack/lib/NormalModule.js:860:5
      at /path/to/project/node_modules/loader-runner/lib/LoaderRunner.js:400:11
      at /path/to/project/node_modules/loader-runner/lib/LoaderRunner.js:252:18
      at context.callback (/path/to/project/node_modules/loader-runner/lib/LoaderRunner.js:124:13)
      at /path/to/project/node_modules/@webdiscus/pug-loader/src/index.js:284:21
      at Object.compile (/path/to/project/node_modules/@webdiscus/pug-loader/src/index.js:244:5)
      at Object.module.exports (/path/to/project/node_modules/@webdiscus/pug-loader/src/index.js:283:11)
      at LOADER_EXECUTION (/path/to/project/node_modules/loader-runner/lib/LoaderRunner.js:132:14)
      at runSyncOrAsync (/path/to/project/node_modules/loader-runner/lib/LoaderRunner.js:133:4)

  - NormalModule.js:755 processResult
    [frontend-webpack]/[webpack]/lib/NormalModule.js:755:12

  - NormalModule.js:860
    [frontend-webpack]/[webpack]/lib/NormalModule.js:860:5

  - LoaderRunner.js:400
    [frontend-webpack]/[loader-runner]/lib/LoaderRunner.js:400:11

  - LoaderRunner.js:252
    [frontend-webpack]/[loader-runner]/lib/LoaderRunner.js:252:18

  - LoaderRunner.js:124 context.callback
    [frontend-webpack]/[loader-runner]/lib/LoaderRunner.js:124:13

  - index.js:284
    [frontend-webpack]/[@webdiscus]/pug-loader/src/index.js:284:21

  - index.js:244 Object.compile
    [frontend-webpack]/[@webdiscus]/pug-loader/src/index.js:244:5

  - index.js:283 Object.module.exports
    [frontend-webpack]/[@webdiscus]/pug-loader/src/index.js:283:11

  - ModuleBuildError: Module build failed (from ./node_modules/@webdiscus/pug-loader/src/index.js):

  - NonErrorEmittedError: (Emitted value instead of an instance of Error)

  - [pug-loader] Pug compilation failed.

  - Error: Error parsing body of the with expression

  - NormalModule.js:755 processResult
    [frontend-webpack]/[webpack]/lib/NormalModule.js:755:12

  - NormalModule.js:860
    [frontend-webpack]/[webpack]/lib/NormalModule.js:860:5

  - LoaderRunner.js:400
    [frontend-webpack]/[loader-runner]/lib/LoaderRunner.js:400:11
  
  - LoaderRunner.js:252
    [frontend-webpack]/[loader-runner]/lib/LoaderRunner.js:252:18

  - LoaderRunner.js:124 context.callback
    [frontend-webpack]/[loader-runner]/lib/LoaderRunner.js:124:13

  - index.js:284
    [frontend-webpack]/[@webdiscus]/pug-loader/src/index.js:284:21

  - index.js:244 Object.compile
    [frontend-webpack]/[@webdiscus]/pug-loader/src/index.js:244:5

  - index.js:283 Object.module.exports
    [frontend-webpack]/[@webdiscus]/pug-loader/src/index.js:283:11

  - NormalModule.js:758 processResult
    [frontend-webpack]/[webpack]/lib/NormalModule.js:758:19

  - NormalModule.js:860
    [frontend-webpack]/[webpack]/lib/NormalModule.js:860:5

  - LoaderRunner.js:400
    [frontend-webpack]/[loader-runner]/lib/LoaderRunner.js:400:11

  - LoaderRunner.js:252
    [frontend-webpack]/[loader-runner]/lib/LoaderRunner.js:252:18

  - LoaderRunner.js:124 context.callback
    [frontend-webpack]/[loader-runner]/lib/LoaderRunner.js:124:13

  - index.js:284
    [frontend-webpack]/[@webdiscus]/pug-loader/src/index.js:284:21

  - index.js:244 Object.compile
    [frontend-webpack]/[@webdiscus]/pug-loader/src/index.js:244:5

  - index.js:283 Object.module.exports
    [frontend-webpack]/[@webdiscus]/pug-loader/src/index.js:283:11

  - LoaderRunner.js:132 LOADER_EXECUTION
    [frontend-webpack]/[loader-runner]/lib/LoaderRunner.js:132:14

  - LoaderRunner.js:133 runSyncOrAsync
    [frontend-webpack]/[loader-runner]/lib/LoaderRunner.js:133:4

  - child-compiler.js:169
    [frontend-webpack]/[html-webpack-plugin]/lib/child-compiler.js:169:18

  - Compiler.js:551 finalCallback
    [frontend-webpack]/[webpack]/lib/Compiler.js:551:5

  - Compiler.js:577
    [frontend-webpack]/[webpack]/lib/Compiler.js:577:11

  - Compiler.js:1196
    [frontend-webpack]/[webpack]/lib/Compiler.js:1196:17


  - Hook.js:18 Hook.CALL_ASYNC_DELEGATE [as _callAsync]
    [frontend-webpack]/[tapable]/lib/Hook.js:18:14

  - Compiler.js:1192
    [frontend-webpack]/[webpack]/lib/Compiler.js:1192:33

  - Compilation.js:2787 finalCallback
    [frontend-webpack]/[webpack]/lib/Compilation.js:2787:11

  - Compilation.js:3092
    [frontend-webpack]/[webpack]/lib/Compilation.js:3092:11




webpack compiled with 2 errors

Missing peer dependency pug-walk

The loader uses the pug-walk module [1] but there is no corresponding entry in the package.json.

pug-walk should be added to the peerDependencies.

Also I noticed webpack-merge being a dependency. Probably this should just be a dev dependency?

[1]

const walk = require('pug-walk');

Will this support pug3?

I can see you guys released last month but I also see that did not include Pug 3. Will this project eventually support Pug 3 as well?

img srcset attribute

Hi, is it possible to use such a feature?

img(
  src=require('@/assets/images/img.png'),
  srcset=`${require('@/assets/images/[email protected]')} 2x, ${require('@/assets/images/[email protected]')} 3x`,
  alt='My image'
)

This code currently gives the following error:

Error: Error parsing body of the with expression

Stack:

  • "webpack": "^5.66.0";
  • "pug": "^3.0.2";
  • "@webdiscus/pug-loader": "^1.6.0";
  • "html-webpack-plugin": "^5.5.0"

Cannot read properties of undefined (reading 'sync') in @webdiscus\pug-loader\src\Resolver.js

Hi,

I am facing following issue:

ERROR in ./src/views/pages/index.pug
Module build failed (from ./node_modules/@webdiscus/pug-loader/src/index.js):
TypeError: Cannot read properties of undefined (reading 'sync')
    at Resolver.init (C:\projects\code\pug-loader-issue\node_modules\@webdiscus\pug-loader\src\Resolver.js:33:47)
    at Object.compile (C:\projects\code\pug-loader-issue\node_modules\@webdiscus\pug-loader\src\index.js:269:14)
    at Object.module.exports (C:\projects\code\pug-loader-issue\node_modules\@webdiscus\pug-loader\src\index.js:334:11)

Full output

PS C:\projects\code\pug-loader-issue> npm run start

> [email protected] start
> cross-env NODE_ENV=development webpack serve --config config/webpack.dev.js

<i> [webpack-dev-server] Project is running at:
<i> [webpack-dev-server] Loopback: http://localhost:8082/
<i> [webpack-dev-server] On Your Network (IPv4): 
<i> [webpack-dev-server] On Your Network (IPv6): 
<i> [webpack-dev-server] Content not from webpack is served from 'C:\projects\code\pug-loader-issue\public' directory
PublicPath: auto
asset index.html 219 KiB [emitted] (name: index)
Entrypoint index 219 KiB = index.html
chunk (runtime: index) index.html (index) 27.3 KiB (runtime) 160 KiB (javascript) [entry] [rendered]
runtime modules 27.3 KiB 12 modules
modules by path ./node_modules/ 160 KiB
  modules by path ./node_modules/webpack-dev-server/client/ 55.8 KiB 12 modules
  modules by path ./node_modules/webpack/hot/*.js 4.3 KiB
    ./node_modules/webpack/hot/dev-server.js 1.59 KiB [built] [code generated]
    ./node_modules/webpack/hot/log.js 1.34 KiB [built] [code generated]
    + 2 modules
  modules by path ./node_modules/html-entities/lib/*.js 81.3 KiB
    ./node_modules/html-entities/lib/index.js 7.74 KiB [built] [code generated]
    ./node_modules/html-entities/lib/named-references.js 72.7 KiB [built] [code generated]
    + 2 modules
  ./node_modules/ansi-html-community/index.js 4.16 KiB [built] [code generated]
  ./node_modules/events/events.js 14.5 KiB [built] [code generated]
./src/views/pages/index.pug 39 bytes [built] [code generated] [1 error]


LOG from webpack.Compilation
    23 modules hashed, 0 from cache (1 variants per module in average)
    100% code generated (23 generated, 0 from cache)
    100% code generated (12 generated, 0 from cache)
+ 25 hidden lines

LOG from webpack.ResolverCachePlugin
    94% really resolved (29 real resolves with 0 cached but invalid, 2 cached valid, 0 concurrent)

LOG from webpack.FlagDependencyExportsPlugin
    61% of exports of modules have been determined (9 no declared exports, 14 not cached, 0 flagged uncacheable, 0 from cache, 0 from mem cache, 0 additional calculations due to dependencies)
+ 3 hidden lines

LOG from webpack.buildChunkGraph
    48 queue items processed (23 blocks)
    0 chunk groups connected
    0 chunk groups processed for merging (0 module sets, 0 forked, 0 + 0 modules forked, 0 + 0 modules merged into fork, 0 resulting modules)
    0 chunk group info updated (0 already connected chunk groups reconnected)
+ 5 hidden lines

LOG from webpack.FileSystemInfo
    51 new snapshots created
    0% root snapshot uncached (0 / 2)
    0% children snapshot uncached (0 / 0)
    0 entries tested
    File info in cache: 14 timestamps 0 hashes 0 timestamp hash combinations
    File timestamp snapshot optimization: 90% (140/156) entries shared via 2 shared snapshots (26 times referenced)
    Directory info in cache: 0 timestamps 0 hashes 0 timestamp hash combinations
    Missing items snapshot optimization: 0% (0/3) entries shared via 0 shared snapshots (0 times referenced)
    Managed items info in cache: 20 items
    Managed items snapshot optimization: 21% (16/77) entries shared via 2 shared snapshots (2 times referenced)
    Managed files snapshot optimization: 44% (75/172) entries shared via 3 shared snapshots (22 times referenced)
    Managed missing snapshot optimization: 16% (16/98) entries shared via 2 shared snapshots (3 times referenced)

ERROR in ./src/views/pages/index.pug
Module build failed (from ./node_modules/@webdiscus/pug-loader/src/index.js):
TypeError: Cannot read properties of undefined (reading 'sync')
    at Resolver.init (C:\projects\code\pug-loader-issue\node_modules\@webdiscus\pug-loader\src\Resolver.js:33:47)
    at Object.compile (C:\projects\code\pug-loader-issue\node_modules\@webdiscus\pug-loader\src\index.js:269:14)
    at Object.module.exports (C:\projects\code\pug-loader-issue\node_modules\@webdiscus\pug-loader\src\index.js:334:11)
ModuleBuildError: Module build failed (from ./node_modules/@webdiscus/pug-loader/src/index.js):
TypeError: Cannot read properties of undefined (reading 'sync')
    at Resolver.init (C:\projects\code\pug-loader-issue\node_modules\@webdiscus\pug-loader\src\Resolver.js:33:47)
    at Object.compile (C:\projects\code\pug-loader-issue\node_modules\@webdiscus\pug-loader\src\index.js:269:14)
    at Object.module.exports (C:\projects\code\pug-loader-issue\node_modules\@webdiscus\pug-loader\src\index.js:334:11)
    at processResult (C:\projects\code\pug-loader-issue\node_modules\webpack\lib\NormalModule.js:758:19)
    at C:\projects\code\pug-loader-issue\node_modules\webpack\lib\NormalModule.js:860:5
    at C:\projects\code\pug-loader-issue\node_modules\loader-runner\lib\LoaderRunner.js:400:11
    at C:\projects\code\pug-loader-issue\node_modules\loader-runner\lib\LoaderRunner.js:252:18
    at runSyncOrAsync (C:\projects\code\pug-loader-issue\node_modules\loader-runner\lib\LoaderRunner.js:156:3)
    at iterateNormalLoaders (C:\projects\code\pug-loader-issue\node_modules\loader-runner\lib\LoaderRunner.js:251:2)
    at C:\projects\code\pug-loader-issue\node_modules\loader-runner\lib\LoaderRunner.js:224:4
    at C:\projects\code\pug-loader-issue\node_modules\webpack\lib\NormalModule.js:834:15
    at Array.eval (eval at create (C:\projects\code\pug-loader-issue\node_modules\webpack\node_modules\tapable\lib\HookCodeFactory.js:33:10), <anonymous>:12:1)
    at runCallbacks (C:\projects\code\pug-loader-issue\node_modules\webpack\node_modules\enhanced-resolve\lib\CachedInputFileSystem.js:27:15)

2022-09-10 23:03:20: webpack 5.74.0 compiled with 1 error in 4126 ms (47ef832b0d2f0acfd69a)

webpack.dev.config.js

/* eslint-disable */
const {
  CleanWebpackPlugin,
} = require('clean-webpack-plugin')
const FaviconsWebpackPlugin = require('favicons-webpack-plugin')
const PugPlugin = require('pug-plugin')

const paths = require('./paths')


const loaders = require('../webpack/loaders');
/* eslint-enable */

module.exports = {

  mode: 'development',
  devtool: 'source-map',

  // Where webpack outputs the assets and bundles
  output: {
    path: paths.dist,
    publicPath: 'auto',

    // output filename of scripts
    filename: 'assets/js/[name].[contenthash:8].js',
    chunkFilename: 'assets/js/[id].[contenthash:8].js',
    clean: true,
  },

  resolve: {
    // aliases used in sources
    alias: {
      Root: paths.root,
      Src: paths.src.root,
      Views: paths.src.views,
      Images: paths.src.images,
      Fonts: paths.src.fonts,
      Styles: paths.src.styles,
      Scripts: paths.src.scripts,
    },
    preferRelative: true,

    // resolve omitted extensions
    extensions: ['.js'],
  },

  // Where webpack looks to start building the bundle
  entry: {
    index: './src/views/pages/index.pug',
    // 404: './src/views/pages/404.pug',
  },

  // Determine how modules within the project are treated
  module: {
    rules: [
      // pug
      loaders.pugLoader(),

      // styles
      loaders.sassLoader(),

      // images
      loaders.imageLoader(),

      // inline images by size (to force inline use the `?inline` query)
      // ...loaders.inlineImageLoader(2 * 1024),

      // fonts
      loaders.fontLoader(),

      // generates filename including last directory name
      // to group fonts by name

      // eslint-disable-next-line max-len
      // (pathData) => `assets/fonts/${path.basename(path.dirname(pathData.filename))}/[name][ext][query]`
    ],
  },

  // Customize the webpack build process
  plugins: [

    // Removes/cleans build folders and unused assets when rebuilding
    new CleanWebpackPlugin(),

    new PugPlugin({
      verbose: true, // output information about the process to console
      pretty: true, // output formatted HTML
      // extract CSS from style source files specified directly in Pug
      extractCss: {
        // output filename of styles
        filename: 'assets/css/[name].[contenthash:8].css',
      },
    }),
  ],

  performance: {
    hints: 'warning',
    // in development mode the size of entrypoint
    // and assets is bigger than in production
    maxEntrypointSize: 15000 * 1024,
    maxAssetSize: 4000 * 1024,
  },

  stats: {
    colors: true,
    // see https://webpack.js.org/configuration/stats/#stats-presets
    // preset: 'minimal',
    // enable @debug output

    env: true,
    // include value of --env in the output
    outputPath: true,
    // include absolute output path in the output
    publicPath: true,
    // include public path in the output

    assets: true,
    // show list of assets in output

    entrypoints: true,
    // show entrypoints list
    chunkGroups: true,
    // show named chunk group list

    chunks: true,
    // show list of chunks in output

    modules: true,
    // show list of modules in output

    children: true,
    // show stats for child compilations

    logging: true,
    // show logging in output
    loggingDebug: ['sass-loader'],
    // show debug type logging for some loggers
    loggingTrace: true,
    // show stack traces for warnings and errors in logging output

    warnings: true,
    // show warnings

    errors: true,
    // show errors
    errorDetails: true,
    // show details for errors
    errorStack: true,
    // show internal stack trace for errors
    moduleTrace: true,
    // show module trace for errors
    // (why was causing module referenced)

    builtAt: true,
    // show timestamp in summary
    errorsCount: true,
    // show errors count in summary
    warningsCount: true,
    // show warnings count in summary
    timings: true,
    // show build timing in summary
    version: true,
    // show webpack version in summary
    hash: true,
    // show build hash in summary
  },
}

Steps to reproduce

  1. clone https://github.com/itsBen/pug-loader-issue
  2. run npm run start

System

OS Name Microsoft Windows 10 Pro
Version 10.0.19044 Build 19044

Support Webpack defined modules

Modules defined in the Webpack configuration don't get resolved properly.

Folder structure:

src
  โ”œโ”€ img
  |   โ”œโ”€ image.jpg
  โ”œโ”€ css
  โ”œโ”€ js
  โ”œโ”€ pug

Webpack config:

resolve: {
  modules: [
    'src',
    'node_modules',
  ],
},

Pug:

img(src=require('img/image.jpg') alt)

Error:

ERROR in   Error: Child compilation failed:
  Module build failed (from ./node_modules/@webdiscus/pug-loader/src/index.js):
  NonErrorEmittedError: (Emitted value instead of an instance of Error)
  [pug-loader] Pug compilation failed.
  PugLoaderException:
  [pug-loader] the file 'img/image.jpg' can't be resolved in the pug template:
  /path/to/project/src/pug/index.pug
  Error: Can't resolve 'img/image.jpg' in '/path/to/project/src/pug/'
      at processResult (/path/to/project/node_modules/webpack/lib/NormalModule.js:755:12)
      at /path/to/project/node_modules/webpack/lib/NormalModule.js:860:5
      at /path/to/project/node_modules/loader-runner/lib/LoaderRunner.js:400:11
      at /path/to/project/node_modules/loader-runner/lib/LoaderRunner.js:252:18
      at context.callback (/path/to/project/node_modules/loader-runner/lib/LoaderRunner.js:124:13)
      at /path/to/project/node_modules/@webdiscus/pug-loader/src/index.js:284:21
      at Object.compile (/path/to/project/node_modules/@webdiscus/pug-loader/src/index.js:244:5)
      at Object.module.exports (/path/to/project/node_modules/@webdiscus/pug-loader/src/index.js:283:11)
  ModuleBuildError: Module build failed (from ./node_modules/@webdiscus/pug-loader/src/index.js):
  NonErrorEmittedError: (Emitted value instead of an instance of Error)
  [pug-loader] Pug compilation failed.
  PugLoaderException:
  [pug-loader] the file 'img/image.jpg' can't be resolved in the pug template:
  /path/to/project/src/pug/index.pug
  Error: Can't resolve 'img/image.jpg' in '/path/to/project/src/pug/'
      at processResult (/path/to/project/node_modules/webpack/lib/NormalModule.js:755:12)
      at /path/to/project/node_modules/webpack/lib/NormalModule.js:860:5
      at /path/to/project/node_modules/loader-runner/lib/LoaderRunner.js:400:11
      at /path/to/project/node_modules/loader-runner/lib/LoaderRunner.js:252:18
      at context.callback (/path/to/project/node_modules/loader-runner/lib/LoaderRunner.js:124:13)
      at /path/to/project/node_modules/@webdiscus/pug-loader/src/index.js:284:21
      at Object.compile (/path/to/project/node_modules/@webdiscus/pug-loader/src/index.js:244:5)
      at Object.module.exports (/path/to/project/node_modules/@webdiscus/pug-loader/src/index.js:283:11)
      at processResult (/path/to/project/node_modules/webpack/lib/NormalModule.js:758:19)
      at /path/to/project/node_modules/webpack/lib/NormalModule.js:860:5
      at /path/to/project/node_modules/loader-runner/lib/LoaderRunner.js:400:11
      at /path/to/project/node_modules/loader-runner/lib/LoaderRunner.js:252:18
      at context.callback (/path/to/project/node_modules/loader-runner/lib/LoaderRunner.js:124:13)
      at /path/to/project/node_modules/@webdiscus/pug-loader/src/index.js:284:21
      at Object.compile (/path/to/project/node_modules/@webdiscus/pug-loader/src/index.js:244:5)
      at Object.module.exports (/path/to/project/node_modules/@webdiscus/pug-loader/src/index.js:283:11)
      at LOADER_EXECUTION (/path/to/project/node_modules/loader-runner/lib/LoaderRunner.js:132:14)
      at runSyncOrAsync (/path/to/project/node_modules/loader-runner/lib/LoaderRunner.js:133:4)

  - NormalModule.js:755 processResult
    [project-name]/[webpack]/lib/NormalModule.js:755:12

  - NormalModule.js:860
    [project-name]/[webpack]/lib/NormalModule.js:860:5

  - LoaderRunner.js:400
    [project-name]/[loader-runner]/lib/LoaderRunner.js:400:11

  - LoaderRunner.js:252
    [project-name]/[loader-runner]/lib/LoaderRunner.js:252:18

  - LoaderRunner.js:124 context.callback
    [project-name]/[loader-runner]/lib/LoaderRunner.js:124:13

  - index.js:284
    [project-name]/[@webdiscus]/pug-loader/src/index.js:284:21

  - index.js:244 Object.compile
    [project-name]/[@webdiscus]/pug-loader/src/index.js:244:5

  - index.js:283 Object.module.exports
    [project-name]/[@webdiscus]/pug-loader/src/index.js:283:11

  - ModuleBuildError: Module build failed (from ./node_modules/@webdiscus/pug-loader/src/index.js):

  - NonErrorEmittedError: (Emitted value instead of an instance of Error)

  - [pug-loader] Pug compilation failed.

  - PugLoaderException:

  - [pug-loader] the file 'img/image.jpg' can't be resolved in the pug template:

  - /path/to/project/src/pug/index.pug

  - Error: Can't resolve 'img/image.jpg' in '/path/to/project/src/pug/'

  - NormalModule.js:755 processResult
    [project-name]/[webpack]/lib/NormalModule.js:755:12

  - NormalModule.js:860
    [project-name]/[webpack]/lib/NormalModule.js:860:5

  - LoaderRunner.js:400
    [project-name]/[loader-runner]/lib/LoaderRunner.js:400:11

  - LoaderRunner.js:252
    [project-name]/[loader-runner]/lib/LoaderRunner.js:252:18

  - LoaderRunner.js:124 context.callback
    [project-name]/[loader-runner]/lib/LoaderRunner.js:124:13

  - index.js:284
    [project-name]/[@webdiscus]/pug-loader/src/index.js:284:21

  - index.js:244 Object.compile
    [project-name]/[@webdiscus]/pug-loader/src/index.js:244:5

  - index.js:283 Object.module.exports
    [project-name]/[@webdiscus]/pug-loader/src/index.js:283:11

  - NormalModule.js:758 processResult
    [project-name]/[webpack]/lib/NormalModule.js:758:19

  - NormalModule.js:860
    [project-name]/[webpack]/lib/NormalModule.js:860:5

  - LoaderRunner.js:400
    [project-name]/[loader-runner]/lib/LoaderRunner.js:400:11
  
  - LoaderRunner.js:252
    [project-name]/[loader-runner]/lib/LoaderRunner.js:252:18

  - LoaderRunner.js:124 context.callback
    [project-name]/[loader-runner]/lib/LoaderRunner.js:124:13

  - index.js:284
    [project-name]/[@webdiscus]/pug-loader/src/index.js:284:21

  - index.js:244 Object.compile
    [project-name]/[@webdiscus]/pug-loader/src/index.js:244:5

  - index.js:283 Object.module.exports
    [project-name]/[@webdiscus]/pug-loader/src/index.js:283:11

  - LoaderRunner.js:132 LOADER_EXECUTION
    [project-name]/[loader-runner]/lib/LoaderRunner.js:132:14

  - LoaderRunner.js:133 runSyncOrAsync
    [project-name]/[loader-runner]/lib/LoaderRunner.js:133:4

  - child-compiler.js:169
    [project-name]/[html-webpack-plugin]/lib/child-compiler.js:169:18

  - Compiler.js:551 finalCallback
    [project-name]/[webpack]/lib/Compiler.js:551:5

  - Compiler.js:577
    [project-name]/[webpack]/lib/Compiler.js:577:11

  - Compiler.js:1196
    [project-name]/[webpack]/lib/Compiler.js:1196:17


  - Hook.js:18 Hook.CALL_ASYNC_DELEGATE [as _callAsync]
    [project-name]/[tapable]/lib/Hook.js:18:14

  - Compiler.js:1192
    [project-name]/[webpack]/lib/Compiler.js:1192:33

  - Compilation.js:2787 finalCallback
    [project-name]/[webpack]/lib/Compilation.js:2787:11

  - Compilation.js:3092
    [project-name]/[webpack]/lib/Compilation.js:3092:11




webpack compiled with 1 error

in simple-pug-loader and scss (sass-loader / css-loader) this does work correctly

related: #15

Improve the error message to find where the error occurred

I can't even figure out anything, which pug file has the error, where the error is, who caused it, or what caused it. I can't even physically find it or calculate it, because the specific source is almost never given. So I am misled and extremely confused. Because of this, I am forced to just frantically and in a panic to look for any possible source of this problem.

And it tends to arise because of this kind of design...

something
  if block
    block
  else
    #{""}

And it seems like the design may not have a visual effect at all.

something
  // v1 
  block()

  // may be, may not work
  if block
    block()
  else
    #{""}

And I have previously, in one form or another, had similar problems.

ERROR in   Error: Child compilation failed:
  Module build failed (from ./node_modules/@webdiscus/pug-loader/src/index.js):
  Error: PugLoaderException:
  [pug-loader] Failed to execute template function.
  Template file: C:\Frontend\IDX-L1-U\src\index.pug

  Original Error:
  TypeError: Cannot read properties of undefined (reading 'call')
      at Object.compile (C:\Frontend\IDX-L1-U\webpack\node_modules\@webdiscus\pug-loader\src\index.js:283:26)
      at module.exports (C:\Frontend\IDX-L1-U\webpack\node_modules\@webdiscus\pug-loader\src\index.js:297:11)
  ModuleBuildError: Module build failed (from ./node_modules/@webdiscus/pug-loader/src/index.js):
  Error: PugLoaderException:
  [pug-loader] Failed to execute template function.
  Template file: C:\Frontend\IDX-L1-U\src\index.pug

  Original Error:
  TypeError: Cannot read properties of undefined (reading 'call')
      at Object.compile (C:\Frontend\IDX-L1-U\webpack\node_modules\@webdiscus\pug-loader\src\index.js:283:26)
      at module.exports (C:\Frontend\IDX-L1-U\webpack\node_modules\@webdiscus\pug-loader\src\index.js:297:11)
      at processResult (C:\Frontend\IDX-L1-U\webpack\node_modules\webpack\lib\NormalModule.js:841:19)
      at C:\Frontend\IDX-L1-U\webpack\node_modules\webpack\lib\NormalModule.js:966:5
      at C:\Frontend\IDX-L1-U\webpack\node_modules\loader-runner\lib\LoaderRunner.js:400:11
      at C:\Frontend\IDX-L1-U\webpack\node_modules\loader-runner\lib\LoaderRunner.js:252:18
      at context.callback (C:\Frontend\IDX-L1-U\webpack\node_modules\loader-runner\lib\LoaderRunner.js:124:13)
      at C:\Frontend\IDX-L1-U\webpack\node_modules\@webdiscus\pug-loader\src\index.js:300:46
      at Object.compile (C:\Frontend\IDX-L1-U\webpack\node_modules\@webdiscus\pug-loader\src\index.js:284:5)
      at module.exports (C:\Frontend\IDX-L1-U\webpack\node_modules\@webdiscus\pug-loader\src\index.js:297:11)
      at LOADER_EXECUTION (C:\Frontend\IDX-L1-U\webpack\node_modules\loader-runner\lib\LoaderRunner.js:132:14)
      at runSyncOrAsync (C:\Frontend\IDX-L1-U\webpack\node_modules\loader-runner\lib\LoaderRunner.js:133:4)
      at iterateNormalLoaders (C:\Frontend\IDX-L1-U\webpack\node_modules\loader-runner\lib\LoaderRunner.js:251:2)
      at C:\Frontend\IDX-L1-U\webpack\node_modules\loader-runner\lib\LoaderRunner.js:224:4
      at C:\Frontend\IDX-L1-U\webpack\node_modules\webpack\lib\NormalModule.js:920:15
      at Array.eval (eval at create (C:\Frontend\IDX-L1-U\webpack\node_modules\tapable\lib\HookCodeFactory.js:33:10), <a  nonymous>:12:1)
      at runCallbacks (C:\Frontend\IDX-L1-U\webpack\node_modules\enhanced-resolve\lib\CachedInputFileSystem.js:45:15)
      at C:\Frontend\IDX-L1-U\webpack\node_modules\enhanced-resolve\lib\CachedInputFileSystem.js:279:5
      at C:\Frontend\IDX-L1-U\webpack\node_modules\graceful-fs\graceful-fs.js:123:16
      at FSReqCallback.readFileAfterClose [as oncomplete] (node:internal/fs/read/context:68:3)

  - index.js:283 Object.compile
    [webpack]/[@webdiscus]/pug-loader/src/index.js:283:26

  - index.js:297 module.exports
    [webpack]/[@webdiscus]/pug-loader/src/index.js:297:11

  - ModuleBuildError: Module build failed (from ./node_modules/@webdiscus/pug-loader/src/index.js):

  - Error: PugLoaderException:

  - [pug-loader] Failed to execute template function.

  - Template file: C:\Frontend\IDX-L1-U\src\index.pug

  - Original Error:

  - TypeError: Cannot read properties of undefined (reading 'call')

  - index.js:283 Object.compile
    [webpack]/[@webdiscus]/pug-loader/src/index.js:283:26

  - index.js:297 module.exports
    [webpack]/[@webdiscus]/pug-loader/src/index.js:297:11

  - NormalModule.js:841 processResult
    [webpack]/[webpack]/lib/NormalModule.js:841:19

  - NormalModule.js:966
    [webpack]/[webpack]/lib/NormalModule.js:966:5

  - LoaderRunner.js:400
    [webpack]/[loader-runner]/lib/LoaderRunner.js:400:11

  - LoaderRunner.js:252
    [webpack]/[loader-runner]/lib/LoaderRunner.js:252:18

  - LoaderRunner.js:124 context.callback
    [webpack]/[loader-runner]/lib/LoaderRunner.js:124:13

  - index.js:300
    [webpack]/[@webdiscus]/pug-loader/src/index.js:300:46

  - index.js:284 Object.compile
    [webpack]/[@webdiscus]/pug-loader/src/index.js:284:5

  - index.js:297 module.exports
    [webpack]/[@webdiscus]/pug-loader/src/index.js:297:11

  - LoaderRunner.js:132 LOADER_EXECUTION
    [webpack]/[loader-runner]/lib/LoaderRunner.js:132:14

  - LoaderRunner.js:133 runSyncOrAsync
    [webpack]/[loader-runner]/lib/LoaderRunner.js:133:4

  - LoaderRunner.js:251 iterateNormalLoaders
    [webpack]/[loader-runner]/lib/LoaderRunner.js:251:2

  - LoaderRunner.js:224
    [webpack]/[loader-runner]/lib/LoaderRunner.js:224:4

  - NormalModule.js:920
    [webpack]/[webpack]/lib/NormalModule.js:920:15


  - CachedInputFileSystem.js:45 runCallbacks
    [webpack]/[enhanced-resolve]/lib/CachedInputFileSystem.js:45:15

  - CachedInputFileSystem.js:279
    [webpack]/[enhanced-resolve]/lib/CachedInputFileSystem.js:279:5

  - graceful-fs.js:123
    [webpack]/[graceful-fs]/graceful-fs.js:123:16

  - context:68 FSReqCallback.readFileAfterClose [as oncomplete]
    node:internal/fs/read/context:68:3

  - child-compiler.js:174
    [webpack]/[html-webpack-plugin]/lib/child-compiler.js:174:18

  - Compiler.js:605 finalCallback
    [webpack]/[webpack]/lib/Compiler.js:605:5

  - Compiler.js:640
    [webpack]/[webpack]/lib/Compiler.js:640:11

  - Compiler.js:1329
    [webpack]/[webpack]/lib/Compiler.js:1329:17


  - Hook.js:18 Hook.CALL_ASYNC_DELEGATE [as _callAsync]
    [webpack]/[tapable]/lib/Hook.js:18:14

  - Compiler.js:1325
    [webpack]/[webpack]/lib/Compiler.js:1325:33

  - Compilation.js:2900 finalCallback
    [webpack]/[webpack]/lib/Compilation.js:2900:11

  - Compilation.js:3209
    [webpack]/[webpack]/lib/Compilation.js:3209:11


  - Hook.js:18 Hook.CALL_ASYNC_DELEGATE [as _callAsync]
    [webpack]/[tapable]/lib/Hook.js:18:14

  - Compilation.js:3202
    [webpack]/[webpack]/lib/Compilation.js:3202:38


  - Compilation.js:529
    [webpack]/[webpack]/lib/Compilation.js:529:10

  - SourceMapDevToolPlugin.js:588
    [webpack]/[webpack]/lib/SourceMapDevToolPlugin.js:588:10

  - async.js:2830
    [webpack]/[neo-async]/async.js:2830:7

  - async.js:2857 Object.each
    [webpack]/[neo-async]/async.js:2857:9

  - SourceMapDevToolPlugin.js:412
    [webpack]/[webpack]/lib/SourceMapDevToolPlugin.js:412:17

  - async.js:2830
    [webpack]/[neo-async]/async.js:2830:7

  - async.js:2857 Object.each
    [webpack]/[neo-async]/async.js:2857:9

  - SourceMapDevToolPlugin.js:231
    [webpack]/[webpack]/lib/SourceMapDevToolPlugin.js:231:15

  - Compilation.js:517 fn
    [webpack]/[webpack]/lib/Compilation.js:517:9




webpack 5.91.0 compiled with 1 error in 127 ms

Main and general issue: (in some cases) misinformation and misrepresentation.

Resolved?
And yet my mistake has been identified, it has to do with the wrong mixin name. But it still does not cancel the fact that you can easily get lost and confused about what happened.

htmlWebpackPlugin.options not available in pug template

Coming from the original pug loader, using the latest version of this library I get the following error during compilation:

  - Error: Cannot find module 'pug-walk'
  
  - Require stack:
  
  - - /home/perry/git/buttercup-browser-extension/node_modules/@webdiscus/pug-loader/src/index.js
  
  - - /home/perry/git/buttercup-browser-extension/node_modules/loader-runner/lib/loadLoader.js
  
  - - /home/perry/git/buttercup-browser-extension/node_modules/loader-runner/lib/LoaderRunner.js
  
  - - /home/perry/git/buttercup-browser-extension/node_modules/webpack/lib/NormalModuleFactory.js
  
  - - /home/perry/git/buttercup-browser-extension/node_modules/webpack/lib/Compiler.js
  
  - - /home/perry/git/buttercup-browser-extension/node_modules/webpack/lib/webpack.js
  
  - - /home/perry/git/buttercup-browser-extension/node_modules/webpack/lib/index.js
  
  - - /home/perry/git/buttercup-browser-extension/node_modules/webpack-cli/lib/webpack-cli.js
  
  - - /home/perry/git/buttercup-browser-extension/node_modules/webpack-cli/lib/bootstrap.js
  
  - - /home/perry/git/buttercup-browser-extension/node_modules/webpack-cli/bin/cli.js
  
  - - /home/perry/git/buttercup-browser-extension/node_modules/webpack/bin/webpack.js
  
  - loader:933 Function.Module._resolveFilename
    node:internal/modules/cjs/loader:933:15
  
  - loader:778 Function.Module._load
    node:internal/modules/cjs/loader:778:27
  
  - loader:1005 Module.require
    node:internal/modules/cjs/loader:1005:19
  
  - helpers:102 require
    node:internal/modules/cjs/helpers:102:18
  
  - index.js:6 Object.<anonymous>
    [buttercup-browser-extension]/[@webdiscus]/pug-loader/src/index.js:6:14
  
  - loader:1101 Module._compile
    node:internal/modules/cjs/loader:1101:14
  
  - loader:1153 Object.Module._extensions..js
    node:internal/modules/cjs/loader:1153:10
  
  - loader:981 Module.load
    node:internal/modules/cjs/loader:981:32
  
  - loader:822 Function.Module._load
    node:internal/modules/cjs/loader:822:12
  
  - loader:1005 Module.require
    node:internal/modules/cjs/loader:1005:19
  
  - helpers:102 require
    node:internal/modules/cjs/helpers:102:18
  
  - loadLoader.js:19 loadLoader
    [buttercup-browser-extension]/[loader-runner]/lib/loadLoader.js:19:17
  
  - LoaderRunner.js:182 iteratePitchingLoaders
    [buttercup-browser-extension]/[loader-runner]/lib/LoaderRunner.js:182:2
  
  - LoaderRunner.js:178 iteratePitchingLoaders
    [buttercup-browser-extension]/[loader-runner]/lib/LoaderRunner.js:178:10
  
  - LoaderRunner.js:189 
    [buttercup-browser-extension]/[loader-runner]/lib/LoaderRunner.js:189:18
  
  - loadLoader.js:53 handleResult
    [buttercup-browser-extension]/[loader-runner]/lib/loadLoader.js:53:2
  
  - NormalModule.js:753 processResult
    [buttercup-browser-extension]/[webpack]/lib/NormalModule.js:753:19
  
  - NormalModule.js:855 
    [buttercup-browser-extension]/[webpack]/lib/NormalModule.js:855:5
  
  - LoaderRunner.js:399 
    [buttercup-browser-extension]/[loader-runner]/lib/LoaderRunner.js:399:11
  
  - LoaderRunner.js:185 
    [buttercup-browser-extension]/[loader-runner]/lib/LoaderRunner.js:185:11
  
  - loadLoader.js:33 loadLoader
    [buttercup-browser-extension]/[loader-runner]/lib/loadLoader.js:33:11

Haven't seen anything regarding pug-walk, but it seems like a requirement?

Vue production build errors in example

I'm having an issue building the vue hello world example using the npm run build
Running in serve mode works as designed.

git clone https://github.com/webdiscus/pug-loader
cd ./pug-loader/examples/hello-world-vue
nvm install v16.17.1
Downloading and installing node v16.17.1...
Downloading https://nodejs.org/dist/v16.17.1/node-v16.17.1-darwin-arm64.tar.xz...
############################################################################################################################################################################################################## 100.0%
Computing checksum with sha256sum
Checksums matched!
Now using node v16.17.1 (npm v8.15.0)
npm i; npm ls
npm WARN deprecated [email protected]: Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility

added 996 packages, and audited 997 packages in 3s

116 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities
[email protected] /Users/null/pug-loader/examples/hello-world-vue
โ”œโ”€โ”€ @babel/[email protected]
โ”œโ”€โ”€ @babel/[email protected]
โ”œโ”€โ”€ @vue/[email protected]
โ”œโ”€โ”€ @vue/[email protected]
โ”œโ”€โ”€ @vue/[email protected]
โ”œโ”€โ”€ @webdiscus/[email protected]
โ”œโ”€โ”€ [email protected]
โ”œโ”€โ”€ [email protected]
โ”œโ”€โ”€ [email protected]
โ”œโ”€โ”€ [email protected]
โ”œโ”€โ”€ [email protected]
โ”œโ”€โ”€ [email protected]
โ”œโ”€โ”€ [email protected]
โ”œโ”€โ”€ [email protected]
โ”œโ”€โ”€ [email protected]
โ”œโ”€โ”€ [email protected]
โ”œโ”€โ”€ [email protected]
โ”œโ”€โ”€ [email protected]
โ””โ”€โ”€ [email protected]
npm run build

> [email protected] build
> vue-cli-service build

All browser targets in the browserslist configuration have supported ES module.
Therefore we don't build two separate bundles for differential loading.


โ ผ  Building for production...

 ERROR  Failed to compile with 1 error                                                                                                                                                                    12:39:40 PM

 error  in ./src/components/HelloWorld.vue?vue&type=template&id=a771edd6&lang=pug

Syntax Error: Thread Loader (Worker 0)
Cannot read properties of undefined (reading 'options')


 ERROR  Error: Build failed with errors.
Error: Build failed with errors.
    at /Users/null/pug-loader/examples/hello-world-vue/node_modules/@vue/cli-service/lib/commands/build/index.js:207:23
    at /Users/null/pug-loader/examples/hello-world-vue/node_modules/webpack/lib/webpack.js:148:8
    at /Users/null/pug-loader/examples/hello-world-vue/node_modules/webpack/lib/HookWebpackError.js:68:3
    at Hook.eval [as callAsync] (eval at create (/Users/null/pug-loader/examples/hello-world-vue/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:6:1)
    at Hook.CALL_ASYNC_DELEGATE [as _callAsync] (/Users/null/pug-loader/examples/hello-world-vue/node_modules/tapable/lib/Hook.js:18:14)
    at Cache.shutdown (/Users/null/pug-loader/examples/hello-world-vue/node_modules/webpack/lib/Cache.js:150:23)
    at /Users/null/pug-loader/examples/hello-world-vue/node_modules/webpack/lib/Compiler.js:1225:15
    at Hook.eval [as callAsync] (eval at create (/Users/null/pug-loader/examples/hello-world-vue/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:6:1)
    at Hook.CALL_ASYNC_DELEGATE [as _callAsync] (/Users/null/pug-loader/examples/hello-world-vue/node_modules/tapable/lib/Hook.js:18:14)
    at Compiler.close (/Users/null/pug-loader/examples/hello-world-vue/node_modules/webpack/lib/Compiler.js:1218:23)
    at /Users/null/pug-loader/examples/hello-world-vue/node_modules/webpack/lib/webpack.js:147:16
    at finalCallback (/Users/null/pug-loader/examples/hello-world-vue/node_modules/webpack/lib/Compiler.js:441:32)
    at /Users/null/pug-loader/examples/hello-world-vue/node_modules/webpack/lib/Compiler.js:458:13
    at Hook.eval [as callAsync] (eval at create (/Users/null/pug-loader/examples/hello-world-vue/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:24:1)
    at Hook.CALL_ASYNC_DELEGATE [as _callAsync] (/Users/null/pug-loader/examples/hello-world-vue/node_modules/tapable/lib/Hook.js:18:14)
    at onCompiled (/Users/null/pug-loader/examples/hello-world-vue/node_modules/webpack/lib/Compiler.js:456:21)
    at /Users/null/pug-loader/examples/hello-world-vue/node_modules/webpack/lib/Compiler.js:1196:17
    at Hook.eval [as callAsync] (eval at create (/Users/null/pug-loader/examples/hello-world-vue/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:6:1)
    at Hook.CALL_ASYNC_DELEGATE [as _callAsync] (/Users/null/pug-loader/examples/hello-world-vue/node_modules/tapable/lib/Hook.js:18:14)
    at /Users/null/pug-loader/examples/hello-world-vue/node_modules/webpack/lib/Compiler.js:1192:33
    at finalCallback (/Users/null/pug-loader/examples/hello-world-vue/node_modules/webpack/lib/Compilation.js:2787:11)
    at /Users/null/pug-loader/examples/hello-world-vue/node_modules/webpack/lib/Compilation.js:3092:11
    at Hook.eval [as callAsync] (eval at create (/Users/null/pug-loader/examples/hello-world-vue/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:6:1)
    at Hook.CALL_ASYNC_DELEGATE [as _callAsync] (/Users/null/pug-loader/examples/hello-world-vue/node_modules/tapable/lib/Hook.js:18:14)
    at /Users/null/pug-loader/examples/hello-world-vue/node_modules/webpack/lib/Compilation.js:3085:38
    at eval (eval at create (/Users/null/pug-loader/examples/hello-world-vue/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:15:1)
    at eval (eval at create (/Users/null/pug-loader/examples/hello-world-vue/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:14:1)
    at runMicrotasks (<anonymous>)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)

How to use it with tailwindcss and server side rendering?

Thanks for great loader!

What would I like to achieve

Following template:

// index.pug
doctype html
html(lang="en")
  head
    link(rel='stylesheet', href='tailwind-generated.css')
  body
    h1.bg-red-500 #{myVar}

and following backend function:

// index.ts
import indexTpl from './index.pug'

function index(): string {
	return indexTpl({
		myVar: 'some value got from elsewhere'
	})
}

should produce html string and generate following file with tailwindcss' jit:

/* tailwind-generated.css */
.bg-red-500 {
    --tw-bg-opacity: 1;
    background-color: rgb(239 68 68 / var(--tw-bg-opacity));
}

What I already got

ATM I get the value myVar into generated html-string, but I fail at generating and including the css file.

Any idea how to achieve that? I can create a small repro, if needed.

Doesn't fix indent pug with @webdiscus/pug-loader on nuxt 3 (vite)

If i have indent after template with pug lang i get error this

  > 2|   WrapperGlobal
> -------^
>     3|     v-container.fill-height
>     4|       h1
>     5|       |  {{ error }}

and i found fix this by @webdiscus/pug-loader and this didn't help me. mb i set config incorrect?

  1. install that
    2.set config in nuxt.config.ts
import vuetify from 'vite-plugin-vuetify'
import eslintPlugin from 'vite-plugin-eslint'
import svgLoader from 'vite-svg-loader'

export default defineNuxtConfig({
    ssr: true,
    generate: {
        dir: 'dist',
        subFolders: false
    },
    modules: [
        '@pinia/nuxt',
    ],
    css: [
        'vuetify/lib/styles/main.sass',
        '@mdi/font/css/materialdesignicons.min.css',
        'assets/sass/main.sass'
    ],
    build: {
        transpile: ['vuetify'],
    },
    app: {
        head: {
            title: 'Certification Personal Account',
        }
    },
    plugins: ['~/plugins/core.js'],
    vite: {
        build: {
            transpile: ['@webdiscus/pug-loader'],
        },
        define: {
            __VUE_I18N_FULL_INSTALL__: true,
            __VUE_I18N_LEGACY_API__: false,
            __INTLIFY_PROD_DEVTOOLS__: false
        },
        plugins: [
            eslintPlugin(),
            svgLoader(),
        ]
    }
})

Support resolving modules

Requiring any modules defined in webpack configuration under resolve.modules does not seem to work currently. This also affects any npm modules under node_modules

Pug:
- const classnames = require('classnames');

Error:

ERROR in   Error: Child compilation failed:
  Module build failed (from ./node_modules/@webdiscus/pug-loader/src/index.js):
  NonErrorEmittedError: (Emitted value instead of an instance of Error)
  [pug-loader] Pug compilation failed.
  PugLoaderException:
  [pug-loader] the file 'classnames' can't be resolved in the pug template:
  /path/to/project/pug/file.pug
  Error: Can't resolve 'classnames' in '/path/to/project/pug/'
      at processResult (/path/to/project/node_modules/webpack/lib/NormalModule.js:755:12)
      at /path/to/project/node_modules/webpack/lib/NormalModule.js:860:5
      at /path/to/project/node_modules/loader-runner/lib/LoaderRunner.js:400:11
      at /path/to/project/node_modules/loader-runner/lib/LoaderRunner.js:252:18
      at context.callback (/path/to/project/node_modules/loader-runner/lib/LoaderRunner.js:124:13)
      at /path/to/project/node_modules/@webdiscus/pug-loader/src/index.js:217:21
      at Object.compile (/path/to/project/node_modules/@webdiscus/pug-loader/src/index.js:168:5)
      at Object.module.exports (/path/to/project/node_modules/@webdiscus/pug-loader/src/index.js:216:11)
  ModuleBuildError: Module build failed (from ./node_modules/@webdiscus/pug-loader/src/index.js): 

Errors don't show the exact location of the error

[2] Template file: /code/nexus/portal/server/views/unsupported-browser.pug
[2] Possible reason: in the template may be used undefined variable.
[2] Solution in this case pass a variable into a pug file via the query parameter.
[2] For example, if you use in pug the external variable, like title= customData.options.title,
[2] then pass it into pug 'template.pug?customData=' + JSON.stringify({options:{title:'My title'}})
[2] TypeError: Cannot read properties of undefined (reading 'undefined')
[2]     at processResult (/code/nexus/node_modules/webpack/lib/NormalModule.js:750:12)
[2]     at /code/nexus/node_modules/webpack/lib/NormalModule.js:855:5
[2]     at /code/nexus/node_modules/loader-runner/lib/LoaderRunner.js:399:11
[2]     at /code/nexus/node_modules/loader-runner/lib/LoaderRunner.js:251:18
[2]     at runSyncOrAsync (/code/nexus/node_modules/loader-runner/lib/LoaderRunner.js:156:3)
[2]     at iterateNormalLoaders (/code/nexus/node_modules/loader-runner/lib/LoaderRunner.js:250:2)
[2]     at /code/nexus/node_modules/loader-runner/lib/LoaderRunner.js:223:4
[2]     at /code/nexus/node_modules/webpack/lib/NormalModule.js:829:15
[2]     at Array.eval (eval at create (/code/nexus/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:12:1)
[2]     at runCallbacks (/code/nexus/node_modules/enhanced-resolve/lib/CachedInputFileSystem.js:27:15)
[2]  @ ./server/views/index.ts 84:19-55
[2]  @ ./server/main.ts 29:16-34
[2]  @ ./server/mainPublic.ts 8:15-32 9:13-30

It only shows the main file where the error is, but it uses a layout which then uses a layout .. the error is hard to find.

webpack-dev-server: pages require access with .html

Hi!

Thanks for this package, I'm in the process of migrating from HtmlWebpackPlugin and using pug-loader from an older website.

One issue, is that while in production our website is fine, when using webpack-dev-server all links to our pages (people, research, publications ,etc.) require an .html postfix. I'm wondering if I've done something wrong, or if you have suggestions as to what I can try? Do I need to use the rewrite field?

My understanding is this should be handled by the magicHtml field https://webpack.js.org/configuration/dev-server/

webpack.common.js

const path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const CopyPlugin = require("copy-webpack-plugin");
const PugPlugin = require('pug-plugin');

module.exports = {
  entry: {
    index: './src/app/home/index.pug',
    people: './src/app/people/index.pug',
    research: './src/app/research/index.pug',
    publications: './src/app/publications/index.pug',
    resources: './src/app/resources/index.pug',
    teaching: './src/app/teaching/index.pug',
    apply: './src/app/apply/index.pug'
  },
  output: {
    filename: 'app/[name].bundle.js',
    path: path.resolve(__dirname, 'dist'),
    publicPath: 'auto'
  },
  plugins: [
    new PugPlugin({
      js: {
        // output filename of extracted JS file from source script defined in Pug
        filename: 'assets/js/[name].[contenthash:8].js',
      },
      css: {
        // output filename of extracted CSS file from source style defined in Pug
        filename: 'assets/css/[name].[contenthash:8].css',
      },
    })
  ],
  module: {
    rules: [
      {
        test: /\.(pug)$/,
        loader: PugPlugin.loader
      },
      {
        test: /\.s[ac]ss$/,
        use: [
          // "style-loader",
          "css-loader",
          "sass-loader"
        ]
      },
      {
        test: /\.(js)$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader'
        }
      },
      {
        test: /\.(png|jpg|jpeg|ico|svg)/,
        type: 'asset/resource',
        generator: {
          // output filename of images
          filename: 'assets/images/[name].[hash:8][ext]',
        },
      },
      {
        test: /font-awesome\/.+\/.+\.(eot|svg|ttf|otf|woff(2)?)(\?v=\d+\.\d+\.\d+)?$/,
        use: [{
          loader: 'file-loader',
          options: {
            name: '[name].[ext]',
            outputPath: 'fonts/'
          }
        }]
      }
    ]
  }
};

webpack.dev.js

const { merge } = require('webpack-merge');
const common = require('./webpack.common.js');
const path = require('path');

module.exports = merge(common, {
  mode: 'development',
  devtool: 'inline-source-map',
  devServer: {
    static: {
      directory: path.join(__dirname, 'dist'),
      serveIndex: true,
    },
  }
});

Windows only: Invalid path when using alias

File paths are not handled correctly when using the alias in include and extends.
The path specified in the alias is always glued to the path to the current template file.

In the case of extends, I get D:\\projects\\new-app\\src\\pages\\main\\D:\\projects\\new-app\\src\\layouts\\default\\default.pug
And in the case of include - D:\\projects\\new-app\\src\\layouts\\default\\D:\\projects\\UI\\src\\components\\XApp\\XApp.pug

In this case, the correct values for the alias are displayed in the console:

Exo path: D:/projects/UI/src/components
Layouts path: D:\projects\new-app\src\layouts

The following aliases have been added to the webpack config:

alias: {
  UI: 'D:/projects/UI/src/components',
  Layouts: path.resolve('src', 'layouts'),
},

My project uses the following structure:

src/
โ”œโ”€โ”€ ...
โ”‚
โ”œโ”€โ”€ layouts/
โ”‚   โ”œโ”€โ”€ default/
โ”‚   โ”‚   โ”œโ”€โ”€ ...
โ”‚   โ”‚   โ””โ”€โ”€ default.pug
โ”‚   โ””โ”€โ”€ ...
โ”‚
โ”œโ”€โ”€ pages/
โ”‚   โ”œโ”€โ”€ main/
โ”‚   โ”‚   โ”œโ”€โ”€ ....
โ”‚   โ”‚   โ””โ”€โ”€ main.pug
โ”‚   โ””โ”€โ”€ ...
โ”‚
โ””โ”€โ”€ ...

Layout code:

- var head = {}

block variables

include ~UI/XApp/XApp

doctype html
html
  head
    meta(charset="UTF-8")
    meta(name="viewport" content="width=device-width, initial-scale=1.0")
    meta(http-equiv="X-UA-Compatible" content="ie=edge")

    block head
      title.
        #{head.title || 'Default title'} - My Webpage
  body
    +x-app
      block content

Page code:

extends ~Layouts/default/default

block variables
  -
    var head = {
      title: 'Main page'
    }

block content
  h1 Hellow pug!

hello-world-app does not compile

Steps to reproduce:

1.) use git to clone /webdiscus/pug-loader/
2.) opened VS Code to this folder:
/pug-loader/blob/master/examples/hello-world-app/
3. Run npm i
4. Run npm run build

Output:

> [email protected] build
> webpack --mode=production --progress

2 assets
23 modules

ERROR in ./src/assets/images/app-logo.svg 1:0
Module parse failed: Unexpected token (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
> <?xml version="1.0" encoding="iso-8859-1"?>
| <!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
| <svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"

ERROR in ./src/assets/images/demo.jpeg 1:0
Module parse failed: Unexpected character '๏ฟฝ' (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
(Source code omitted for this binary file)

ERROR in ./src/assets/images/favicons/favicon-32px.png 1:0
Module parse failed: Unexpected character '๏ฟฝ' (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
(Source code omitted for this binary file)

ERROR in ./src/assets/images/favicons/favicon.svg 1:0
Module parse failed: Unexpected token (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
> <?xml version="1.0" encoding="utf-8"?>
| <!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
| <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"

ERROR in [entry] [initial]
[pug-plugin] Can't resolve the file C:/Users/***/source/pug-loader/examples/hello-world-app/src/assets/images/favicons/favicon.svg in C:\Users\***\source\pug-loader\examples\hello-world-app\src\views\pages\home\index.pug

Is this happening because I'm on a Windows 10 machine?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.