How To Start A DoneJS Project

I have added a section to the guide linked to above that explains how to work with sass and Bootstrap 4 when using DoneJS.

By default DoneJS projects utilize less via the a less compiler engine that runs on the client side. This is probably not optimal, to be compiling our CSS on the client side. Also, if you want to use the new version 4 of Bootstrap, you will need to compile scss not less files.

Hope that helps someone!

Thanks for the update!

Assuming that live-reload is working fine, compiling less on the client is actually optimal over the course of many changes.

One more thought, the ability for a module to contain its own styles and be able to load them is really important for making small/isolated components and sticking to the modlet pattern.

If you start having a different lifecycle for styles vs code, that can hurt a project in the long run.

Totally agree with you on modlets, and I will continue to use LESS in the modlets. However, I am basing this guide off the place-my-order guide which has the separate repo for the assets (bootstrap, images, and custom style declarations). Bootstrap 4 requires Sass, and the steal-sass plugin is not performant (actually, it fails to resolve @imports).

I can theorize, but I donā€™t know why compiling on the client is optimal, if you wouldnā€™t mind explaining why? At least for Sass there are different compilers made for performance reasons f.ex. the original in Ruby and the much faster C/C++ implementation libsass, but sass.js is the slowest of them all (even the maintainer says use the any other compiler unless you absolutely must use sass.js to compile in the browser).

So, I think if you want to use Bootstrap 4 and Sass, this is probably the best way for now.

I really am curious about the details of why itā€™s actually optimal to compile less on the client over the course of many changes. Is it because of optimizations that can be done in-flight, spreading workload, or perhaps avoiding the overhead of reloading a compiled CSS file? Hope you can explain that!

Itā€™s basically the benefits of hot module swapping. Assuming you have many sass files, if one of them changes, we only have to reload that one file that changed recompile just it (and any parent modules).

If you change mymodule/mymodule.scss, the client downloads that, re-compiles it, and updates the DOM accordingly.

If you do this server-side, you could setup a similar hot-module swapping server, but even with that, youā€™d still be transporting the full css output everytime.

All of this is certainly true with JavaScript, which is why I said

Assuming that live-reload is working fine,

Iā€™m not sure how great our live-reload works with scss as Iā€™ve not used them together on a project (others in Bitovi have). A lot depends on how scss compiles source files. Someone like @RyanWheale or @matthewp would know more about this. I know that in a good system, hot-module swapping in the client should be generally faster than a server-side equivalent. Iā€™m just not confident SCSS is something we can make (or have made) operate in the same way JavaScript dependencies operate.

1 Like

That sounds pretty slick, if Iā€™m grokking everything right! So, let me try and get this straightā€¦

If I have some components, letā€™s say foobar.component:

<can-component tag="app-foobar">
  <can-import from="my-app/same.less!" />
  <template>
    <p>Foobar!</p>
  </template>
</can-component>

And batman.component:

<can-component tag="app-batman">
  <can-import from="my-app/same.less!" /> <!-- loading same.less again -->
  <template>
    <p>Batman!</p>
  </template>
</can-component>

That are used in index.stache like so:

<html>
  <head>
    <title>{{title}}</title>
  </head>
  <body>
    <can-import from="my-app/app" export-as="viewModel" />
    <can-import from="my-app/foobar.component" />
    <can-import from="my-app/batman.component" />
    
   {{#switch page}}
      {{#case "home"}}
        <app-foobar/>
        <app-foobar/>
        <app-batman/>
        <app-batman/>
      {{/case}}
      {{#case "away"}}
        <app-foobar/>
        <app-batman/>
      {{/case}}
    {{/switch}}
  </body>
</html>

Then in production, DoneJS would bundle the compiled CSS with the respective foobar and batman components, and intelligently inject that CSS when a component is used (like <app-foobar/>)ā€¦

However, Iā€™ve outlined a questionable situation in the example above, and Iā€™m curious about how it would be handled (more specifically, I want to know if the CSS would be loaded more than just once).

So, considering that foobar and batman both can-import the same less file, would that CSS be loaded twice when foobar and batman are used on the same page?

What about when one component is used twice in a row?

What about when changing pages that contain the same component that was on the previous ā€œpageā€?

Itā€™s also possible that Iā€™ve misunderstood production, and really all CSS is just globbed together in one big file (non-redundantly?), and thereā€™s no injection of CSS going on. I see in the in-depth guide for place-my-order, it says:

the restaurant list pageā€™s JavaScript and CSS will only be loaded when the user visits that page.

Thanks if you can give any insight as to how this system pans out under the hood!

No, only once. Steal will resolve these to be the same module and execute (load it) only once. This is the same way RequireJS, Node.js and every JavaScript loader Iā€™m aware of works.