Closed MarcelRobitaille closed 2 years ago
Hi @MarcelRobitaille,
to inline CSS in Pug use include
:
style: include ../css/styles.css
You don't need to configure Webpack for this.
Using type: 'asset/inline'
Pug plugin can inline images like SVG, PNG, JPG, etc., but to inline CSS must be used native Pug feature.
Hi @webdiscus. Thanks for the response. I'm aware of pug's include
keyword. However, this includes the file totally raw exactly as it is in src
. I would like to minify the styles using webpack. That's why I am trying to use require()
with asset/inline
. Is there really no way to do this? Thanks
Yes, it makes sense. I note this feature request in TODO for next release.
@MarcelRobitaille,
Pug plugin has full control over all required assets in Pug and the inlining CSS must be implemented in the plugin. It is in development.
@webdiscus That is great! Thank you so much
@MarcelRobitaille
please update to v4.4.0
.
For inline CSS and load CSS as file use in Webpack config the oneOf
:
{
test: /\.(css|sass|scss)$/,
oneOf: [
// inline styles in HTML
{
resourceQuery: /^\?raw/u, // match exact first URL query `?raw`
type: 'asset/source',
use: ['css-loader', 'sass-loader'],
},
// load styles as file
{
use: ['css-loader', 'sass-loader'],
},
],
},
Then you can use both:
//- load CSS as file
link(href=require('./main.scss') rel='stylesheet')
//- inline CSS from styles.scss
style=require('./styles.scss?raw')
Note
The IDEA (JetBrains) don't understand the
style !{require('./styles.css?raw')}
syntax. I use Escaped String Interpolation:style=require('./styles.scss?raw')
w/o linter error in my IDE.
Here is the test case for inline CSS with postcss plugin cssnano
.
The inlined CSS support the sourceMaps. If in Webpack config is defined devtool: 'inline-source-map'
then source map will be inlined too and it works in browser fine.
devtool: 'source-map'
? To inline map like inline-source-map
or ignore the map, because for inlined CSS not exists an original CSS file?P.S. thanks for donate :-)
@webdiscus Thank you so much! :rocket: I will try it now.
what should be with devtool: 'source-map'? To inline map like inline-source-map or ignore the map, because for inlined CSS not exists an original CSS file?
I am not sure the best way to handle this to be honest. Sorry
P.S. thanks for donate :-)
No prob. I figure I bugged you enough that I should support you somehow. I'm not sure how long I can afford to stay a patron though.
I just tried 4.4.0. It seems like it's not handling url()
in the CSS anymore.
ERROR in [entry] [initial]
[pug-plugin] Can't resolve the file ../svg/background-tile.svg in /home/marcel/code/biography-site/src/css/styles.css?raw
/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 ../svg/background-tile.svg in /home/marcel/code/biography-site/src/css/styles.css?raw
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:309:5)
at /home/marcel/code/biography-site/src/css/styles.css:5:37
at Script.runInContext (node:vm:141:12)
at PugPlugin.renderModule (/home/marcel/code/biography-site/node_modules/pug-plugin/src/index.js:755:33)
at PugPlugin.renderManifest (/home/marcel/code/biography-site/node_modules/pug-plugin/src/index.js:683: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)
.foo {
background-image: url(../svg/background-tile.svg);
}
If I remove that line, it's working perfectly!
@MarcelRobitaille
I will fix it.
P.S. For me, the money does not play any role. I am financially independent. For a private user, a one-time donation is enough. I see it as an acknowledgment of my work that the plugin is really useful. You can cancel a patron. I'm grateful for one donation.
@MarcelRobitaille
to implement support of URL in inline CSS using asset/source
is very complex, because Webpack for asset/source
type don't analyse/parse the source and don't resolve a resource in CSS. The asset/source
exports the source code of the asset, e.g. for text files. Webpack simple inject content of file. This type is not suitable for inline CSS.
I must implement the resolving of resources in CSS self. It will take a while.
As alternative syntax for inline CSS I can suggest following:
//- load CSS as file
link(href=require('./styles.scss') rel='stylesheet')
//- inline CSS from styles.scss link(href=require('./styles.scss?inline') rel='stylesheet')
Then the `link` tag will be replaced with `<style>... inline CSS content ...</style>`.
- variant 2
```pug
//- load CSS as file
link(href=require('./styles.scss') rel='stylesheet')
//- inline CSS from styles.scss
style=require('./styles.scss?inline')
For both variants, the Webpack config still be unchanged, also w/o a type:
{
test: /\.(css|sass|scss)$/,
use: ['css-loader', 'sass-loader'],
},
Variant 2 can be implemented faster. I will implement this variant.
Note: for both variants the URL query ?inline
will be hard & fix coded. It will be as marker to inline the file.
@webdiscus Thanks for the updates. I didn't expect making url()
work would be so complicated. So, if I understand correctly, the workaround is to link the stylesheet in the normal way (not inline)? I assume this helps webpack recognize the imports somehow? Is it possible for this to be commented so the full stylesheet doesn't actually load or something like that?
For asset/source
type Webpack inject a source without processing and urls will be not resolved in Webpack.
To inline CSS with supports url(), the style file must be processed (parsed and resolved all URLs) via Webpack as javascript/auto
type. Then Webpack call special hooks for each asset (image, font, etc) resolved in url(). In this hooks I can resolve output asset files. Well, it is complex process, but I know wath to do. I'm in process... ;-)
Can I just put the css file as an entry in webpack without linking it to my HTML?
Can I just put the css file as an entry in webpack without linking it to my HTML?
Yes, of cause. The Pug plugin can extract CSS from a style (css, scss, etc) defined in Webpack entry into separate file without linking to a Pug/HTML.
Webpack config:
module.exports = {
output: {
path: path.join(__dirname, 'dist/'),
},
entry: {
styles: './src/assets/main.scss', // => dist/asset/css/styles.css
},
plugins: [
new PugPlugin({
// extract CSS from Pug or from Webpack entry
extractCss: {
filename: 'asset/css/[name].css' , // output CSS filename
//filename: 'asset/css/[name].[contenthash:8].css' , // output CSS hashed filename
},
}),
],
module: {
rules: [
{
test: /\.(css|sass|scss)$/,
use: [ 'css-loader', 'sass-loader'],
},
],
},
};
Note
An additional plugin and loader, such as
mini-css-extract-plugin
, is not required.
To be clear, my question was if adding the CSS file as another entry in webpack would satisfy the first line of variant 1 and variant 2 from here.
I have just tried this, and I am getting the same error. I also tried variant 2 exactly as you have it. Neither of these variants has been implemented yet, right?
To be clear, my question was if adding the CSS file as another entry in webpack would satisfy the first line of variant 1 and variant 2 from here.
I have just tried this, and I am getting the same error. I also tried variant 2 exactly as you have it. Neither of these variants has been implemented yet, right?
All my variants were implementation suggestions. It will be implemented. It's not ready yet.
See my comment above:
I'm in process... ;-)
Yes ok that was what I thought. I just wanted to see what would happen
@MarcelRobitaille
update please to v4.5.0
. In this version is implemented the variant 2.
To inline CSS use the ?inline
query:
//- load CSS as file
link(href=require('./styles.scss') rel='stylesheet')
//- inline CSS from styles.scss
style=require('./styles.scss?inline')
Webpack config rule for styles:
{
test: /\.(css|sass|scss)$/,
use: ['css-loader', 'sass-loader'],
},
@webdiscus It's working perfectly! Thank you so much.
//- load CSS as file link(href=require('./styles.scss') rel='stylesheet') //- inline CSS from styles.scss style=require('./styles.scss?inline')
I totally misunderstood this. I thought you were saying I needed to have both tags in order for the inline minification and linking to work. That lead to the confusion in later comments. Sorry about that.
@MarcelRobitaille
I wanted to demonstrate both usage cases in one example. It would be correct to demonstrate:
Use case load CSS as file
link(href=require('./styles-one.scss') rel='stylesheet')
Use case inline CSS
style=require('./styles-two.scss?inline')
Both use cases are independent of each other.
@MarcelRobitaille
is everything working? Can be closed the issue?
Working beautifully. Thank you :heart:
I am trying to inline my critical CSS for a faster initial load.
I tried the following pug code:
And in my webpack config, I put:
But this throws the following error:
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 secondentry
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.My source for
type: 'asset/source'
: https://webpack.js.org/guides/asset-modules/Is there a way to achieve this?