72

After playing around with AMD/RequireJS I was wondering if it is a good idea to load UI modules including templates and CSS so they are completely independent from the web page.

It sounds like good, but I haven't seen this implemented in the wild so there may be pitfalls.

Think of some UI module with the following structure:

myWidget
    |--img 
    |--main.js
    |--styles.css
    +--template.tpl

All stuff in one folder. Looks very nice.

The module in main.js would look something like this:

define(["TemplateEngine", "text!myWidget/template.tpl"], function(TemplateEngine, template) {

    // Load CSS (Pseudo Code)
    var cssUrl = "myWidget/styles.css";
    appendToHead(cssUrl);

    return function() {
        return {
            render: function(data) {
                  return TemplateEngine.toHtml(template, data);
            } 
        }
    }
});

Questions are now:

  1. Am I missing something?
  2. Are there any plugins/concepts how to achieve this in a "standard" way?
  3. Is the RequireJS optimizer able to handle the CSS part here, say concat/minify the stylesheets like it does with the JS parts?
  4. Any opinions on that? Good or bad?
Dan D.
  • 73,243
  • 15
  • 104
  • 123
fbrandel
  • 1,605
  • 3
  • 17
  • 18
  • i'm doing this for templates and it's working great. The only struggle I had was with CSS where I couldn't get the optimization to work. It would give me a cryptic error and I didn't have the time to solve it. It's currently on my list of things to try to resolve so I'm going to keep an eye on your question to see if someone has a resolution – timDunham Oct 27 '11 at 17:49

2 Answers2

54

You can specify the template as a dependency using the text! module like you have shown. I do this with Mustache Templates.

However Require.js does not explicitly support css files.

Here is the official explanation, it's explained pretty well: http://requirejs.org/docs/faq-advanced.html#css

Edit: Feb 2012.

Templates such as handlebars can also be precompiled and included just like any other JS module http://handlebarsjs.com/precompilation.html

Edit: August 2015

If you're after this sort of modularization you should look into webpack and specifically css-loader. I'm using it to pair .css files with .jsx files as a unified "module" and extract the relevant CSS into a single stylesheet at build time.

Chris Biscardi
  • 3,148
  • 2
  • 20
  • 19
  • 2
    What is the "correct" way to deal with CSS then? – hugomg Nov 02 '11 at 01:10
  • AFAIK there is no "right" way. your options are: 1) traditional link tag 2) dynamically including the stylesheet using javascript . If your javascript depends on your css and you want to dynamically load it you will have to create a function to test for the existence of an attribute from the loaded css class before your javascript widget runs. – Chris Biscardi Nov 02 '11 at 01:45
  • you could also load css via the text! module and parse it, although I have never done this. – Chris Biscardi Nov 02 '11 at 01:48
  • 29
    Yeah, I know that there are many alternatives, It still kinda bums me that we have a standard system for JS modules but when it comes to CSS we are back to the wild west. – hugomg Nov 02 '11 at 01:51
  • You can use yesnope.js to load css files via injectCSS function – Saleh Dec 13 '12 at 11:07
  • 1
    I guess I don't understand why CSS can't be loaded by the text! plugin? isn't CSS just utf8 text? – Alexander Mills Aug 16 '15 at 01:01
7

There is a third-party CSS plugin for RequireJS which seems to work well: https://github.com/VIISON/RequireCSS/.

Chad Johnson
  • 21,215
  • 34
  • 109
  • 207