Bundling Angular project without compiling - css

I divided my Angular 6 Project in many modules. Those modules reference a ui module containing all the style sheets (SASS) as values e.g.
$primary-text-color: #dde7ff !default;
The reason for this is reusability of the modules. After building one of those modules the stylesheets are already part of the *.js files. Everything is CSS and and the scss values doesn't exist anymore.
However, this approach doesn't allow the consumer to theme or change the values e.g. colors or fonts of the components inside the module afterwards.
My objective is to allow the consumer to:
create a new angular-cli project
define own global style variables like $primary-text-color: #dddddd !default; and therefore overwrite the mentioned variables
referencing existing modules
build the application.
The expected result would be an application with the look/theme of the consumers new style. With this approach the consumer wouldn't be forced to style each component manually.
To achieve this would it be possible to:
create angular-cli libraries without compiling the ts files and rendering the stylesheets? This would be just a bundle of the original files, but in a library. In this case the reference to the variables still exist and could be overwritten.
Style the components in the module with global stylesheets afterwards?

You can't really bundle your code without building it.
But, maybe there is a workaround for what you trying to achieve.
you can create an InjectionToken with the theming option.
Let say:
export interface Theming{
color: string;
}
const THEMING_CONFIG : InjectionToken<Theming> = new InjectionToken<Theming>('Theming Config');
Now, in your lib Module:
#NgModule()
....
export class UIModule{
static init(config: Theming): ModuleWithProviders {
return {
ngModule: UIModule,
providers: [{provide: THEMING_CONFIG, useValue: config}]
}
}
}
Now in each and every component in your lib you can inject the InjectionToken and use it in to style the elements (ngStyle?)
The usage of the lib for the end-user will be:
#NgModule
...
export class AppModule {
imports: [..., UIModule.init(USER_COLOR_HERE)]
}

Related

Classes brought from Team A and Team B polluting the same global namespace

I am new to Tailwind CSS but there is something that confuses me.
Let's run a scenario:
Team A
builds a UI component library using TailwindCSS (Button, Forms, Dialog, etc)
publish NPM package where exports index.ts and theme/tailwind.css
Team B
npm install Team A library. Imports theme/tailwind.css into their application main.ts (entry point).
At this point, their main.ts should have
import { Button } from '#team-a/ui`
import '#team-a/ui/theme/tailwind.css` // tailwind classes coming from Team A
import `./theme/main.css` // tailwind CSS global file belonging to Team B
At this point in time, in the <style> tags in the head, we will have classes brought from Team A and Team B, polluting the same global namespace.
How do you get around this issue?
There a few ways to avoid this, but if both teams uses tailwind there should not be any issue. unless you have custom CSS that for example overrides custom properties at the :root.
Regardless here a few ways to avoid clashing CSS styles.
use #layers,
Scope the CSS to apply only to a specific tag and below. This is a tricky one, usually frameworks will handle that, react with CSS modules, angular with view encapsulation, but it is possible with postcss or sass.
Prefix the tailwind config with each team unique string, if they build separated tailwind output CSS.

Include external CSS in an Angular library by modules

I am working on an angular design library based on bootstrap, similar to ng-bootstrap
I currently created multiples modules for each design component that can be imported separately based on user needs.
ex :
src/
modules/
inputs/
buttons/
navs/
tooltips/
....
Each module can be imported independently and used in application.
The problem I face is with bootstrap scss. Has explained here we can import all bootstrap with
#import "../node_modules/bootstrap/scss/bootstrap";
or by chunk
#import "../node_modules/bootstrap/scss/root";
#import "../node_modules/bootstrap/scss/reboot";
#import "../node_modules/bootstrap/scss/type";
#import "../node_modules/bootstrap/scss/images";
#import "../node_modules/bootstrap/scss/containers";
#import "../node_modules/bootstrap/scss/grid";
I would like each of my modules to import their specific scss files. The table would import the tables scss, the navs the navs etc...
Since bootstrap files are scss they need to be compiled before added to the page, and the easy solution of manually adding in each module a stylesheet element would not work.
In ng-bootstrap they require users to manually add each bootstrap scss that they wish to use, but this could be kind of a pain for users since they need to manually add a module and the associated styles.
Are there any solution to bind a scss file to a module, and compile it if that module is used in the app ?
I would follow in the footsteps of Angular Material's implementation and provide users of your library instructions on how to include the design library styles default styles or custom styles. Take a look at Angular Materials build code and the corresponding exported assets made available as an NPM package. Essentially to manually import a single SCSS file per module that is imported as described above a user would need to take the following steps and understand the styles will be applied globally. There is no dynamic inclusion and compilation of SCSS in Angular upon loading of a module the chunks under the hood would need to be recompiled and the styles would be preprocessed again.
In angular.json under the "build.options" object modify "styles" and "stylePreprocessorOptions" and update the configuration to point to the new global styles directory "entry" such as "styles":["src/styles/styles.scss"], "stylePreprocessorOptions": { "includePaths": [ "styles" ] } then in styles.scss import your bootstrap scss. Under the styles directory you can now create a custom directory structure and the angular compiler will be able to find everything imported in the global "styles.scss" file. Further reading: read about the shadow DOM in Angular in the context of styles applied based on view encapsulation for component scoped styles vs. globally applied styles.

How to keep CSS/SCSS with Vue component file

I am creating a component library where I do not want to have global CSS. Therefore, every component is scoped.
When running the production build via
vue-cli-service build --target lib --name sc components/index.js, everything is compiled into sc.css and dist/css/1.392e001d.css.
If possible, I want to keep the css and/or scss combined with the vue file or js.
The reason I want to do this is to enable users of the library to import a singular component from the library. The users could then use the component anywhere without having to import/include a css file.
If this is not possible, is there a way to accomplish the desired functionality?
From the Vue CLI docs for css.extract:
When building as a library, you can also set this to false to avoid your users having to import the CSS themselves.
// vue.config.js
module.exports = {
css: {
extract: false
}
}

How could I make Aurelia include my styles as external styles via <link>?

I am trying to set up the conjunction of Atom editor, Sass, Typescript and Aurelia. This question is about Aurelia (installed via aurelia-cli) and its building system, I guess.
Well, I wrote style.sass for my component, then I required it in the component's view (app.html, for instance) as style.css. Fine, it works. But the content of compiled style.css gets included in index.html as internal styles, I mean everything goes inside <style>-tag, not through <link>. Also it seems that the corresponding .css file is never created at all. The stream just includes its content right in <style>-tag inside index.html.
How could I make Aurelia include my styles as external styles via <link>? In building task the last action is a build-plugin coming from aurelia-cli which is kinda black-box for me. Also aurelia.json is imported, so there should be a way to configure the needed behavior. A quick search didn't give me the answer, so here I am.
This is probably not the best solution, and not completely what you want, but perhaps it helps. You can do the following (I took a new TypeScript project):
First remove the css includes from your views.
Then, adjust the ./aurelia_project/tasks/process-css.ts task as follows:
import * as gulp from 'gulp';
import * as sourcemaps from 'gulp-sourcemaps';
import * as sass from 'gulp-sass';
import * as project from '../aurelia.json';
import {build} from 'aurelia-cli';
export default function processCSS() {
return gulp.src(project.cssProcessor.source)
.pipe(sourcemaps.init())
.pipe(sass().on('error', sass.logError))
.pipe(gulp.dest(project.platform.output));
};
This will output CSS files in the ./scripts folder. Then, adjust the aurelia_project/aurelia.json file as follows (remove css):
{
"name": "app-bundle.js",
"source": [
"[**/*.js]",
"**/*.{html}"
]
},
In your index.html you can now include the generated styles (or even in your components views).

Using global css files with CSS Modules

I'm using https://github.com/mxstbr/react-boilerplate for a project, which uses CSS Modules and postCSS for the styles, which is great. However, I also need to have some global CSS files for typography, base components, etc. What is the best practice for how these should be added in? I've looked at using preCSS but not entirely sure how to set it up within webpack, so that it can import these global files into the main stylesheet. I'm new to webpack (come from a Gulp/Grunt background, using Sass) so any help here would be much appreciated.
It would also be great if I could use the variables and mixins defined in these files in the CSS Module files, but unsure if this is possible or advised. I've installed react-css-modules so that I can use styleName to refer to the CSS Module file and className to refer to the global CSS classes.
I know there is the composes: class from '/path/to/file.css'; attribute but I would prefer to have some global files where various utility classes are defined, such as clearfix and error classes, etc. So using react-css-modules, it would look something like this:
<div className="clearfix" styleName="app-header">{...}</div>
Again, not sure if this is correct.
I want to stick to best practices as I'm working on an open-source project and want it to be done in the best way possible. Thanks for any advice!
css-modules provides :global that can be used to include locally in your code css files that will included globally in application
I did come across this problem when I wanted to use a 3rd party library that requires some css files that are directly referenced in the js templates (by class name strings) and css modules were not supported. As I did not want to change the css files by adding :global modifier (because they are 3rd party and might change in the future), I've figure out there is a mode setting in the css-loader that you can use to preserve original names for certain files.
How it works:
There is a mode setting in the in the css-loader that (beside other options) accepts a function. It takes a resourcePath as an argument and returns values local, global and pure. Global keeps all the name as they were defined in the original file, while local uses standard hashing as defined. This is handy for third party libraries that don't work with css modules.
I've written a short function that checks the the resourcePath for modules that should stay global. Seems to work fine for me, the only disadvantage is that I have to write it twice (development and production setting).
Here is the development env example:
{
loader: 'css-loader',
options: {
modules: {
localIdentName: '[name]_[local]_[hash:base64:6]',
exportLocalsConvention: 'camelCase',
mode: (resourcePath) => {
let globalStyles = ['module-to-stay-global-1', 'module-to-stay-global-2'];
return globalStyles.some(globalFile => resourcePath.includes(globalFile)) ? 'global' : 'local'
}
},
}
}
Documentation to the mode function can be found here:
https://github.com/webpack-contrib/css-loader#function-3

Resources