• Stars
    star
    983
  • Rank 46,580 (Top 1.0 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created over 12 years ago
  • Updated about 4 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A RequireJS CSS loader plugin to allow CSS requires and optimization

require-css

RequireJS CSS requiring and optimization, with almond support.

Useful for writing modular CSS dependencies alongside scripts.

For LESS inclusion, use require-less, which behaves and builds the css exactly like this module apart from the preprocessing step.

Overview

Allows the construction of scripts that can require CSS, using the simple RequireJS syntax:

define(['css!styles/main'], function() {
  //code that requires the stylesheet: styles/main.css
});

Fully compatible in IE 6+, Chrome 3+, Firefox 3.5+, Opera 10+, iOS.

  • CSS builds When run as part of a build with the RequireJS optimizer, css! dependencies are automatically inlined into the built layer within the JavaScript, fully compatible with layering. CSS injection is performed as soon as the layer is loaded.
  • Option to build separate layer CSS files A separateCSS build parameter allows for built layers to output their css files separately, instead of inline with the JavaScript, for manual inclusion.
  • CSS compression CSS redundancy compression is supported through the external library, csso.

Installation and Setup

Download the require-css folder manually or use Bower:

bower install require-css

To allow the direct css! usage, add the following map configuration in RequireJS:

map: {
  '*': {
    'css': 'require-css/css' // or whatever the path to require-css is
  }
}

Use Cases and Benefits

Motivation

The use case for RequireCSS came out of a need to manage templates and their CSS together. The idea being that a CSS require can be a dependency of the code that dynamically renders a template. When writing a large dynamic application, with templates being rendered on the client-side, it can be beneficial to inject the CSS as templates are required instead of dumping all the CSS together separately. The added benefit of this is then being able to build the CSS naturally with the RequireJS optimizer, which also supports separate build layers as needed.

Script-inlined CSS Benefits

By default, during the build CSS is compressed and inlined as a string within the layer that injects the CSS when run.

If the layer is included as a <script> tag, only one browser request is needed instead of many separate CSS requests with <link> tags.

Even better than including a layer as a <script> tag is to include the layer dynamically with a non-blocking require. Then the page can be displayed while the layer is still loading asynchronously in the background. In this case, the CSS that goes with a template being dynamically rendered is loaded with that same script asynchronously. No longer does it need to sit in a <link> tag that blocks the page display unnecessarily.

Modular CSS

RequireCSS implies a CSS modularisation where styles can be scoped directly to the render code that they are bundled with.

Just like JS requires, the order of CSS injection can't be guaranteed. The idea here is that whenever there are style overrides, they should be based on using a more specific selector with an extra id or class at the base, and not assuming a CSS load order. Reset and global styles are a repeated dependency of all modular styles that build on top of them.

Optimizer Configuration

Basic Usage

Optimizer configuration:

{
  modules: [
  {
    name: 'mymodule',
    exclude: ['css/normalize']
  }
  ]
}

If the contents of 'mymodule' are:

  define(['css!style', 'css!page'], function(css) {
    //...
  });

Then the optimizer output would be:

-mymodule.js containing: style.css and page.css which will be dynamically injected

The css/normalize exclude is needed due to r.js issue #289

Separate File Output

To output the CSS to a separate file, use the configuration:

{
  separateCSS: true,
  modules: [
  {
    name: 'mymodule'
  }
  ]
}

This will then output all the css to the file mymodule.css. This configuration can also be placed on the module object itself for layer-specific settings.

Optimization is fully compatible with exclude and include.

IE8 and 9 Selector Limit

In IE9 and below, there is a maximum limit of 4095 selectors per stylesheet.

In order to avoid this limit, CSS concatenation can be disabled entirely with the IESelectorLimit option.

{
  IESelectorLimit: true,
  modules: [
  {
    name: 'mymodule'
  }
  ]
}

Ideally build layers would avoid this limit entirely by naturally being designed to not reach it. This option is really only as a fix when nothing else is possible as it will degrade injection performance.

This option is also not compatible with the separateCSS option.

Excluding the CSS Module in Production

When dynamic CSS requires are not going to be made in production, a minimal version of RequireCSS can be written by setting a pragma for the build:

{
  pragmasOnSave: {
    excludeRequireCss: true
  }
}

siteRoot Configuration

When building the CSS, all URIs are renormalized relative to the site root.

It assumed that the siteRoot matches the build directory in this case.

If this is different, then specify the server path of the siteRoot relative to the baseURL in the configuration.

For example, if the site root is www and we are building the directory www/lib, we would use the configuration:

{
  appDir: 'lib',
  dir: 'lib-built',
  siteRoot: '../',
  modules: [
  {
    name: 'mymodule'
  }
  ]
}

Almond Configuration

Almond doesn't support the packages configuration option. When using Almond, rather configuration RequireCSS with map configuration instead, by including the following configuration in the production app:

  requirejs.config({
    map: {
      '*': {
        css: 'require-css/css'
      }
    }
  });

Disabling the Build

To disable any CSS build entirely, use the configuration option buildCSS:

{
  buildCSS: false,
  modules: [
  {
    name: 'mymodule'
  }
  ]
}

CSS requires will then be left in the source "as is". This shouldn't be used with stubModules.

CSS Compression

CSS compression is supported with csso.

To enable the CSS compression, install csso with npm:

  npm install csso -g

The build log will display the compression results.

When running the r.js optimizer through NodeJS, sometimes the global module isn't found. In this case install csso as a local node module so it can be found.

Injection methods

When loading a CSS file or external CSS file, a <link> tag is used. Cross-browser support comes through a number of careful browser conditions for this.

If CSS resources such as images are important to be loaded first, these can be added to the require through a loader plugin that can act as a preloader such as image or font. Then a require can be written of the form:

require(['css!my-css', 'image!preload-background-image.jpg', 'font!google,families:[Tangerine]']);

License

MIT

More Repositories

1

es-module-shims

Shims for new ES modules features on top of the basic modules support in browsers
JavaScript
1,514
star
2

es-module-lexer

Low-overhead lexer dedicated to ES module parsing for fast analysis
JavaScript
791
star
3

chomp

'JS Make' - parallel task runner for the frontend ecosystem with a JS extension system.
Rust
141
star
4

require-less

LESS loader plugin for RequireJS with builds, based on RequireCSS
JavaScript
139
star
5

wasm-intro

Egghead.io WASM Introduction Examples
HTML
119
star
6

wasm-demo

Egghead.io WASM Introduction Demo Project
HTML
107
star
7

isomorphic-browser-modules

A workflow for using <script type="module"> with a fallback for older browsers
JavaScript
51
star
8

require-is

Conditional loader plugin for RequireJS with code branch build support
JavaScript
51
star
9

amd-loader

RequireJS loader plugin helper for transpiler and template plugins
JavaScript
34
star
10

import-maps-extensions

Extensions to the WICG import maps proposal
HTML
30
star
11

systemjs-webpack-plugin

Webpack bundling for SystemJS
JavaScript
28
star
12

wasm-stdlib-hack

Copy of libc and libcxx includes from Emscripten with some wast linking helpers
C++
25
star
13

markdown-component

JavaScript
21
star
14

proposal-weak-imports

Experimental Weak Imports Proposal for ECMAScript
HTML
20
star
15

cjs

CommonJS loader plugin for RequireJS
JavaScript
17
star
16

jspm-react-component-demo

JavaScript
14
star
17

react-jspm-es6-gulp-example

a work in progress example showing react / react-nested-router / jspm / gulp / es6
JavaScript
14
star
18

system-md

jspm Markdown plugin
JavaScript
12
star
19

es6

ES6 Loader Plugin for RequireJS
JavaScript
10
star
20

packagemap-polyfill

Experimental polyfill approach for package name maps in browsers
JavaScript
10
star
21

js-components

WebAssembly
9
star
22

require-inline

A small add-on for RequireJS providing inline sync load support. Useful for dynamic widgets that need JavaScript attachments to occur instantly during the page load.
JavaScript
8
star
23

amdquery

A selector plugin for RequireJS with a dynamic query selector polyfill, supporting modular DOM utilities and builds.
JavaScript
6
star
24

jspm-beta-guide

5
star
25

proposal-export-star-default

Proposal to include default export in `export * from 'module'`
HTML
5
star
26

chomp-extensions

Chomp template collection
JavaScript
5
star
27

proposal-pkg-entries

package.json "entries" field proposal
4
star
28

systemjs-istanbul

SystemJS Istanbul Coverage Helper
JavaScript
4
star
29

chomp-action

GitHub Action to Install Chomp
JavaScript
4
star
30

wasi_unstable

WASI Unstable Experimental ES Module Integration
JavaScript
4
star
31

node-resolve-hook

Draft proposal for NodeJS ES modules pipeline hooks
4
star
32

karma-systemjs-experiment

JavaScript
3
star
33

jspm-demo

JavaScript
3
star
34

extract-requires

Extract CommonJS requires from a JavaScript source string with simple tokenizing
JavaScript
3
star
35

modules-caching

JavaScript
2
star
36

cjs-named-exports-loader

JavaScript
2
star
37

jspm-test-demo

jspm test demo
JavaScript
2
star
38

proposal-pkg-targets

package.json proposal for differential target resolution
2
star
39

hbs

JavaScript
2
star
40

babel-modules-system-source-maps-bug

JavaScript
1
star
41

plugin-traceur

SystemJS Traceur Plugin (wip)
1
star
42

voxel-demo

JavaScript
1
star
43

json

AMD wrapper module for JSON parsing. Feature detects JSON.stringify and JSON.parse, dynamically requesting json2 polyfill when necessary.
JavaScript
1
star
44

asset-plugin-experiment

JavaScript
1
star
45

module-property-refined-proposal

Yet another proposal for ES module distinction in Node
1
star
46

esm-resolver-test

JavaScript
1
star
47

amd-version

RequireJS semver-compatible versioning plugin
JavaScript
1
star
48

chrome-modules-bug

ES modules circular test case
JavaScript
1
star
49

separate-css-test

JavaScript
1
star
50

styletab

JavaScript
1
star
51

systemjs-sandbox

Prototype sandbox demo for SystemJS
JavaScript
1
star
52

require-cs

JavaScript
1
star
53

modules-link-preload

Testing link rel=preload for module scripts in browsers
JavaScript
1
star
54

modules-benchmarks

Module loading benchmarks
JavaScript
1
star