Closed Rush closed 2 years ago
1) Are you using the HtmlWebpackPlugin in your project? If yes, whether using in PUG external variables, e.g.:
div= htmlWebpackPlugin.options.title
2) Did this bug appear after update to v1.6.3 or is it a new case?
Could you please create a simple repo with the file unsupported-browser.pug
and all other dependencies in this template.
I need the source of unsupported-browser.pug
and webpack.config.js
.
In this case I am using the default function output. I discovered the problematic code is:
link(rel="preload" href=require('assets/fonts/ibm-plex-sans-v7-latin-regular.woff2') as="font" type="font/woff2" crossorigin)
which then goes to the webpack file-loader
This code worked with webdiscus 1.4 but broke with 1.6. I think perhaps the version should have been bumped to 2.x?
Perhaps 1.6 is doing something funky with require
.
the error Cannot read properties of undefined (reading 'undefined')
has not a relation with it the require()
.
If the required resource is not found (e.g. wrong resolved path), it will display some like Can't resolve the file ...
.
To locate the problem I need more information:
HtmlWebpackPlugin
in your project? If yes, are external variables used in the pug template? e.g.:
div= htmlWebpackPlugin.options.title
I have created the test case for require fonts.
index.pug
, where the 'assets/fonts/
is relative path by the the template
html
head
link(rel="preload" href=require('assets/fonts/ibm-plex-sans-v7-latin-regular.woff2') as="font" type="font/woff2" crossorigin)
body
p Hello World!
img(src=require('image.jpeg'))
webpack.config.js
const path = require('path');
const PugPlugin = require('pug-plugin');
module.exports = {
output: {
path: path.join(__dirname, 'public/'),
publicPath: '/',
},
entry: {
index: 'src/index.pug', // the `pug-plugin` is required
},
plugins: [
new PugPlugin() // extract HTML from pug defined in webpack entry and save to separate file
],
module: {
rules: [
{
test: /\.pug$/,
loader: PugPlugin.loader, // `@webdiscus/pug-loader` is already included in PugPlugin
options: {
method: 'render', // export the HTML string, rendered at compile time
},
},
{
test: /\.(png|jpg|jpeg)/,
type: 'asset/resource', // <= must be exact this to handles an image
generator: {
filename: 'assets/images/[name].[hash:8][ext]', // save required image under this filename
},
},
{
test: /\.(eot|ttf|woff|woff2)/,
type: 'asset/resource', // <= must be exact this to handles an font
generator: {
filename: 'assets/fonts/[name][ext]', // save required font under this filename
},
},
],
},
};
What is difference by usage require()
to compare with your case? I think the problem is elsewhere.
The file-loader
is deprecated for Webpack 5, link to file-loader doc.
For Webpack 5 should be used assets module.
From ver 1.6 I have "improved" the resolving of required resources. The "interpolation" of paths was replaced with "evaluation" of once. Now is possible use a variable in require('path/to/images/${myImage}')
at compile time. Added resolving of paths from tsconfig.js
.
Thank you for the investigation. Unfortunately I can't use the assets modules as it's not as flexible when it comes to the output paths.
I am trying to make a reproducible small test case, which is not that easy. :)
I suspect method: "compile"
is for some reason not being used.
https://github.com/Rush/webdiscus-issue-9-repro
I also suspect file-loader has nothing to do with it. It's an issue purely in pug-loader
. Please check out my repo and follow README.
In regards to file-loader
I need more granularity as for where to output the files. I believe webpack doesn't expose such granular options for assets.
const fileLoader = {
loader: 'file-loader',
options: {
esModule: false,
outputPath: '../public-built',
context: path.resolve(__dirname),
publicPath: '/',
name: '[hash].[ext][query]'
},
};
Just wondering if you were able to run my repo and reproduce?
Just wondering if you were able to run my repo and reproduce?
Sorry, I am just very busy, I try your repo tomorrow. Thank you for the repo!
Sorry, I am just very busy,
Good luck with whatever keeps you occupied! :)
I try your repo tomorrow.
Thanks!
yes, I can reproduce the issue and I found the place in the code. I will fix it. Thank you for very important issue report.
The problem is by usage variables in template.
At pre compile time the usage of variables like opts.prop1.prop2
or opts[prop1]
has issue because they are not defined. Only in runtime will be passed variables available. This is the BUG :-/
Anywhere in PUG use ?.
notation (node >= 14) by each variable with a property. Use this only in JS context, not in PUG context, e.g.:
you use already the correct chained properties with ?.
:
- const osName = parsedUA?.os?.name; // RIGHT!
In your template unsupported-browser.pug
you should change:
this
span.browser-icon
+svgIcon(browserIcons[recommendedBrowser])
to
span.browser-icon
- const icons = browserIcons?.[recommendedBrowser];
+svgIcon(icons)
and in mixin self use properties with ?.
:
mixin svgIcon(iconData, currentColor = 'currentColor')
- const [width, height, _, __, paths] = iconData?.icon || [];
...
I understand, this is not comfortable and tricked, sorry, but currently this works with this limitation.
P.S. I try to fix it, but it is not easy and not quick.
The workarounds seem really messy. I will stick with the old version.
Probably variable
existence check should only be applied to html
render mode.
Hello @Rush,
in the new version 1.7.0
I have fixed the issue undefined variable
by usage the compile
method.
This was a compromise for compile
method:
?.
-VS- ?.
But the same limitation has original pug-loader. The problem is with webpack require. My solution in v1.6. was a mega useful "killer-feature", no other pug-loader does this.
Do you can please try to test the version 1.7.0?
Yes thank you. This is now solved. There is another issue for which I'll open a different ticket.
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.