how to stop meteor from auto merging my css files? - css

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();
},

Related

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

Minimizing Individual Assets with Webpack

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);
});

how to prevent a sass build of each page file when just changing a common scss file

I have a _common.scss file which I import to various page.scss files:
page.scss:
#import "common";
#page {
...
}
_common.scss:
#import "partials/all";
#import "components/all";
...
But the problem is, since all my pages import _common.scss, the way I have things structured, if I make any changes inside _common.scss (or any of the files it imports), sass has to rebuild all the page css files. But if I just make _common.scss its own file and call it with a <link> tag (<link href="common.css">), then the page.scss file has errors, because it is trying to use variables and mixins defined in _common.scss and its imports.
Is it possible to structure my project so that the page.scss files can use all the mixins and variables in _common, but so that sass doesn't have to rebuild each page.css file each time I make a change to the common file? i.e. - make it so that sass only builds the common file when a change is made in common, and only builds the page file when a change is made in page?
I would say it is not possible, since the aim is to have one css for each page at the end. This said it HAS to be rebuild if something is changed in common.

How to use less mixins in meteor with #import and not get multiple definitions

in my current meteor app I have split the less declarations in one file per Controller (iron-router). I have a common file - where I have defined some mixins - which is imported in each less file. My problem is that the classes are imported multiple times in each route.
The file structure is:
mixins.import.less (new names, reference http://docs.meteor.com/#less)
.grid-container {
// something
}
postList.less
#import (once) url('/client/views/mixins.import.less');
postDetail.less
#import (once) url('/client/views/mixins.import.less');
Then in the Chrome inspector I found duplicated everything I have written in mixins.import.less. Is it possible to avoid this double import?
Assuming you want the mixin code at least once in your compiled css (perhaps not, some just want them as mixins, not classes in the css code), then make sure you set it to bring in the "mixins.import.less" file all by itself. Then for all your dependent files using it, do this:
"postList.less", "postDetail.less", etc.
#import (reference) url('/client/views/mixins.import.less');
The (reference) option has been available since LESS 1.5, and will only bring in the code for reference purposes to be used in the LESS file, but will not itself output any css.
Meteor bundles css and js/html resources all together as a single css and a single js file in production.
In development, they are individually served, but still at the same time, during initial page load (first ever request to server)
For less files, a css file is created for each (during development). Since you are importing, what Meteor basically does is create each corresponding css file that each contain the import individually.
And when they are served to the client all together (take a look at the head section of the generated html), you end up with that many copies of the imported style declarations.
Therefore, due to this bundling behaviour of Meteor, you can just keep one copy of your less mixins in a less file, and not import at all, since they are going to be served to the client in CSS form anyway.
Also, it is possible to trick Meteor into bypassing as described in the unofficial meteor faq:
... you can change the extension of the less files to be imported from .less to .lessimport and then change your #import file.less to #import file.lessimport. This will prevent the less compiler from automatically trying to compile all your import files independently, yet still let you use them ...

Bootstrap 3 - confused about including .less files into my app

I'm wondering if its okay to import all of bootstrap.less into my own .less file and then overriding anything I wish to change within that one file. My own .less file, style.less, outputs everything into a single style sheet, and I'm NOT including the compiled bootstrap.css file, only the JS files.
bootstrap // folder with all bootstrap less files.
style.less // imports bootstrap folder, and outputs style.css in root directory
Are there any drawbacks to doing it like this, or should I also be including the compiled bootstrap.css file?
Yes, do, you immediately gain access to all the mix-ins and variables. I'd say this is the most powerful way to use bootstrap.
As you're suggesting just import bootstrap.less at the head of your less file. I import any other mixin libraries, like lesshat, after that.
The problem is that you end up with one monolithic CSS file which is a nightmare to debug, but less.js 1.50 introduces source maps which is invaluable when using this methodology: http://robdodson.me/blog/2012/12/28/debug-less-with-chrome-developer-tools/
A faff to set up but saves a lot of head scratching.

Resources