Minimizing Individual Assets with Webpack - wordpress

I would like to optimize a wordpress website with webpack. The application is not a single page app, and each page requires their own styles, scripts, and images in the head. I would like to use webpack to minimize css, js, and images in place. I don't need a single bundle file.
In a folder with three css files, I would like to iterate through each of the files and minimize them.
css/
page.css ---> page.css(minimized)
header.css ---> header.css(minimized)
footer.css ---> footer.css(minimized)
I would like to do the same with js files and use an image optimizer for jpgs, png, ect. Can this be done with webpack? If so, how could this be done? I have read about multiple entry points but that does not seem to be what I need. Thanks!

No, multiple entry points will still only give one output. What you could do, is write a wrapping script which wraps your webpack.config.js and having the entry config variable set to be dynamic.
Pseudo-code:
import glob from 'glob'
import webpack from 'webpack'
import config from './webpack.config'
const files = glob.glob('**/my-entry-file.js');
files.forEach((file) => {
config.entry = file;
webpack(config);
});

Related

How to import global SASS with Gatsby

I'm trying to have a global .scss file that gets imported into all pages.
I have the following project structure
/src
/pages
index.js
index.module.scss
/templates
/restaurants
/hungry
hungry.js
hungry.module.scss
/styles
typography.scss
variables.scss
/package.json
gatsby-plugin-sass
node-sass
/fonts
...
I tried passing options via gatsby-plugin-sass and also exposing global styles with gatsby-browser.js using this link: Include sass in gatsby globally but no luck.
My typography.scss file
typography.scss
Passing options to gatsby-config.js
My gatsby-config.js file
Error message
Exposing global styles with gatsby-browser.js
gatsby-browser.js
hungry.module.scss
Error message
I've also tried reading the documentation:
https://www.gatsbyjs.com/docs/how-to/styling/global-css/
I'm new to Gatsby and completely out of ideas at this point. I appreciate any help.
Thank you.
The approach of using gatsby-browser.js is perfectly valid and it should work, in addition, your paths look correct to me.
Regarding your typography.scss, it clearly seems that the relative paths are not working, try adding/removing relativity using ../../path/to/fonts or ./path/to/fonts.
Another approach that may work for you, is removing the options from your gatsby-plugin-sass plugin and import it as .scss import to the desired file.
Let's say that you fix the issue with the relative paths in your typography.scss (first step). Once done, your .subtitle class file, you can simply:
#import '../../../styles/fonts/typography.scss' use it. Something like:
#import '../../../styles/fonts/typography.scss
.subtitle{
font-family: $font-medium;
}
So, summarizing. The first step should be to fix the relative font importation and then, import that file directly in the needed .scss files.
Once you comment the manifest plugin (which request a missing asset in the GitHub), it loads the fonts correctly:
Notice the K, quite unique in this typography.
Gatsby uses the path inside /pages folder to build URLs of the pages. You were putting the templates folder inside the /pages folder, causing some weird behavior. Move it outside to fix the issue.

What is the current best way to handle a CSS entry file in Webpack?

This should be simple, but I'm kind of stumped over how complex it's turning out to be.
What I would like to do is have a simple reference to my CSS in my Webpack config's entry list:
entry: {
'app.js': './src/app/index.js',
'app.css': './src/app/app.css',
},
output: {
filename: 'web/[name]',
},
app.css can import other files through the standard CSS syntax: #import url('./morestuff.css'); I would like these to be inlined as Webpack does for JS imports.
I would like that to be exported as normal. For the config above that means outputting it into 'dist/web/app.css'.
I don't want:
To import/require CSS in my JS
To have it output a JS file that either includes the CSS as a string, or dynamically loads the CSS file itself
To do any HTML rewriting
What I've tried/considered:
Using css-loader outputs JS instead of CSS.
Using css-loader along with mini-css-extract-plugin will import/concat the files as I'd like, but the actual entrypoint output file is JS, and the CSS file it makes is in the wrong folder and renamed to app.css.css. If I try mini-css-extract-plugin without css-loader then it can't handle # characters (I think it's trying to load the file as JS.)
Using the sequence of loaders ['file-loader', 'extract-loader', 'css-loader'] as indicated in the extract-loader documentation, but it behaves as above (except the CSS is output with a hashed filename.)
Lots of old SO questions refer to extract-text-webpack-plugin, but that is now an archived project.
style-loader is about HTML rewriting, not what I want.
Now this may not be the "proper" way to handle CSS in Webpack, which does seem to be based on importing everything from your JS, but it's surely a common enough pattern. Any ideas?

Access the content of css files with Webpacker

Using Webpacker I can load css files and they get output in the stylesheet pack files, but sometimes I'd like to access the CSS in these files from within javascript for use say in a WYSIWYG editor's config (specifying some extra styles for the IFRAME). The other option is to be able to access the public path of a css file loaded in like so:
import froala_style from '../../../css/froala.css'
My suspicion is that it's to do with the css loader that comes with Webpacker. Its job is to load the css and compile it out to a seperate file. I think that one can't have two css loaders at the same time? Could the answer be to apply filters to a custom loader so that it takes effect on only the file I'm wanting to load in as text or the path?
One can override the existing loaders for a particular import like so:
import froala_style from '!css-loader!../../../css/froala.css'
Prepending the ! overrides existing loaders allowing us to specify our own. In this example one can call froala_style.toString() to receive the contents of the CSS file.
For reference: https://webpack.js.org/concepts/loaders/#inline

Structuring CSS files in React with Webpack

I'd like to get a better understanding on how I can structure my css files. My folder structure is like so:
-app
|-src
||-components
|||-app.js
||-styles
|||-styles.scss
|-webpack.config
So I have one stylesheet that will be imported into app.js and cascade to my other components. But as I'm creating more components, my stylesheet is getting pretty long. Is it best practice to have stylesheets per component? Also, I'm using webpack to compile and extract my stylesheet into a css file to import into index.html file. If I have multiple files, I'm assuming webpack will compile all of them into one css file?
When your application scales it becomes hard to maintain a huge CSS file , not to mention class name collision , so files separation its generally a good idea.
I prefer CSS file per page , kind of up to you how to separate them.
As for webpack loaders , think of it as a pipe , the pipe sets rule that every file that ends with .css comes in and bundled, so yea , it will bundle multiple css files.

how to stop meteor from auto merging my css files?

I have 2 html files linked to each other and have different css files for each of them, but meteor merges them automatically.
How do I stop this?
You cannot. Meteor merges CSS to optimize its network delivery.
If you want to choose the order your stylesheets have in the merged CSS you may need to :
- Use a language as SASS, LESS or Stylus which allow to generate css so you could do #import 'imports/ui/yourstylesheet.scss' to #import files in the order you want. Note that if you choose to use a language as SASS or LESS you need to put your sass/less files that you want to import into /imports so you manually import them (puting files anywhere else than in /imports makes your files automatically imported). And import these files via a SASS/LESS/stylus file in the /client folder.
OR
- Put your css in /client folder and understand the Meteor's rules to choose in which order your css get loaded :
The JavaScript and CSS files in an application are loaded according to
these rules:
Files in subdirectories are loaded before files in parent directories,
so that files in the deepest subdirectory are loaded first, and files
in the root directory are loaded last.
Within a directory, files are loaded in alphabetical order by
filename.
After sorting as described above, all files under directories named
lib are moved before everything else (preserving their order).
Finally, all files that match main.* are moved after everything else
(preserving their order).
OR
- You put your .css in the /imports directory (so Meteor doesn't import them automatically so you can choose in which order you load css files). And you import your css via a .js (javascript) file put into /client (as files into /client are loaded on your browser). In the .js file you do import '/imports/ui/mystylesheet.css' to import your css.
The cons of the three methods are respectively :
- You have to learn a language if you don't know any of these languages : stylus less or sass.
- Relying on complex rules to choose the order your css get loaded is probably not maintainable and oblige you to have specific names for your css
- css files loaded within a .js file are put in a <style> tag inside the DOM instead of being loaded in a separate .css file (which is not recommended). Besides the css loaded this way doesn't use the toolchain offered by Meteor plugins (compression of CSS, add pre-vendor prefixed to maximize the compatibility of your css and whatever the plugin you have offers you).
You can carefully change the order of load. Such as to make one override the other.
For example consider the following file structure
|-client
|-imports
|-ui
|-page1
|-page1.html
|-page1.js
|-page1.css
|-page2
|-page2.html
|-page2.js
|-page3.css
Here, page1.js will import page1.css and this css will be applied to the template in page1.html
Similarly, page2.js can import page2.css and the same will be applied when the page2.html is rendered.
You can add your css class to the template when calling the route if you are using the iron router.
Router.route('/addMemberProfile',{
onBeforeAction: function () {
$('body').addClass('your required class for this template');
this.next();
},

Resources