Webpack - how to do simple css minification and concatenation - css

Webpack is powerful, sure, but it's confusing and complicated for beginners (like I am). Doesn't help that recently they moved to 2.2 so a lot of documentation I see is for the older version which adds to this difficulty.
All I want to do is this:
I have an app.css and a main.css which I want to minify and bundle into one (say app.min.css) and copy to my output directory - what's the easiest way?
I am manually linking it in my html file so I don't need webpack to write out a URL for me or anything. I may do a lot more fancy stuff around modularization latter, but for now I'd like to get my basic setup up and running. I do have my webpack.config.js running on my entry index.js file and that all seems fine.
What's the simplest way to do it? What am I missing? I'm getting lost in this loader and that loader (css-loader, raw-loader, style-loader...) and errors that are cryptic and take time to figure out. It surprises me that for a tool so powerful you'd imagine there are simpler ways to do basic things like this...
Thank you for the help

This is actually very simple, and the docs do a good job of explaining it.
First you need to make sure you have a css loader configured so Webpack knows what to do with css files. Then by using the ExtractTextPlugin you basically bundle what you specify into a separate file.
The entry block can take multiple files, so you could modify it like so. OR you could require/import them at the top of index.js.
entry: {
bundle: "./index.js",
main: "./main.css",
app: "./app.css"
}

Related

I can't use css styles on my navbar (using sass)

I'm starting to learn by my own and I tried for the first time to use sass in order to get more clean my code, having everything on sections. So the problem is when I try to give some styles to the navbar, I don't know why when I write code it doesn't apply. Maybe is because I'm not linking correctly or just using bad the sass compiler.
The best option to help me is take a look into my repository where I started to build this project to practice. I really hope could help me because I want to create differents sections like navbar, body, articles, footer using sass and give them styles.
https://github.com/Shylex96/test-portfolio
Edit: After a long search about this issue I see there is a problem with "use" and I have to change rules or something like that, but still don't know.
Replace #use with #import in your scss files.
Try updating your \util\style.scss like below:
#import '../globals/';
#import '../components/';
Save and compile them then copy the resulting css files to dist folder if they weren't copied automatically.
Update the stylesheet link in your index.html file to:
<link rel="stylesheet" type="text/css" href="dist/style.css">
It should be "dist/style.css" not "/dist/style.css"
FINALLY!! I solved it and I'm going to commit what helps me if someone have same issues..
I had to reinstall node.js, install gulp, and change "about_Execution_Policies" from windows.. when I did, I could finally install gulp correctly and then I install again sass. Of course, I just converted all the changes that people told me about into the first ones I had.
I created a new file called gulpfie.js and two more files: .gitignore and .gitattributes
So, If someone need it, can check the changes here: https://github.com/Shylex96/test-portfolio

CSS modules and rollup - generating separate CSS files ("themes") with same hashes

I'm using CSS Modules (Sass) with rollup on a component library project, which is working well. Each component ends up with a dist folder containing a single JS bundle file, and a corresponding CSS file with the scoped CSS classes so consumers of the component don't have to worry about CSS class name conflicts. All they do is include the JS bundle and the CSS file and everything is great. Yay CSS Modules.
The problem I'm now facing is that some components really need separate "themes" - ideally, separate CSS files, one per theme. So consumers can continue as they've been doing: including the JS bundle, but now choosing which CSS file to include to pick a theme.
I'm not sure how to get this going with CSS modules & rollup, and whether this is even the sort of approach others are taking. From what I can see, rollup always handles bundling things together, whereas I want separate CSS files, all of which get their classes renamed identically during the build phase. That way, if within my JS I refer to styles.myclass, if myclass had gotten renamed to scoped-myclass by CSS modules for the original CSS file, for a second CSS file it would also get the same name.
This would keep consumption of the component extremely simple - just a matter of including a different CSS file.
Any suggestions?
Awfully late, but let me answer this 3 years on. So what I ended up doing was totally detaching the CSS generation step from rollup and relying on the Sass CLI to handle that portion of the build process. It felt a bit klutzy, but I remember it wasn't awfully hard to do and solved the problem I outlined above. I don't believe there was a plain rollup solution at the time, nor do I think there's one today.
However... in my case the whole approach was kinda mistaken. This certainly won't be everyone's scenario, but let me spell it all out because hey it may be useful and it definitely wasn't obvious to me at the time.
This was for an in-house shared component library, where each component and its corresponding CSS was a separate npm package stored in our Artifactory. When it grew, plenty of internal references popped up, e.g. multiple components would reference the Button component, and over time they'd reference different versions of the Buttons component - each of which needed its own properly scoped CSS, unique to that package-version.
So what I found was that by doing it this way - having the CSS generated as part of the npm package dist files - I had to write an additional layer for the consumer applications that would parse their node_modules/ folder for our own internal components and combine all the different CSS files, such as the multiple versions of buttons. e.g. the main application would directly import buttons v1.0.0 in its package.json file, but the Dialog component (also included in the package.json) could include buttons 2.0.0 as its own dependency. For every version of the package, there was a uniquely scoped version of the CSS - so the consuming application HAD to include every version otherwise the styling would be borked.
So all in all, it ended up being way more complex that I wanted. I thought I could make it easier & better with the separate generated themed CSS files as part of the package dist, but it didn't end up that way. If I could revisit that project today, I'd re-examine a solution used by Material UI and others which I kinda poo-poo'd at the time: automatic injection of the CSS into the page by the component JS, rather than generating standalone CSS files which required extra work by the consumer applications to gather up and add to the final webpage. Frankly, now I regard it as the "least crap". There are definite downsides to the injection approach (extra work done on every page render for everyone! Yikes!), but there's no doubt in my mind it hugely simplifies the job of the consumer applications. It's a balancing act, but in 20-20 hindsight I'd lean towards the injection approach. With that, scoping & theming is a different and much simpler problem.
If I got you right, consider looking at SCSS plugin: rollup-plugin-scss. It captures all spare .css files imported in the components, and then processes them through underlying node-sass. The catch is, it seems like you can write a custom callback function that'd handle your CSSs differently based on conditions you throw in.
Based on the example from the plugin's page:
import scss from 'rollup-plugin-scss'
...
export default {
input: 'src/index.tsx',
output: [...],
plugins: [
...
output: function (styles, styleNodes) {
// replace this with conditioned outputs as needed:
writeFileSync('bundle1.css', styles)
writeFileSync('bundle2.css', styles)
},
]
}

SCSS: how to actually include the contents of a #include?

I'm moving from Grunt to Gulp and noticed that gulp-sass does not include the contents of files referenced by #import "reset.css" statements. Instead, it normalizes the url reference, as #import url(reset.css). My intention is to have a single CSS reference on my index.html, that would be the concatenation of my CSS dependencies.
It's a simple read-file-and-output-contents operation, but I bet this is already implemented and I just don't know where to find it -- I'm still new on this ecosystem and would not like to spend time reinventing the wheel.
EDIT: the selected answer for this related question uses gulp-minify-css, instead of gulp-sass. Exchanging them could be a short-term solution, but I'd prefer to avoid my new build system to rely on unstable plugins. Moreover, I actually have plans to use scss, so I'd be back to having to deal with gulp-sass again. Thanks for the suggestion, though.
#import should actually include the contents of the file, not make a reference to it. Sounds like maybe the transpiling of the SCSS to CSS isn't working properly.

ReactJS Sass, without webpack

Preface: I can't use webpack. It breaks too much of my AWS stuff and I'm too frustrated finding ever more problems. I wish I could use the convenience of webpack but I stopped using it and AWS now works. Now its all watchify and babel.
Can I use CSS/Sass without using Webpack (as mentioned) or import CSS Modules, PostCSS etc?
Issue: I can link a css file, pass in the classes to my component and it all renders out proper div / class syntax, but (I assume) the virtual DOM just doesnt load it. How can I get around this?
[Edited as I got a down-vote, just to be safe.]
You can just run gulp, and gulp-sass. That compiles a .css file and you can just manually include that file in the <head> of your file. Try there are dozens of tutorials on Google like this one

How do I build my RactiveJS-based library into one JS file?

(Related question: what's the difference between rv.js and r.js?)
I've got a series of RactiveJS-based components, each in their own module. I use the rv.js loader (linked above) mentioned on the Ractive site. I love it, but what I want to do is use that (or something similar) to build to one JS file that will work even in non-AMD/RequireJS apps. I've looked at Almond, but it seems to want to use r.js (rather than rv.js), and I'm not sure what the difference is or what changes I'd need to make.
Bonus points: is there a way to run all of this in Gulp? I'm one of those people who cringes when he has to use the command line, so please talk slowly and forgive my ignorance:)
A bit late to answer, apologies for that.
rv.js is a RequireJS plugin that loads ractive components as if they are javascript modules
r.js is the RequireJS optimizer, used to bundle together all files and minify (exactly your use-case)
RequireJS is quite large in size, and you don't want it bundled with your application js during a build.
Enter almond.js. It mimics the module resolution of RequireJS, but doesn't have the code to handle actual loading of the files over the network. The result is a smaller file size.
So, your workflow would be:
You use RequireJS during development
Use rv.js, as you are already, to load ractive components
When it's time to build, you use r.js to build
And ensure almond.js replaces RequireJS in the final built js file
Now, I use grunt, and there is a plugin for that: grunt-contrib-requirejs
For gulp, I suggest gulp-requirejs-optimize
It has options to replace requirejs with almond during the build process if you look at the documentation on that page.
Hope that helps.

Resources