scissors 0.2.0+1 scissors: ^0.2.0+1 copied to clipboard
A CSS minifier / tree-shaker for AngularDart 1.x / Angular2.
sCiSSors #
Build smaller resources for Angular apps, faster: CSS pruning, SVG+PNG optimization, Sass compilation, locale permutations, automatic reload.
Disclaimer: This is not an official Google product.
Features #
All of the following features are lazy (only triggered when needed) and
most of them are disabled or optimized for speed with pub serve
in debug mode.
(note: may need pub serve --force-poll
on MacOS X)
- CSS pruning for Angular (see example/angular1, example/angular2):
- Finds which .css rules are not used by Angular templates and removes them.
- Supports
ng-class
andclass
with programmatic interpolated fragments (e.g.class="some-{{fragmented}}-class and-some-normal-class"
,ng-class="{'some-class': isSome}"
). - Disabled by default in debug mode.
- Sass compilation:
- Compiles
*.sass
and*.scss
files withsassc
, the lightning-fast C++ port of Ruby Sass. - Rebuilds
.css
files whenever their.sass
sources are modified.
- Compiles
- Image inlining:
- Expands inline-image calls in CSS files into data URI links, like Compass does.
- By default in debug mode, links to images instead of inlining them.
- PNG optimization:
- Calls
pngcrush
to remove all metadata that is useless for rendering. - Disabled by default in debug mode.
- Calls
- SVG optimization:
- Removes comments, doctypes, unused namespaces.
- Disabled by default in debug mode.
- Locale-specific permutations generation (Optional, see example/permutations):
- Generates one .js per locale (e.g.
main_en.js
,main_fr.js
...) with the deferred parts needed for that locale, which speeds up load time. - Supports deferred messages and deferred LTR/RTL template caches.
- Optionally optimizes the resulting
.js
files with the Closure Compiler.
- Generates one .js per locale (e.g.
- Automatic reload support (Optional): zero-turnaround for Dart!
Usage #
Defaults vs. debug vs. release #
sCiSSors is fine-tuned for fast build in debug
mode (default for pub serve
)
and small code size in release
mode (default for pub build
).
Its behaviour can be fully customized through transformer settings in
pubspec.yaml
.
For instance, to enable PNG optimizations in all modes, and enable SVG
optimizations in debug
only:
transformers:
- scissors:
optimizePng: true
release:
optimizeSvg: false
debug:
optimizeSvg: false
Using the scissors
transformer #
The default transformer will build Sass files in a blink of an
eye and will optimize CSS, PNG and SVG assets in release
mode
(pub build
).
Please only setup sCiSSors's transformer on projects you know respect sCiSSors' conventions and limitations (see below).
Examples: see example/angular1, example/angular2).
pubspec.yaml
:
dev_dependencies:
scissors
transformers:
- scissors
Valid settings:
pruneCss
(boolean): by default,true
inrelease
onlyimageInlining
: default islinkInlinedImages
indebug
,inlineInlinedImages
inrelease
inlineAllUrls
: treatsurl
asinline-image
inlineInlinedImages
: simply honoursinline-image
linkInlinedImages
: replacesinline-image
byurl
disablePass
: leavesinline-image
untouched
optimizePng
(boolean): by default,true
inrelease
onlyoptimizeSvg
(boolean): by default,true
inrelease
onlysasscPath
: default issassc
pngCrushPath
: default ispngcrush
Limitations #
- Assumes if foo.html exists, foo.css is only used from there (conventions
matter). This means sCiSSors should be disabled or used with caution when
using Angular2 with
ViewEncapsulation.None
(see section below). - Very limited support of CSS rules (naive and hopefully pessimistic matching),
- Bails out of pruning as soon as it doesn't recognize the (map literal)
syntax of an
ng-class
(or if the map has non-string-literal keys), - Does not detect direct / handle DOM manipulations done in .dart companion files yet (html:Element.classes, etc).
- No support for XML namespaces in CSS3 attribute selectors.
- No CSS renaming yet (just pruning for now),
- No Polymer.dart support yet.
Style Isolation in Angular #
Angular(1,2) provide the following strategies:
- Shadow DOM (default in AngularDart 1.x), implemented by
ShadowDomComponentFactory
in AngularDart 1.x andViewEncapsulation.Native
in Angular2 - Shadow DOM emulation with "transclusion" (default in Angular2) implemented by
TranscludingComponentFactory
in AngularDart 1.x andViewEncapsulation.Emulated
in Angular2 - Unscoped / no Shadow DOM, implemented by
ViewEncapsulation.None
in Angular2
The first two strategies (Shadow DOM & its transcluded emulation) provide strict encapsulation of style at the component level: styles defined in a component do not leak to any of its sub-components or parent components. This is the assumption by which sCiSSors lives, so you're safe with it.
The last "unscoped" strategy means there's no file- or component-local way of deciding if a style could be used elsewhere. You should not use sCiSSors on packages / projects with that strategy.
Using scissors/permutations_transformer
#
Example: see example/permutations.
pubspec.yaml
:
dev_dependencies:
scissors
transformers:
- scissors/permutations_transformer
Valid settings:
generatePermutations
:true
by defaultltrImport
andrtlImport
: unset by default. If you're deferred-loading LTR/RTL-specific template caches, these settings should take the alias you're importing them under. See example/permutations for a concrete example.expectedPartCounts
(map of .dart.js artifact to number of expected parts): unset by default. For instance:{ web/main.dart.js: 3 }
.reoptimizePermutations
:false
by default. Whether to optimize permutations with the Closure Compiler.closureCompilerJarPath
:compiler.jar
by defaultjavaPath
:java
by default.
Using scissors/reloader/transformer
#
This provides an amazing development turnaround experience, whether you're using the other sCiSSors transformers or not.
With pub serve --force-poll
, as soon as you save an asset (say, foo.scss
)
and it finished building the dependent assets (say, foo.scss.css
), the app
will reload. That's typically before you even have the time to tab-switch to
the browser (+ no need to Ctrl+R).
The transformer ensures the automatic reload logic is removed in release
builds (pub build
), without interfering with source maps.
Example: see example/permutations.
Just edit pubspec.yaml
(note: it's in dev_dependencies
, not dependencies
):
dev_dependencies:
scissors
transformers:
- scissors/reloader/transformer
And edit main.dart
:
import 'package:scissors/reloader/reloader.dart';
main() {
setupReloader();
...
}
Valid settings:
serveTimestamps
(boolean): by default,true
indebug
onlyremoveReloader
(boolean): by default,true
inrelease
only
TODO #
Please see issues.