How to generate different CSS bundle with Webpack 5 - css

I have a React project with webpack (own configuration), from which I need to generate different packages with different styles. It would always be the same application, only in each package it generates, it would need a particular css file to end up in the package.
For example, in the repository I would have different css files:
- src
- index.js
- index.html
- themes
- theme1
theme1.css
- theme2
theme2.css
- theme3
theme3.css
and when I build it should look like this: (in "build" folder)
- build
index.html
main.css // with the styles of theme2, for example
bundle.js
I don't know how to do this with webpack or which plugin, hope you help me.
Thanks

You can get multiple separate CSS by adding multiple entries in your configuration.
Example:
webpack.config.js
module.exports = {
entry: {
main: "./path/to/your_main.js",
"css-theme-1": "./path/to/your/theme.css",
"css-theme-2": "./path/to/your/another-theme.css",
}
}
Also, you can build it into a folder by configuring filename properties in mini-css-extract-plugin.
Further reading:
Webpack Code Splitting

Related

Angular material: include pre-built theme

I wanted to include prebuilt theme for angular app. I included below line in app.component.css.
#import "../../node_modules/#angular/material/prebuilt-themes/indigo-pink.css";
I was surprised it didn't apply the theme to my app. Then from docs I inferred I should include, now it works but I am curious why?
#import "#angular/material/prebuilt-themes/indigo-pink.css";
Inside common stylesheet, style.css not app.component.css! and the path (../../node_modules/#angular/material/prebuilt-themes/indigo-pink.css) makes more sense than "~#angular/material/prebuilt-themes/indigo-pink.css"
I have following questions,
1.What does it needs import only in style.css an why not inside appcomponent.css?
2.Though the path ~#angular/material/prebuilt-themes/indigo-pink.cs leads to nothing, how is the angular-material could pick the theme?
3.What does '~' mean in the above path?
To give more info, I have included project structure
All the imports here are referenced relatively. It can be a hassle to remember how many folders to jump into and out of.
If you move your files around, you'll have to update all your import paths.
Let's look at how we can reference imports absolutely so that TypeScript always looks at the root /src folder when finding items.
Our goal for this will be to reference things like so:
import { HeaderComponent } from '#app/components/header/header.component';
import { FooterComponent } from '#app/components/footer/footer.component';
import { GifService } from '#app/core/services/gif.service';
This is similar to how Angular imports are referenced using #angular like #angular/core or #angular/router.
Setting Up Absolute Paths
Since TypeScript is what is in charge of transpiling our Angular apps, we'll make sure to configure our paths in tsconfig.json.
In the tsconfig.json, we'll do two things by using two of the compiler options:
baseUrl: Set the base folder as /src
paths: Tell TypeScript to look for #app in the /src/app folder
baseUrl will be the base directory that is used to resolve non-relative module names. paths is an array of mapping entries for module names to locations relative to the baseUrl.
Here's the original tsconfig.json that comes with a new Angular CLI install. We'll add our two lines to compilerOptions.
{
"compileOnSave": false,
"compilerOptions": {
...
"baseUrl": "src",
"paths": {
"#app/*": ["app/*"]
}
}
}
With that in our tsconfig.json, we can now reference items absolutely!
import { HeaderComponent } from '#app/components/header/header.component';
import { FooterComponent } from '#app/components/footer/footer.component';
import { GifService } from '#app/core/services/gif.service';
This is great because we can now move our files around and not have to worry about updating paths everywhere.
based on this:
/ - Site root
~/ - Root directory of the application
this can be useful too;

Build additional CSS file in angular build

Background
#angular-builders/custom-webpack allows us to customize the webpack config of angular build, tutorial here. I am using it to build the additional scripts for web extension (Chrome/Firefox).
Here is the extra.webpack.config.js that I have included in angular.json
const { resolve } = require('path');
const scriptsDir = __dirname;
module.exports = {
entry: {
"background-script": resolve(scriptsDir, 'background-script/boot.ts'),
"fill-manager": [resolve(scriptsDir, 'fill-manager/boot.ts')],
"site-bridge": resolve(scriptsDir, 'site-bridge/boot.ts')
}
};
As expected it outputs background-script.js, fill-manager.js and site-bridge.js alongside angular build artifacts. As this webpack config is merged with the angular's webpack config, we can control all the optimizations, hashing, source maps etc from a single angular.json file.
Problem
I also want to bundle additional css files that would be used with extension scripts and be controlled by angular build.
I might be able to add specific rules, loaders etc to extra.webpack.config.js but I do not want to deal with postcss, autoprefixer and sass loaders etc as its already being done inside angular.
Just like script files, simply adding css entry inside extra.webpack.config.js does not produce css file i.e.
module.exports = {
entry: {
...
"fill-manager": [resolve(scriptsDir, 'fill-manager/boot.ts'), resolve(scriptsDir, 'fill-manager/main.css')],
...
}
};
Is there a way where I can specify a css/scss file entry in extra.webpack.config.js and it just output a bundled css file using configuration based on angular?

Add the CSS from the node_modules folder using angular cli

I've installed a new library with npm, so far so good. Now I want to import the css in there to my project, obviously I shouldn't link directly to the node_modules folder. So, is there a simple to do import this to my project? I'm using Angular CLI.
I have an idea, but I'm not sure if it's a good idea - I thought about installing gulp/grunt and then require the style there and output it as vendor.css into my project. Is it even possible?
First go to your angular-cli-build.js file and add an entry in the vendorNPMFiles array. This will copy your node_modules files to the /vendor directory during the build. Now you can reference your css in your index.html as /vendor/folder/file.css.
Eg: angular-cli-build.js
/* global require, module */
var Angular2App = require('angular-cli/lib/broccoli/angular2-app');
module.exports = function(defaults) {
return new Angular2App(defaults, {
vendorNpmFiles: [
'systemjs/dist/system-polyfills.js',
'systemjs/dist/system.src.js',
'zone.js/dist/**/*.+(js|js.map)',
'es6-shim/es6-shim.js',
'reflect-metadata/**/*.+(js|js.map)',
'rxjs/**/*.+(js|js.map)',
'#angular/**/*.+(js|js.map)',
'bootstrap/dist/**/*.*',
'lodash/lodash.min.js'
]
});
};
index.html snippet
<link rel="stylesheet" href="vendor/bootstrap/dist/css/bootstrap.min.css">

How to include semantic-ui fonts using bower and ember-cli

I want to use semantic-ui within ember-cli project, having trouble with including fonts.
bower install semantic-ui
Import css and fonts in Brocfile.js
app.import('bower_components/semantic-ui/dist/semantic.css');
app.import('bower_components/semantic-ui/dist/semantic.js');
var semanticFonts =
pickFiles('bower_components/semantic-ui/dist/themes/default/assets/fonts', {
srcDir: '/',
files: ['**/*'],
destDir: 'assets/themes/default/assets/fonts'
});
This works, because semantic.css looks for themes/default/assets/fonts relative to itself.
Note the destDir: 'assets/themes/default/assets/fonts', this is because ember-cli puts the semantic-css within assets/ folder, and I have to put the fonts in that folder. But this looks like a hack is there a better solution?
Finally semantic-ui dist folder doesn't include different build options, do I have to compile the project myself eg: using gulp?, I thought using bower it should be straightforward.
We also got 404's for the fonts after installing Semantic via Bower. We solved it by adding the font folder as a tree to the Ember build.var
EmberApp = require('ember-cli/lib/broccoli/ember-app');
var pickFiles = require('broccoli-static-compiler');
module.exports = function(defaults) {
var app = new EmberApp(defaults, {
babel: {
includePolyfill: true
},
fingerprint: {
extensions: ['js', 'css', /*'png', 'jpg', 'gif',*/ 'map']
}
});
app.import('bower_components/semantic/dist/semantic.css');
app.import('vendor/shims.js');
var semanticIcons = pickFiles('bower_components/semantic/dist/themes/default/assets/fonts', {
srcDir: '/',
destDir: '/assets/themes/default/assets/fonts'
});
return app.toTree([semanticIcons]);
};
Looking at semantic-ui, it seems pretty gigantic, and specifically setup with gulp.
First off, I would use the flag --save in your bower request.
bower install --save semantic-ui
This will add it as a dependency to your bower.json automatically - or --save-dev if it's only for development and not production.
Semantic-ui looks like it's written in "LESS", so not only do you have to deal with a favored build tool, but also it has opinions about the preprocessor.
The fonts involved seem to be just some google includes, and some svg fonts.
My advice, if you really really want to use a monstrous set of CSS declarations like this, - in this situation - would be to take the /dist output .css and .js -and- combine it with YOUR favorite css pre processing setup - and just override where appropriate. - or borrow the forms or whatever specific styles lead you to want to use this.
I am worried that fully integrating it into your ember project wont be as smooth as intended... and that you won't get a terribly useful amount of stuff out of keeping it in sync.
Just my opinion, - but I can't comment yet. - and I think you would be better off just writing the styles in stylus from scratch anyways. : )
I had the same problem.
I don't know if there's a better way, but I added the following line to the config/application.rb
config.assets.paths << Rails.root.join('vendor', 'assets', 'bower_components', 'semantic-ui', 'dist')
This adds the dist folder to the asset path, so when semantic-ui is looking for /themes, it will be picked up.

How can I customise Bootstrap without losing the changes?

I'm using Bower to manage Bootstrap and would like to make some changes (colours, font size etc) to the default Bootstrap look and feel. Here's my workflow:
Edit bower_components/bootstrap/less/variables.less
Recompile bootstrap using grunt build
The problem is that I want to be able to upgrade bootstrap when a new version comes out and presumably I'll lose my changes to variables.less.
Is there a way I can keep my changes outside of bower_components and also avoid having bower_components in source control since it's 122MB?
you can create a variables-custom.less and import it into theme.less like this:
//
// Load core variables and mixins
// --------------------------------------------------
#import "variables.less";
//import custom-variables after variables so the values will override.
#import "custom-variables.less"; //only has variables that have changed.
#import "mixins.less";
IMO this is a little bit better than the first solution because you wont have to load two (almost) identical CSS files on the client.
I'm sorry I cant help you with what to to about Bower and your source control as I do not use Bower
Here's the solution which worked for me:
Use bower to install all UI packages e.g. bower install bootstrap chosen
Create a separate folder less which contains all the LESS modifications. This article was very helpful here.
Here's my less/styles.less file:
#import "../bower_components/bootstrap/less/bootstrap.less";
#import "../bower_components/bootstrap-chosen/bootstrap-chosen.less";
//My custom variables - overrides the bootstrap variables file
#import "variables-custom.less";
Use grunt to monitor changes within the less folder and compile them into .css
Here's my Gruntfile.js (thanks to this answer):
module.exports = function(grunt) {
grunt.initConfig({
less: {
development: {
options: {
paths: ["./less"],
yuicompress: true
},
files: {
"./static/css/styles.css": "./less/styles.less"
}
}
},
watch: {
files: "./less/*",
tasks: ["less"]
}
});
grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks('grunt-contrib-watch');
};
This is indeed the best customization method. You create a theme.less and pull in original Bootstrap files (which can get upgraded in the future) and in the same file you call your own custom overrides. Either you #import them from a custom file which is not in the Bower directory or you just write your custom rules in your theme.less itself. You'll find this technique explained in this tutorial as well.
With Grunt, custom setups can get tricky. But with Brunch it's a piece of cake (yes!) and all pretty much goes automatically. Your grandma could do it.
As for avoiding the inclusion of bower_components in source control: with Git it's easy. You just check-in your bower.json but make sure to add /bower_components to your .gitignore file.
You should just create your own style sheet, use both with your custom one listed secondly. That way you can make changes but not change bootstrap at all.
Also, when you update, you keep your style sheet the same.
This allows you to change bits and pieces of Bootstrap but not actually changing the file, you're overriding it.
To be clear, your second CSS file would be SIGNIFICANTLY smaller... Only putting things your needed to change in it.

Resources