How do I use Less with a aurelia cli project - less

How do I get Less to work with an aurelia cli project?
I've added a style.less file under src and I can see it's bundled into app-bundle.js. But I am not sure if or how I need to add reference to it in app.html?
I've added a div tag
<div class="test-less">Test less</div>
in app.html using a class in my style.less file but when I run the app the css is not used - even though I can see the css in the app-bundle.js:
define('text!style.css', ['module'], function(module) { module.exports = ".test-less {\n color: #FF0000;\n background-color: green;\n}\n"; });
I'm not sure what the 'define..' actually does - ie does it inject the css into the DOM? It is listed beneath the define statement which includes the app.html - so maybe it's out of scope - so not usable in app.html???? If so, how should one use Less with Aurelia (project created by aurelia CLI)
Thanks
Tim

As #Rabah-g stated - I needed to add a require eg:
<require from="style.css"></require>
To figure out what path to use - I just used what was stated in the 'define' statement in app-bundle.js. In this case simply 'style.css'.

Related

Vue Quasar - change name of builted generated css

Quasar creates two CSS files upon the build:
I want them to have the names like:
-quasar.css
-appQuasar.css
I have been searching a lot and I can't find any documentation to change the CSS. For example the app file on quasar.config.js
Thank you,

Including partials in components results in duplicate css

I'm trying to make use of the #extend of sass so that I don't mix markup and html together. As explained in this article.
In short, instead of writing
<div class="alert alert-primary>This is an alert!</div>
You'd instead write something like
<div class="banner">This is an alert!</div>
.banner {
#extend .alert;
#extend .alert-primary;
}
Such that styling and content stay nicely separated.
The problem: When using this with webpack (sass-loader) and components (e.g. Vue.js or Angular), I run into a problem where including a bootstrap partial will now result in the complete compilation of the entire bootstrap file into css.
This results into a class .btn[data-v-3614b62c] and another .btn[data-v-45ac961c] etc. for every component that uses the partial bootstrap/scss/_buttons.scss and that for all classes defined in that partial.
Even if I don't use it.
In the long run, this will be detrimental for the application since its size will increase rapidly and I image the browser will slow down with that many css classes to parse.
The question(s): How do I make sure sass doesn't duplicate the entire imported partial?
Can I enable some kind of tree shaking where it only includes the classes I use?
Do I have to change my file structure so that sass understands I only need certain classes inside the partial rather than everything?
Code example
This is a vue component using bootstrap
<template>
<form class="form">
<input type="text" class="input">
<button class="button-submit">Send</button>
<button class="button-cancel">Cancel</button>
</form>
</template>
<style lang="scss" scoped>
#import "node_modules/bootstrap/scss/functions";
#import "node_modules/bootstrap/scss/variables";
#import "node_modules/bootstrap/scss/mixins";
#import "node_modules/bootstrap/scss/root";
#import "node_modules/bootstrap/scss/buttons";
.form {
.button-submit {
#extend .btn;
#extend .btn-primary;
}
.button-cancel {
#extend .btn;
#extend .btn-danger;
}
}
</style>
This will result in the entire partial _buttons.scss to be compiled into css instead of only .form .button-submit and .form .button-cancel.
Live example
https://codesandbox.io/embed/musing-feynman-8w2kx.
To see the problem I have:
Right click on the example to the right and click Inspect
In the Elements tab, navigate to #document > html > head
At the bottom you'll have several style elements
Two of them will contain all the button css where only the [data-v-######] attribute is different and at the end are my couple of lines code.
Note that the same happens for production builds. The css is then simply bundled up in a single file, but duplicates are still around.
If you are #importing the same CSS rules into different components, then you will get the same rules duplicated across all modules. That's just how it works.
You should only be #importing modules that define abstract declarations like variables, mixins, functions, etc, not actual styles.
The only way you can de-duplicate the styles globally is if you use something like mini-css-extract-plugin to extract and combine all the CSS into a single file and then run it through something like cssnano which will discard duplicate rules (although with scoped CSS, this probably won't work).
Modules are typically built independently of other modules and there isn't a simple way to know if a rule has been declared already by a previous module. In development you may be using style-loader which operates on a per-module basis and injects styles into the webpage on demand; there's just no way it can work out which styles should be injected in case some particular style has already been injected by another component.
It just gets messy; keep it simple by not duplicating styles in the first place.
If you really want to use #extend, then make a separate .scss file which is the only module that #imports the bootstrap styles, and define all your extensions in there.

What's the best way to add JQuery to Enduro.js

I'd like to be able to use Jquery in my Enduro.js project, but there is not a single sample using it on github Enduro.js page
Libraries seem to be loaded in Enduro.js using RequireJS, wth the line found at the bottom of the default index.hbs :
{{!-- <script data-main="/assets/js/main.js" src="/assets/vendor/requirejs/require.js"></script> --}}
and the following code found un "assets/js/main.js" by default in all Enduro.js samples :
require.config({
baseUrl: '/assets/',
paths: {
// 'jquery': 'vendor/jquery/dist/jquery.min',
},
})
require(['jquery'], function ($) {
$(document).ready(function () {
console.log('requirejs ready to use')
})
})
The Jquery "path" line is commented out, and there is no /vendor directory in /assets by default.
Is there an automated way to install jquery in Enduro.js or is it just simply about creating by hand a /vendor folder, and copying /Jquery inside it ?
Well, there are many ways to use JQuery in Enduro. I'm not sure if it is the best way to import it (it could exist better ones).
In my current project, I'm using the CDN for reasons of efficiency. If you have no problem using CDNs I'd recommend it.
just copy this code:
<script
src="https://code.jquery.com/jquery-3.3.1.min.js"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
crossorigin="anonymous">
</script>
And then, paste it just before closing the body tag.
Another way is to create a folder inside /assets/js called 'vendor' and there, you cat put the jquery-3.3.x.min.js (Or whatever version you would like to use). Of course, you have to download it first from the official site.
After doing that, you just have to import it via HTML (before closing body tag):
<script src="assets/js/vendor/jqueryfile.js"></script>
NOTE: Creating the folder called 'vendor' is optional, you just could paste the file inside /assets/js. And make sure you type the right path to import it.
NOTE 2: remember that you should never touch the files inside _generated, so if you paste the file inside _genereated/assets/js, everything is going to work, but when you migrate your site to production or anywhere else the app will crash.
Hope this helps.

Can I include scoped css without Vue Loader?

For a project where Vue is dropped in, is using style or similar available to components?
Vue.component('vue-sup', {
template: '<div>Sup</div>',
style: '* { color: blue; }'
})
I tried adding the styles inside the template like:
<div>
<style>
.here{}
</style>
<div>Sup</div>
</div>
which didn't work because the template parser detected a tag with side effects
Vue's implementation of scoped css is entirely a feature of vue-loader, and thus only works with compilation. Scoped css momentarily made a debut into Html 5 but saw almost no adoption and was dropped entirely as far as I know. There is the anticipation that "Shadow DOM" may be supported broadly and could be use to add scoped css, but adoption is not there yet either.
So at this point you can add unique classes or ids obviously to a parent container and scope your css that way, but is understandably not what you are asking for nor is it always practical.
The best alternative is a pollyfill. There are several that are available. Here is one by Sam Thorogood and another by Thomas Park but if you do a quick search you will likely discover more.
I came across the same problem and I'm able to insert styling inside Vue template
by creating a component that will dynamically insert a <style> tag on the DOM. This might be impractical like #skribe said but it allows me to have separate CSS from JS without using .vue extension.
You can take a look at this

Importing CSS and controlling order in <head> using jspm and system.js

I've written the following in an Aurelia app
import "bootstrap/css/bootstrap.css!";
import "./app.css!";
and I want app.css second in since it overrides bootstrap.css styles. However, I'm getting app.css first since I presume the system.js loader is running them in parallel and since app.css is the smaller of the two it gets loaded first.
Is there a way in jspm to define a dependency between these two files to control their loading order is is there some other way?
Many thanks in advance! :)
You could try to import the css using System.import.
E.g. in your index.html:
System.import('bootstrap/css/bootstrap.css!').then(() => {
System.import('./app.css!');
});
But keep in mind that this way you have to make sure that system.js is served with your app. So you can't bundle your whole app as an self-executing bundle.
We have some stuff in the pipeline that should help you with this issue. If you check out this:
<template>
<require from="nav-bar.html"></require>
<require from="bootstrap/css/bootstrap.css"></require>
<nav-bar router.bind="router"></nav-bar>
<div class="page-host">
<router-view></router-view>
</div>
</template>
I know that Aurelia will be passing the CSS files to the loader in order, but I'm not sure if we'll be able to guarantee loading order. Hopefully Rob can come over here and give a proper answer to this, though. I'll point him in this direction.
I had exactly the same problem. Controlling order of CSS is not possible in JSPM. I solved this problem with SASS and some tricks. Here's what I've done:
In html you give main element some id:
<html id="some-id">
Then you create sass file that will host your overrides (_overrides.scss):
#some-id {
#import "buttons";
}
Now your buttons.scss can override styles from bootstrap (_buttons.scss):
.btn-default {
background-color: #B6B3C7;
border-color: #B33A3A;
}
This works thanks to the principle in CSS - most specific selector wins. By wrapping all your customizations in #some-id in scss it will produce code with every bit of code that is imported into curly braces prefixed by #some-id. This way your selector will always be more specific than bootstrap one and will override it.
I don't know if this will be sufficient for you as you don't mention scss, but it was for me.
I've faced similar issue during development.
The code below has helped me solve my problem.
Now everything is loading exactly the way I want it.
System.import('bootstrap/css/bootstrap.css!').then(() => {
System.import('./app.css!');
});
Thanks LazerBass for this suggestion.