Git Product home page Git Product logo

webdiscus / pug-plugin Goto Github PK

View Code? Open in Web Editor NEW
69.0 2.0 8.0 21.38 MB

Uses Pug template as entry point. Resolves source files of scripts, styles, images in Pug. Renders Pug to HTML.

Home Page: https://webdiscus.github.io/pug-plugin/hello-world

License: ISC License

JavaScript 61.30% HTML 16.21% Pug 13.78% SCSS 4.99% CSS 3.71%
webpack pug pug-loader html loader plugin pug-plugin render template entry

pug-plugin's Introduction

The plugin renders Pug templates with referenced source asset files into HTML

npm node node Test codecov node

Pug template as entry point

The Pug Plugin 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.

💡 Highlights

  • An entry point is the Pug template.
  • Auto processing multiple templates in the entry path.
  • Allows to specify script and style source files directly in Pug:
    • link(href="./style.scss" rel="stylesheet")
    • script(src="./app.tsx" defer="defer")
  • Resolves source files in default attributes href src srcset etc. using relative path or alias:
    • link(href="../images/favicon.svg" type="image/svg" rel=icon)
    • img(src="@images/pic.png" srcset="@images/pic400.png 1x, @images/pic800.png 2x")
  • Inlines JS and CSS into HTML.
  • Inlines images into HTML and CSS.
  • Compile the Pug template into template function for usage in JS on the client-side.
  • Generates the preload tags for fonts, images, video, scripts, styles, etc.
  • Generates the integrity attribute in the link and script tags.
  • Generates the favicons of different sizes for various platforms.
  • Built-in filters: :escape :code :highlight :markdown.
  • You can create own plugin using the Plugin Hooks.

See the full list of features.

Note

‼️ All features and options of the html-bundler-webpack-plugin available now in the pug-plugin too.

Warning

Since the version 5.0.0, the Pug plugin is essentially the html-bundler-webpack-plugin preconfigured for using Pug templates.

Warning

Compared to the version 4.x, in the new version 5.x the source asset file can be specified in a template without the require() function. For compatibility, the require() function is still supported.

//- OLD syntax: the path is relative to the partial file or can be as the webpack alias
link(href=require("./style.scss") rel="stylesheet")
//- NEW syntax: the path is relative to the entry file or can be as the webpack alias
link(href="./style.scss" rel="stylesheet")

See the full list of the BREAKING CHANGES in v5.



Install and Quick start

Install the pug-plugin:

npm install pug-plugin --save-dev

Install additional packages for styles:

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

For example, there is the Pug template with source asset files ./src/views/index.pug:

html
  head
    //- relative path to SCSS source file
    link(href="../scss/style.scss" rel="stylesheet")
    //- relative path to TypeScript source file
    script(src="../app/main.js" defer="defer")
  body
    h1 Hello World!
    //- relative path to image source file
    img(src="../assets/images/picture1.png")
    //- Webpack alias as path (src/assets/images/) to image source file
    img(src="@images/picture2.png")

The minimal webpack config:

const PugPlugin = require('PugPlugin');

module.exports = {
  plugins: [
    new PugPlugin({
      entry: {
        // define many page templates here
        index: 'src/views/index.pug', // => dist/index.html
      },
      js: {
        // JS output filename
        filename: 'js/[name].[contenthash:8].js',
      },
      css: {
        // CSS output filename
        filename: 'css/[name].[contenthash:8].css',
      },
    }),
  ],
  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]',
        },
      },
    ],
  },
};

Warning

No additional pug or html loaders required.

The generated HTML contains URLs of the output filenames:

<html>
  <head>
    <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/picture1.58b43bd8.png" />
    <img src="img/picture2.bd858b43.png" />
  </body>
</html>

Pug Plugin options

The Pug plugin has all the options of the HTML Bundler Plugin, plus a few options specific to Pug plugin.

pretty

Type: 'auto'|boolean|Object Default: false

The Pug compiler generate minimized HTML. For formatting generated HTML is used the js-beautify with the following default options:

{
  html: {
    indent_size: 2,
    end_with_newline: true,
    indent_inner_html: true,
    preserve_newlines: true,
    max_preserve_newlines: 0,
    wrap_line_length: 120,
    extra_liners: [],
    space_before_conditional: true,
    js: {
      end_with_newline: false,
      preserve_newlines: true,
      max_preserve_newlines: 2,
      space_after_anon_function: true,
    },
    css: {
      end_with_newline: false,
      preserve_newlines: false,
      newline_between_rules: false,
    },
  },
}

Possible values:

  • false - disable formatting
  • true - enable formatting with default options
  • 'auto' - in development mode enable formatting with default options, in production mode disable formatting, use prettyOptions to customize options
  • {} - enable formatting with custom options, this object are merged with default options
    see options reference

prettyOptions

Type: Object Default: null

When the pretty option is set to auto or true, you can configure minification options using the prettyOptions.


History of Pug Plugin

Why the Pug Plugin since v5.0 based on html-bundler-webpack-plugin?

2021
The history of the creation of the pug-plugin began back in October 2021. Then, at the end of 2021, I created the @webdiscus/pug-loader that had all the features of the original pug-loader.

2022
Using, then without an alternative, html-webpack-plugin caused me pain and suffering to configure webpack for rendering Pug templates containing various assets. At the beginning of 2022, I started creating the pug-plugin as a complete replacement for the html-webpack-plugin and many other "crutches". During of the year, the pug-plugin has gained a lot of useful features and was able to replace the html-webpack-plugin, mini-css-extract-plugin and many other plugins and loaders.

2023
Based on the pug-plugin code, I decided to create a universal html-bundler-webpack-plugin that would support all the most popular template engines, such as Eta, EJS, Handlebars, Nunjucks, Pug, TwigJS, and would be extendable for other template engines, e.g., LiquidJS. During 2023, this plugin has gained even more useful features and absorbed all the functionality of the pug-plugin and the @webdiscus/pug-loader.

2024
At the beginning of 2024, the pug-plugin completely switched to the universal code html-bundler-webpack-plugin. Starting from version 5.0, the pug-plugin is the html-bundler-webpack-plugin pre-configured for Pug templates with the pre-installed pug package.

The config of pug-plugin >= v5.0:

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

module.exports = {
  plugins: [
    new PugPlugin({
      entry: {
        index: 'src/views/home.pug',
      },
    }),
  ],
};

is the same as:

const HtmlBundlerPlugin = require('html-bundler-webpack-plugin');

module.exports = {
  plugins: [
    new HtmlBundlerPlugin({
      entry: {
        index: 'src/views/home.pug',
      },
      preprocessor: 'pug', // <= enable using Pug templating engine
    }),
  ],
};

The pug-plugin's heart now lives in the html-bundler-webpack-plugin.

@webdiscus/pug-loader -> pug-plugin -> html-bundler-webpack-plugin -> pug-plugin

Also See

  • ansis - The Node.js library for ANSI color styling of text in terminal
  • pug-loader - The Pug loader for webpack
  • html-bundler-webpack-plugin - The plugin handles HTML template as entry point, extracts CSS, JS, images from their sources loaded directly in HTML

License

ISC

pug-plugin's People

Contributors

glektarssza avatar snyk-bot 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  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

pug-plugin's Issues

[Windows] Inline CSS not working due to the difference between sourceRequest and rawRequest

I'm trying to use inline CSS with the plugin, but what i got inside style is the resource url of the SCSS I required.

For example, if I use inline CSS using style=require('./styles.scss?inline'), the content of style will be style.3ef5f.css instead of the CSS code generated by webpack.

After some research, I found that the sourceRequest (index.js#L655) added to AssetSource is different from rawRequest (Resolver.js#L286) used by require.
The sourceRequest's path separator is \, which is Windows style (I'm working on Windows).
The rawRequest's path separator is /.
If I replace all / in rawRequest to \ using debugger, everything is working as expected.

Compilation fails when using `url` with `var` in SCSS

I've tried using the following snippet:

h2::before {
    content: url(var(--my-content));
}

which fails with Can't resolve 'var(--my-content in...

I'm using

    "css-loader": "^6.7.1",
    "pug-plugin": "^4.2.0",
    "sass": "^1.54.6",
    "sass-loader": "^13.0.2",
    "webpack": "^5.74.0",
    "webpack-cli": "^4.10.0"

with the following webpack config:

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

module.exports = {
  entry: {
    index: './src/views/login.pug',
    albums: './src/views/albums.pug',
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    publicPath: 'auto',
    filename: 'assets/js/[name].js',
  },
  module: {
    rules: [
      {
        test: /\.pug$/,
        loader: PugPlugin.loader,
        options: {
          method: 'render',
        }
      },
      {
        test: /\.s[ac]ss$/,
        use: [
          'css-loader',
          'sass-loader',
        ],
      },
      {
        test: /\.(png|jpg|jpeg|svg|ico)$/,
        type: 'asset/resource',
        generator: {
          filename: 'assets/images/[name][ext]',
        },
      },
    ],
  },
  plugins: [
    // enable processing of Pug files defined in webpack entry
    new PugPlugin({
      extractCss: {
        // output filename of CSS files
        filename: 'assets/css/[name].css',
      },
    }),
  ],
  resolve: {
    alias: {
      Assets: path.join(__dirname, 'src/assets/'),
    },
  },
}

I think pug-plugin should just ignore any url containing var since it cannot be resolved at compile-time.

Unexpected troubles with output.publicPath

Good afternoon!

To begin with, I have to say, thats my first issue on github, don't judge strictly.

I updated pug-plugin dependency and found out some troubles with output.publicPath. I setted output.publicPath: './'. The problem is that there were generated chunks (runtime,vendors, app) but i didn't use any settings for it. Also, HRM didn't work. Thereafter, I wanted to describe this issue. But then I suddenly decided to change the output.public Path to 'auto' and all these problems disappeared.

My config - https://github.com/ladown/webpack-template/tree/master/webpack

What could be the problem?

Cannot find module with root path using context

script(src=require('/js/main.js')):

  • 3.0.1 - works
  • 3.1.0 - doesn't work: Cannot find module '/js/main.js'

With styles is ok: link(href=require('/styles/styles.scss'), rel='stylesheet')

Structure:

  • src/views/index.pug
  • src/js/main.js
  • src/styles/styles.scss

Modules from HotReplacementPlugin being injected into inline JS

When I'm using inline JS with webpack-dev-server, the inline JS code will be injected with hot replacement code from HotReplacementPlugin and webpack bootstrap code.

In my circumstance, the inline JS code throws an error claiming Automatic publicPath is not supported in this browser and stops execution.

If I run a build instead of dev server, the inline JS script works perfectly.

I have no idea how to deal with this.
I'll be waiting for your reply on this, thanks.

[FEATURE REQUEST] How to do inline CSS

I am trying to inline my critical CSS for a faster initial load.

I tried the following pug code:

style !{require('../css/styles.css?raw')}

And in my webpack config, I put:

{
    resourceQuery: /raw/,
    type: 'asset/source',
    use: 'css-loader',

}

But this throws the following error:

ERROR in [entry] [initial]
[pug-plugin] Can't resolve the file /home/marcel/code/biography-site/src/css/styles.css?raw in /home/marcel/code/biography-site/src/pug/index.pug
The reason: this file not found!
/home/marcel/code/biography-site/node_modules/pug-plugin/src/Exceptions.js:34
  throw new PugPluginException(lastError);
  ^

PugPluginException:
[pug-plugin] Can't resolve the file /home/marcel/code/biography-site/src/css/styles.css?raw in /home/marcel/code/biography-site/src/pug/index.pug
The reason: this file not found!

    at PugPluginError (/home/marcel/code/biography-site/node_modules/pug-plugin/src/Exceptions.js:34:9)
    at resolveException (/home/marcel/code/biography-site/node_modules/pug-plugin/src/Exceptions.js:77:3)
    at Resolver.require (/home/marcel/code/biography-site/node_modules/pug-plugin/src/Resolver.js:305:5)
    at /home/marcel/code/biography-site/src/pug/index.pug:1:955
    at Script.runInContext (node:vm:141:12)
    at PugPlugin.renderModule (/home/marcel/code/biography-site/node_modules/pug-plugin/src/index.js:718:33)
    at PugPlugin.renderManifest (/home/marcel/code/biography-site/node_modules/pug-plugin/src/index.js:652:28)
    at Hook.eval [as call] (eval at create (/home/marcel/code/biography-site/node_modules/tapable/lib/HookCodeFactory.js:19:10), <anonymous>:7:16)
    at Hook.CALL_DELEGATE [as _call] (/home/marcel/code/biography-site/node_modules/tapable/lib/Hook.js:14:14)
    at Compilation.getRenderManifest (/home/marcel/code/biography-site/node_modules/webpack/lib/Compilation.js:4483:36)

It seems like a problem with this plugin, because if I delete the style tag from the pug code and move the contents of require() to a second entry in my webpack config, it compiles without problems.

I also tried with asset/inline, but that is putting the base64 encoding of the styles in the <style> tag.

{
    resourceQuery: /raw/,
    type: 'asset/inline',
    use: 'css-loader',

}

My source for type: 'asset/source': https://webpack.js.org/guides/asset-modules/

Is there a way to achieve this?

Automatic "publicPath"

Why is output.publicPath: 'auto' not supported?

When are you planning to role this feature?

Screenshot 2022-07-10 at 10 22 55 AM

Require manifest.json file

Discussed in #70

Originally posted by elldur March 21, 2023

link(rel="manifest" href=require("/meta/webmanifest.json"))
\/
<link rel="manifest" href="{... json contents}">

Despite {test: /\.(ico|svg|png|ttf|json)$/, type: "asset/resource"} being in webpack config. Loading works correctly when importing in javascript (using import not require). The problem is fixed by using a different extension e.g. .webmanifest.

require treats json differently even outside of pug but the solutions I found involve changing require.extensions which does not exist in pug since require seems to be a wrapper for mod.require which is not accessible within pug.

Is there a way around this other than changing the extension?

TypeError if webpack output.path is not defined

To get started, I copied the first code block from your readme:

const PugPlugin = require('pug-plugin');
module.exports = {
  entry: {
    index: './src/views/home/index.pug',  // output dist/index.html
    about: './src/views/about/index.pug', // output dist/about.html
  },
  plugins: [
    new PugPlugin(), // enable processing of Pug files specified in Webpack entry
  ],
  module: {
    rules: [
      {
        test: /.pug$/,
        loader: PugPlugin.loader, // Pug loader
      },
    ],
  },
};

However, this produced the following error:

[webpack-cli] TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string. Received undefined
    at new NodeError (node:internal/errors:363:5)
    at validateString (node:internal/validators:119:11)
    at Object.isAbsolute (node:path:1157:5)
    at AssetEntry.add (/home/marcel/code/biography-site/node_modules/pug-plugin/src/AssetEntry.js:54:37)
    at PugPlugin.afterProcessEntry (/home/marcel/code/biography-site/node_modules/pug-plugin/src/index.js:356:18)
    at Hook.eval [as call] (eval at create (/home/marcel/code/biography-site/node_modules/tapable/lib/HookCodeFactory.js:19:10), <anonymous>:7:16)
    at Hook.CALL_DELEGATE [as _call] (/home/marcel/code/biography-site/node_modules/tapable/lib/Hook.js:14:14)
    at WebpackOptionsApply.process (/home/marcel/code/biography-site/node_modules/webpack/lib/WebpackOptionsApply.js:330:30)
    at createCompiler (/home/marcel/code/biography-site/node_modules/webpack/lib/webpack.js:80:28)
    at create (/home/marcel/code/biography-site/node_modules/webpack/lib/webpack.js:134:16) {
  code: 'ERR_INVALID_ARG_TYPE'
}

The solution was as easy as adding the following to webpack.config.js:

	output: {
		filename: '[name].js',
		path: path.resolve(__dirname, 'build'),
	},

However, I think the plugin should somehow use webpack's default output options. At the very least, the example should be updated to have output.path specified.

I am using version 4.3.3 of this plugin, version 5.68.0 of webpack, and 6.2.0 of node.

Can I choose different outputPath of specific file by extension?

I want to know if is possible to set different outputPath of specific files.
I'm using in my project PugJS, StylusJS, and Typescript. I've configured the output.path to dist directory, so now all files render inside it.

module.exports = {
  mode,
  watch: !isProduction,
  entry: WebpackUtil.filesToCompileSync('pug/modules', /\.pug$/),
  output: {
    path: path.resolve(__dirname, 'dist'),
    publicPath: '/',
    clean: true
  },
  resolve: {
    extensions: ['.ts', '.js'],
  },
  plugins: [
    new PugPlugin({
      pretty: !isProduction,
      filename: '[name].phtml',
      modules: [
        {
          test: /\.(css|styl)$/,
          outputPath: path.resolve(__dirname, 'other/path/')
        }
      ],
      css: {
        filename: 'css/[name].css',
        outputPath: path.join(__dirname, 'test')
      },
      js: {
        filename: 'js/[name].js'
      }
    })
  ],
  module: {
    rules: [
      {
        test: /\.pug$/,
        loader: PugPlugin.loader
      },
      {
        test: /\.(css|styl)$/,
        use: ['css-loader', 'stylus-loader']
      },
      {
        test: /\.ts$/,
        loader: 'ts-loader'
      }
    ]
  }
}

I've seen in your documentation that I can configure outputPath from specific directory, something like this:

const PugPlugin = require('pug-plugin');
module.exports = {
  plugins: [
    new PugPlugin({
      modules: [
        {
          test: /fonts\/.+\.svg$/,
          outputPath: path.join(__dirname, 'dist/some/other/path/'),
        },
      ],
    }),
  ],
};

I want to do this:

html: application/modules/...
css: css/modules/...
js: js/modules/...

This is my public repo if you want to see it https://github.com/ltsfran/example-legacy-webpack

How to combine all CSS and JS files in bundle?

Hi guys,

Maybe I missed something. But how to combine all css files for the page in one bundle css file?
The same for js files - how to combine all js files for the page in one bundle?

Because I construct my pages in pug including widgets (also in pug), each widget has its own styles and scripts. I would like to gather all styles all widgets in one css file for the page, and I can't find any information on it in pug-plugin documentation...

When pug template is broken, error page is not properly rendered.

Based on hello world example project.
I introduce error in about/index.pug template.
When opening /about.html unreadable page is returned to user.
Weirdly, when opening other valid page, like /contact.html, error is still displayed, and it is readable.
See screenshots.
I think, we should get readable error when opening broken page (/about.html).
Ideally we could also open valid pages, even if few others are broken.

when-opening-broken-page

when-opening-other-page

Only use PugPlugin.loader but can't compile images

I've use PugPlugin.loader to preprocess the pug templates in my project, only use the loader without initial the plugin. It work fine when at development mode, but when build it in production mode, all images referenced in the pug files can't compile to the output directory.

Here is the code in base webpack config

...

  {
    test: /\.pug$/,
    use: {
      loader: PugPlugin.loader,
      options: {},
    },
  },

...

  new HtmlWebPackPlugin({
    filename: `${page}.html`,

    // template for individual pages index, about and contact
    template: `./src/templates/${page}.pug`,
    chunks: [share, page],
    chunksSortMode: 'manual',
  })

How can I make it work with minimal changes, I'd like to use only the loader instead of replace all other things with PugPlugin.

Can't extract html, css, js and images from pug file

I'm using pug v2.0.4, webpack v5.75.0 and node v14.15.4 for dev reasons. This is the interested code:

---
title: "Core - Dashboard Builder"
classSidebarHome: active
pageTitle: "Dashboard"
classHeader: unauthorized
---
extends layouts/layout
block content...

And this is my webpack.config.js:

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

module.exports = {
    mode: 'none',
    entry: {
        index: './src/pug/index.pug',
    },
    output: {
        path: path.resolve(__dirname, 'dist'),
        publicPath: '/',
        filename: 'assets/js/[name].[contenthash:8].js'
    },
    module: {
        rules: [
            {
                test: /\.pug$/,
                loader: PugPlugin.loader, // default method is 'render'
            },
            {
                test: /\.(css|sass|scss)$/,
                use: ['style-loader', 'css-loader', 'sass-loader']
            },
            {
                test: /\.(png|jpg|jpeg|ico)/,
                type: 'asset/resource',
                generator: {
                    // output filename of images
                    filename: 'assets/img/[name].[hash:8][ext]',
                },
            }
        ]
    },
    plugins: [
        new PugPlugin({
            extractCss: {
                // output filename of CSS files
                filename: 'assets/css/[name].[contenthash:8].css'
            },
        }),
    ],
    devServer: {
        static: './src'
    }
};

Instead this is my src folder structure:

  • src [root]
  • img [2nd-tier]
  • js [2nd-tier]
  • pug [2nd-tier]
  • sass [2nd-tier]

When I run webpack (aka npm run build) the result is an unexpected text error near "Core..." and also if I remove the "variables" from pug file because they are not variables I can't extract assets from entry file and src folder.

What's the problem? I would like to understand where I'm wrong.

If HMR is disabled then page gets infinite reload

@webdiscus that is great!

The infinite reload loop is still there for me - now with both HMP Enabled/Disabled.

I noticed that if I open the dev-tools (on browser) it stops reloading and gives the following HMP warning(s) in the console.

Screenshot 2022-06-19 at 8 48 50 AM

Also I have added video below to see it live:

comp.mp4

NOTE: If dev-tools are active then it works fine, if dev-tools are not opened it gives this infinite loop behaviour on all the browsers.

My devServer config is as follow:

devServer: {
    devMiddleware: {
      publicPath: join(__dirname, 'build'),
      writeToDisk: true,
    },
    port: '9999',
    proxy: {
      '/': {
        target: `http://localhost/${projectName}/build`,
      },
    },
    static: {
      directory: join(__dirname, 'build'),
    },
    watchFiles: {
      paths: ['src/**/*.*'],
      options: {
        usePolling: true,
      },
    },
  },

Hope all this give you some direction in order to help this issue.

"Not allowed to load local resource" when adding a script from node modules

Good day! I'm trying to add Bootstrap to my project when using pug-plugin. As recipes said I do:

script(src=require('bootstrap/dist/js/bootstrap.bundle.js'))

Then I start webpack-dev-server. And everything goes good until I make a change in any .scss or .js file of the project and then save the file. After page autoreload I get this error in browser console:

error-image

Strangely enough, if I make a change in .pug file the error doesn't appear. And if I put bootstrap.bundle.js out of /node_modules somewhere into /src and load it from there the error also does not appear.

As a test I add Bootstrap in the standard pug-plugin example "simple-multipage". Here is the repo

Can't resolve the file for data-url in CSS

When using inline data in CSS via a data-url, the pug plugin tries to resolve the url which throws an error:

[pug-plugin] Can't resolve the file data:image/png;base64,iVBORw0K...
.image {
  background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSU...==);
}

this issue is extracted from the ticket to split one issue to two differents.

[FEATURE REQUEST] Preload support for font image audio video

Here is the modified FR #60.

Automatically preload assets resolved in HTML or in CSS:

  • style
  • script
  • font
  • image
  • audio
  • video

For example, there is the style used a font:

style.css

@font-face {
  font-family: "Fira Sans";
  src:  url('fonts/fira/FiraSans-Regular.woff2') format('woff2');
}

The generated HTML:

<html>
<head>
  <title>Demo</title>

  <!-- injected preloads -->
  <link rel="preload" href="css/style.1f4faaff.css" as="style">
  <link rel="preload" href="js/main.c608b1cd.js" as="script">  
  <link rel="preload" href="fonts/fira/FiraSans-Regular.woff2" as="font" type="font/woff2" />
  <link rel="preload" href="assets/img/imac.3666c92d.svg" as="image" type="image/svg+xml">
   
  <!-- load style -->   
  <link href="style.1f4faaff.css" rel="stylesheet" />
</head>
<body>
  <img src="assets/img/apple.3666c92d.svg" alt="apple">
  ...
  <!-- load script -->
  <script src="js/main.c608b1cd.js"></script>
</body>
</html>

The auto generated preload link tag should be injected before a first style or script tag in head.

The option name should be preload:

{
  preload: [
    {
      test: /\.(s?css|less)$/,
      as: 'style',
    },
    {
      test: /\.(js|ts)$/,
      as: 'script',
    },
    {
      test: /[\\/]fonts[\\/].+(eot|ttf|woff|woff2)$/,
      as: 'font',
      // the `type` attribute will be added automatically : 'font/woff2',  'font/ttf', etc.
      // additional optional attributes 
      attributes: { crossorigin: true },
    },
    {
      test: /[\\/]images[\\/].+(svg|png|jpg)$/,
      as: 'image',
      // the `type` attribute will be added automatically : 'image/svg+xml',  'image/png', etc.
    },
  ],
}

Usage with webpack-hot-middleware

We use webpack-hot-middleware [1] in Development for hot reloading.

Our entrypoints currently look like this:

Development:

entry: {
  main: [
    // must be first entry to properly set public path
    path.resolve(dirname, 'src/webpack-public-path'),
    'webpack-hot-middleware/client?reload=true',
    path.resolve(dirname, 'src/js/index')
  ],
}

Production:

entry: {
  main: path.resolve(dirname, 'src/js/index'),
}

In development (only) each entrypoint needs to have 'webpack-hot-middleware/client?reload=true'.
How can we configure this with pug-plugin?

[1] https://github.com/webpack-contrib/webpack-hot-middleware

Bug in Node.js <= 14. No sourceMap for CSS.

Hey,

I'm using extractCss which is working so far, but I couldn't figure out how to enable the source map creation with this.
I have added sourceMap: true to css- postcss- and sass-loader, but it's not creating one.

How do I enable source map with pug plugin?

splitChunks settings breaks the build

Hi

Trying to to extract third-party libraries into a separate vendor chunk, using webpack optimization.splitChunks.cacheGroups settings:

     splitChunks: {
       cacheGroups: {
         vendor: {
           test: /[\\/]node_modules[\\/]/,
           name: 'vendors',
           chunks: 'all',
         },
       },
     },

Got an error:

assets by status 269 KiB [cached] 5 assets
Entrypoint index = assets/js/runtime.1b128ecc.js assets/js/vendors.c9af3c70.js index.html assets/css/styles.d17f6b81.css
Entrypoint main = assets/js/runtime.1b128ecc.js assets/js/vendors.c9af3c70.js assets/js/main.750f9c8b.js
orphan modules 76.6 KiB [orphan] 58 modules
runtime modules 3.36 KiB 6 modules
cacheable modules 404 KiB
  asset modules 4.42 KiB
    data:image/svg+xml,%3csvg xmlns=%27.. 281 bytes [built] [code generated]
    data:image/svg+xml,%3csvg xmlns=%27.. 279 bytes [built] [code generated]
    data:image/svg+xml,%3csvg xmlns=%27.. 161 bytes [built] [code generated]
    data:image/svg+xml,%3csvg xmlns=%27.. 271 bytes [built] [code generated]
    + 12 modules
  javascript modules 400 KiB
    modules by path ./node_modules/ 208 KiB 4 modules
    modules by path ./src/ 192 KiB
      ./src/index.pug 337 bytes [built] [code generated]
      + 2 modules

ERROR in [initial] assets/js/vendors.0608b1c6.js
Cannot destructure property 'managedFiles' of 'module.buildInfo.snapshot' as it is undefined.
TypeError: Cannot destructure property 'managedFiles' of 'module.buildInfo.snapshot' as it is undefined.
    at C:\Users\arusak\Documents\git\pug-plugin-split-chunk-issue\node_modules\pug-plugin\src\index.js:623:21
    at Hook.eval [as call] (eval at create (C:\Users\arusak\Documents\git\pug-plugin-split-chunk-issue\node_modules\tapable\lib\HookCodeFactory.js:19:10), <anonymous>:7:1)
    at C:\Users\arusak\Documents\git\pug-plugin-split-chunk-issue\node_modules\webpack\lib\Compilation.js:4644:31
    at C:\Users\arusak\Documents\git\pug-plugin-split-chunk-issue\node_modules\webpack\lib\Cache.js:93:5
    at Hook.eval [as callAsync] (eval at create (C:\Users\arusak\Documents\git\pug-plugin-split-chunk-issue\node_modules\tapable\lib\HookCodeFactory.js:33:10), <anonymous>:6:1)
    at Cache.get (C:\Users\arusak\Documents\git\pug-plugin-split-chunk-issue\node_modules\webpack\lib\Cache.js:75:18)
    at ItemCacheFacade.get (C:\Users\arusak\Documents\git\pug-plugin-split-chunk-issue\node_modules\webpack\lib\CacheFacade.js:111:15)
    at C:\Users\arusak\Documents\git\pug-plugin-split-chunk-issue\node_modules\webpack\lib\Compilation.js:4560:22
    at arrayEach (C:\Users\arusak\Documents\git\pug-plugin-split-chunk-issue\node_modules\neo-async\async.js:2405:9)
    at Object.each (C:\Users\arusak\Documents\git\pug-plugin-split-chunk-issue\node_modules\neo-async\async.js:2846:9)

webpack 5.73.0 compiled with 1 error in 5315 ms

Sample repo for reproduce the issue

Thank you!

Add html-loader functionality

It would be really awesome if you could add functionality similar to that of html-loader.

html-loader parses the html and automatically adds assets as dependencies. Something similar should be possible for pug.

TMK this happens on the basis of a list of tags and attributes that should be treated as assets.

Adding this functionality would eliminate the need to use require for assets making the DX even more awesome.
(parcel also does this. HTML as entypoint with automatic asset loading)

Using require for assets could ideally still be optionally possible.

Bootstrap JS not executing after build

I just noticed, when i in the development mode, bootstrapjs work perfectly fine, but once I build it, paths going to extract and include in the head area, but none of the functions are working tried all possible ways, but none of them are working,

try to include like this

script(src=require('../../../node_modules/bootstrap/dist/js/bootstrap.bundle.min.js'), defer=true) 
script(src=require('./onboarding.js'), defer=true) 

and then this one inside onboarding.js

import "bootstrap";

also tried

require("bootstrap")

all of them are working but not after build js files going to compile and include in the head area.

match text in postprocess for compiled pug

@webdiscus something is wrong with postprocess for js. I think /main.js/ is not here in postprocess moment

new PugPlugin({
  postprocess: (content) => {
    // ...content
    content = content.replace(
      /src="(\/.*?\.js)"/g, // doesn't find anything
      `src="FROM(my_zip, '$1')"`,
    );
    return content;
  }),
})

src="(\/.*?\.js)" matches src="/js/main.js"

The links of JS and CSS should be replaced in generated HTML.

Sometimes we need to paste HTML in another parser which reads assets (images, css, js) from zip file and sends to client. So "replacer" replaces to path to zip folder

Originally posted by @silveoj in #36 (comment)

Windows only: All reported dependencies need to be absolute paths.

[NOTE] The issue has relation with the issue in pug-loader.

Original description

When I try to include a partial mixin file it shows:

Invalid dependencies have been reported by plugins or loaders for this module. All reported dependencies need to be absolute paths. Invalid dependencies may lead to broken watching and caching. As best effort we try to convert all invalid values to absolute paths and converting globs into context dependencies, but this is deprecated behavior. Loaders: Pass absolute paths to this.addDependency (existing files), this.addMissingDependency (not existing files), and this.addContextDependency (directories). Plugins: Pass absolute paths to fileDependencies (existing files), missingDependencies (not existing files), and contextDependencies (directories). Globs: They are not supported. Pass absolute path to the directory as context dependencies.

Why is this happening? I have tried ./Stats and src/pug/Stats but it shows the same error...
And also webpack dev server is not watching the partials file. On edit, the server is not refreshing...

Optimize/minify CSS, HTML, Javascript

I used your pug-loader with html-webpack-plugin, mini-css-extract-plugin. (For prod) I minify my CSS, HTML (and Javascript) files.

Now I use pug-plugin. So I don't use html-webpack-plugin, mini-css-extract-plugin (from doc).

webpack config:

PugPlugin.extractCss({
  filename: '[name].[contenthash:8].css',
}),
// extractHtml

index.pug:

    link(href=require('/styles/styles.scss') rel='stylesheet')
    script(src=require('/js/main.js'))

And now only CSS is minified (because of PugPlugin.extractCss?)

optimization doesn't work.

optimization: {
    minimize: true,
    // minimizer: []
}

How to find options to minify HTML and JS?

Missing script attributes after re-compiling with HMR

Hi I'm facing two issues that are built on each other when using this plugin.

First, If I disable Hot Module Replacement (HMP) then page gets infinite reload.
Page keeps refreshing no matter what you do. However, enabling HMP fix this issue.

But this leads to another one.

Now with HMP enabled defer attribute added to script tag is randomly added/removed on liveReload.

Whenever I make any change to the code (especially SCSS), defer attribute added to script(src=require(~JS/${name}.js) defer='defer') is randomly added (majority of times it's not in the script) from the output.

Mixin doesn't generate slash for self closing tags

I prepared 2 branches:

I use doctype html5 to pug adds me slash for self closing tags.

2 test cases:

  1. works - when I use markup without mixin output generates slash for self closing tags
  2. doesn't work - when I use markup inside any mixin (mixin is placed inside/outside of files) output doesn't generate slash for self closing tags: source, img, link, etc

Actual:

<link rel="stylesheet" href="/styles.css">
<source srcset="/assets/img/image.png" type="image/png">
<img src="/assets/img/image.jpeg" alt="description">

Expected:

<link rel="stylesheet" href="/styles.css"/>
<source srcset="/assets/img/image.png" type="image/png"/>
<img src="/assets/img/image.jpeg" alt="description" />

Quick fix: add slash at the end of pug tag - img(src="..")/

Input

mixin my-picture
  picture
    source(
      srcset=require(`/assets/img/image.png`)
      type='image/png'
    )
    img(
      src=require(`/assets/img/image.jpeg`)
      alt=''
    )

doctype html5
html
  body
    h2 picture + img - mixin
    h3 doesn't work
    +my-picture

~Output

    <picture>
      <source srcset="/assets/img/image.0acbc4558e7b27c288531b5c4f5971c7-737w.png" type="image/png">
      <img src="/assets/img/image.a222788447658269ca708d9ab19798a6-737w.jpeg" alt="">

Alias resolving issue on Windows

using latest webpack, ang pug-plugin
can't resolve alises usage like in example
try to use "extends ~Views/layouts/default.pug"
in "views/pages/home/index.pug"

got error:
ERROR in ./src/views/pages/home/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. PugLoaderException: [pug-loader] the file ~Views/layouts/default.pug can't be resolved in the pug template: D:\0html\pug_plugin_test2\src\views\pages\home\index.pug Error: Can't resolve '~Views/layouts/default.pug' in 'D:\0html\pug_plugin_test2\src\views\pages\home' at D:\0html\pug_plugin_test2\src\views\pages\home\index.pug line 2 at processResult (D:\0html\pug_plugin_test2\node_modules\webpack\lib\NormalModule.js:755:12) at D:\0html\pug_plugin_test2\node_modules\webpack\lib\NormalModule.js:860:5 at D:\0html\pug_plugin_test2\node_modules\loader-runner\lib\LoaderRunner.js:400:11 at D:\0html\pug_plugin_test2\node_modules\loader-runner\lib\LoaderRunner.js:252:18 at context.callback (D:\0html\pug_plugin_test2\node_modules\loader-runner\lib\LoaderRunner.js:124:13) at D:\0html\pug_plugin_test2\node_modules\@webdiscus\pug-loader\src\index.js:270:21 at Object.compile (D:\0html\pug_plugin_test2\node_modules\@webdiscus\pug-loader\src\index.js:256:5) at Object.module.exports (D:\0html\pug_plugin_test2\node_modules\@webdiscus\pug-loader\src\index.js:269:11)

it seems it try to find "pug for extending" in same directory.
if specify directly "extends ../../layouts/default.pug" it works.
instead of it, aliases for "~Images", "~Styles" work properly.

use Windows 10 x64.

Can't resolve the file when using splitChunks

See branch https://github.com/silveoj/pug-plugin-responsive-loader-issue/tree/scss-and-chunks

I can't build if I use

splitChunks: {
  chunks: 'all', // remove it to work
},

I get error on Win and Linux:
Can't resolve the file ../src/assets/img/image.png in ..\src\html\pages\view-2.pug
here:

header
  img(src=require('~Images/image.png'))
  • Also it starts to works SOMETIMES if I remove .browserlistrc
  • I can replace padding-bottom to padding-top and it will work.
  • I can remove random line and it CAN start to work.

I think it's pug-plugin issue because error with require('~Images/image.png')

To run webpack-dev-server I need to remove require('~Images/image.png'), run server and restore require. Now it's work on dev-server.
But there is no chance to build dist files

[question] Separate output path for resources

  1. I might have svg files in src/img folder. But I might also have svg files in src/fonts. I wanna seperate them in build time. src/img svg files to dist/img, src/fonts to dist/fonts. Like this.

  2. If i have folder structure like this "src/img/banners" and if i require these images from "src/img/banners", can i have dist folder structure like this "dist/img/banners"? Or just "dist/img"? Because i can have kind of folder structures in src. Like "src/fonts/OpenSans/..." or "src/img/banners/...". I wanna have dist folder like this "dist/fonts/OpenSans/..." or "dist/img/banners/...".

How to minify inline JS & CSS & Generate Hash?

Hi @webdiscus

  1. I am not able to minify inline JS & CSS.
  2. Can i generate Hash for script & link tags?

Before pug-plugin i used HtmlWebpackPlugin to do the same.

Sample Code:

new HtmlWebpackPlugin({
    template: join(__dirname, 'xyz.pug'),
    filename: 'xyz.html',
    hash: true,
    minify: {
      minifyCSS: true,
      minifyJS: true,
  },
}),
hash: true
// this appends a unique webpack compilation hash
// to all included scripts and CSS files
minify: {
    minifyCSS: true,
    minifyJS: true,
}
// this minified the inline css and js

[question] debug in pug file

Is there any way to debug in pug file? For example when i require an image, i wanna debug it with console.log and i wanna see the results in terminal. But if your plugin's method is "render" or "compile", i cannot see the results in terminal.

[FEATURE REQUEST] Preload support

Hello!

If there are any possibilities how to configure preload for styles or scripts. I found out a plugin, but it requires HtmlWebpackPlugin to be initialized. How can i do it?

TypeScript emitted no output for /src/app/app.ts

Hello,

using this pug-plugin package with TypeScript gives an error. I would like to understand how can TypeScript be used in the pug-plugin package?

new PugPlugin({
		pretty: true, // formatting HTML, useful for development mode
		verbose: true,
		js: {
			// output filename of extracted JS file from source script
			filename: 'js/[name].js',
		},
		css: {
			// output filename of extracted CSS file from source style
			filename: 'css/[name].css',
		},
	}),
			{
				test: /\.pug$/,
				oneOf: [
					// import Pug in JavaScript/TypeScript as template function
					{
						issuer: /\.(js|ts)$/,
						loader: PugPlugin.loader,
						options: {
							method: 'compile',
							esModule: true,
						},
					},
					// render Pug from Webpack entry into static HTML
					{
						loader: PugPlugin.loader,
						options: {
							method: 'compile',
							data: {
								listLinks: links,
							},
							embedFilters: {
								escape: true,
							},
							// compileDebug: true,
						},
					},
				],
			},

ERROR in ./src/app/app.ts
Module build failed (from ./node_modules/ts-loader/index.js):
Error: TypeScript emitted no output for /home/abstract13/Общедоступные/PhpstormProjects/AAtheBestPractics/src/app/app.ts.
at makeSourceMapAndFinish (/home/abstract13/Общедоступные/PhpstormProjects/AAtheBestPractics/node_modules/ts-loader/dist/index.js:52:18)
at successLoader (/home/abstract13/Общедоступные/PhpstormProjects/AAtheBestPractics/node_modules/ts-loader/dist/index.js:39:5)
at Object.loader (/home/abstract13/Общедоступные/PhpstormProjects/AAtheBestPractics/node_modules/ts-loader/dist/index.js:22:5)
@ ./src/pages/index/index.pug 4793:56-157

Thanks

Support Node v12.x

  1. I have nodejs v12.18.3
  2. Run webpack command
  3. Get this error:

Снимок экрана 2022-11-12 в 14 20 44

On node v16.x it’s working fine, but I need 12.x.

My webpack.config.js:


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

module.exports = {
  mode: 'development',
  stats: 'maximal',
  entry: './src/index.ts',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].[contenthash].js',
    clean: true,
  },
  resolve: {
    extensions: ['.ts', '.tsx', '.js'],
  },
  devServer: {
    static: {
      directory: path.join(__dirname, 'dist'),
    },
    hot: true,
    port: 3000,
    historyApiFallback: true,
    compress: true,
  },
  module: {
    rules: [
      {
        test: /\.ts$/,
        include: path.resolve(__dirname, 'src'),
        use: [
          {
            loader: 'ts-loader',
            options: {
              configFile: path.resolve(__dirname, 'tsconfig.json'),
            },
          },
        ],
        exclude: /(node_modules)/,
      },
      {
        test: /\.s[ac]ss$/i,
        use: [
          MiniCssExtractPlugin.loader,
          'css-loader',
          'sass-loader',
        ],
      },
      {
        test: /\.pug$/,
        loader: PugPlugin.loader,
        exclude: /(node_modules)/,
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: 'src/index.html',
    }),
    new MiniCssExtractPlugin({
      filename: '[name].[contenthash].css',
    }),
  ],
};

pretty option seems to be messing around with inline JS

As I mentioned in #56 (comment), the inline JS was not working.

By looking through the process that HTML code being processed, I found that Pretty.format turned <script>I:/ulr-loading/test/config.ts</script> into <script>\n I: /ulr-loading/test / config.ts\n </script>.

newContent = content.replace(sourceFile, source);

This is where the JS code being inserted into HTML, but after prettify, the text used to replace was no longer existed.

Can't resolve url in CSS propertly

The issue with data-url is extracted in separate ticket.

The problem with @font-face in scss file. I have these lines in _variables.scss:

@font-face{
	font-family: 'Conv_Montserrat-Regular';
	src: url('../fonts/Montserrat-Regular.eot');
	src: local('☺'), url('../fonts/Montserrat-Regular.woff') format('woff'), url('../fonts/Montserrat-Regular.ttf') format('truetype'), url('../fonts/Montserrat-Regular.svg') format('svg');
	font-weight: normal;
	font-style: normal;
}
...

Webpack gives away this error:

[pug-plugin] Can't resolve the file ../../../fonts/Montserrat-Regular.eot

How can pug-plugin resolve these urls?

I can resolve these urls with MiniCssExtractPlugin and resolve-url-loader.

I have this webpack.config.js:

let mode='development';
const PugPlugin= require('pug-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const path = require('path');
if (process.env.NODE_ENV === 'production') {
  mode = 'production'
}

console.log(mode + 'mode')

module.exports={
  mode: mode,
  output:{
    filename:'[name].[contenthash].js',
    path:path.resolve(__dirname,'dist'),
    publicPath:'/',
    assetModuleFilename:'assets/[hash][ext][query]',
    clean: true,
  },
  entry:{
    uiforms:'./src/pages/ui-kit/ui-forms/ui-forms.pug',
    uiformsScripts:'./src/pages/ui-kit/ui-forms/ui-kit.js'
  },
  devtool: 'source-map',
  plugins:[
    new PugPlugin({
      modules:[
        PugPlugin.extractCss(),
      ]
    }),
  ],
  module: {
    rules:[
      {
        test: /\.pug$/,
        loader: PugPlugin.loader,
      },
      {
        test: /\.scss$/,
        type:'asset/resource',
        generator:{
          filename:'assets/css/[name].[hash:8].css'
        },
        use:[
          "css-loader",
          "resolve-url-loader",
          {
          loader:"sass-loader",
          options:{
            sourceMap: true,
          },
          }
        ]
      },
      {
        test: /\.(png|svg|jpg|jpeg|gif)$/i,
        type:'asset/resource',
        exclude: path.resolve(__dirname, './src/fonts'),
        generator: {
          filename: '/assets/img/[hash][ext][query]'
        }
      },
      {
        test: /\.(woff|woff2|eot|ttf|otf|svg)$/i,
        type:'asset/resource',
        include: path.resolve(__dirname, './src/fonts'),
        generator: {
          filename: '/assets/fonts/[hash][ext][query]'
        }
      }
    ]
  },
};

[webpack-dev-middleware] HookWebpackError: self is not defined

Hi, very excited about this plugin. Really want this to work 😃

However, I am getting the below error when trying to use it in my project (IN DEV MODE i.e webpack serve)::

[webpack-dev-middleware] HookWebpackError: self is not defined -- inner error -- ReferenceError: self is not defined
Screenshot 2021-12-24 at 1 56 12 AM

My Config is as follow::
(Bare minimum for testing)
Screenshot 2021-12-24 at 1 59 11 AM

I hope you can resolve this ASAP. Let me know if I am missing something.

Thank you!

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.