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)
Finds which .css rules are not used by Angular templates and removes them.
Supports ng-class and class 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.
CSS mirroring / bidirectionalization that works with Angular2’s transformer:
Uses CSSJanus to produce a single CSS file that supports both RTL & LTR layouts!
Given foo { color: blue; float: left }, it generates:
foo { color: blue; }
:host-context([dir="ltr"]) foo { float: left }
:host-context([dir="rtl"]) foo { float: right }
So you just need the supporting code in your main.dart to support bidirectional layouts (see example/mirroring):
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:
If you checked out scissors‘s sources, you can run . ./script/install_dependencies.sh to get all the required dependencies, and skip the rest of this section :-)
Installing CSSJanus
You’ll need a local install of CSSJanus for CSS mirroring.
Note that this transformer uses Google’s original cssjanus.py, not its .js port (github.com/cssjanus/cssjanus, which might work if packaged as a binary that consumes css from stdin and outputs mirrored css on stdout).
To install CSSJanus, run the following command in a console (ensure you have something like export PATH=~/bin:$PATH in your ~/.profile or ~/.bashrc):
optimizePng (boolean): by default, true in release only
optimizeSvg (boolean): by default, true in release only
sasscPath: default is sassc
compiledCssExtension: default is append
append: append the .css extension to the SASS / SCSS file name: foo.scss will be compiled to foo.scss.css.
replace: replace the SASS / SCSS file extension by .css: foo.scss will be compiled to foo.css.
pngCrushPath: default is pngcrush
bidiCss (boolean): default is false (note that this is true by default in the scissors/css_mirroring_transformer, see below)
cssJanusPath: cssjanus.py by default, see prerequisites
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.
Shadow DOM (default in AngularDart 1.x), implemented by
ShadowDomComponentFactory in AngularDart 1.x and ViewEncapsulation.Native
in Angular2
Shadow DOM emulation with “transclusion” (default in Angular2) implemented by
TranscludingComponentFactory in AngularDart 1.x and ViewEncapsulation.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.
bidiCss (boolean): true by default (Note: this is not the same default as in the scissors transformer)
originalCssDirection (ltr or rtl): ltr by default, defines the direction of input css.
cssJanusPath: cssjanus.py by default.
Limitations
The standalone scissors/css_mirroring_transformer transformer only consumes CSS files. If you need Sass support, please use the scissors transformer with bidiCss: true.
Does not handle directives like @keyframes and @page.
ltrImport and rtlImport: 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 }.
stripSourceMaps: false by default.
Removes the sourceMappingURL links from all generated .js files, to avoid
provoking 404s in production when sourcemaps aren’t served (relevant only
when the $dart2js transformer has setting sourceMaps: true).
reoptimizePermutations: false by default.
Whether to optimize permutations with the Closure Compiler.
closureCompilerJarPath: compiler.jar by default
javaPath: 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.
Keep in mind that this transformer is very experimental, and slow.
It aims to complement Dart’s new strong-mode analyzer with more static checks,
some of which could eventually graduate to the analyzer itself.
sCiSSors

Smarter resources for Angular apps: CSS pruning, bidirectional layouts, 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 servein debug mode. (note: may needpub serve --force-pollon MacOS X)CSS pruning for Angular (see example/angular1, example/angular2):
ng-classandclasswith programmatic interpolated fragments (e.g.class="some-{{fragmented}}-class and-some-normal-class",ng-class="{'some-class': isSome}").CSS mirroring / bidirectionalization that works with Angular2’s transformer:
Uses CSSJanus to produce a single CSS file that supports both RTL & LTR layouts!
Given
foo { color: blue; float: left }, it generates:So you just need the supporting code in your
main.dartto support bidirectional layouts (see example/mirroring):Sass compilation:
*.sassand*.scssfiles withsassc, the lightning-fast C++ port of Ruby Sass..cssfiles whenever their.sasssources are modified.Image inlining:
PNG optimization:
pngcrushto remove all metadata that is useless for rendering.SVG optimization:
Locale-specific permutations generation (Optional, see example/permutations):
main_en.js,main_fr.js…) with the deferred parts needed for that locale, which speeds up load time..jsfiles with the Closure Compiler.Automatic reload support (Optional): zero-turnaround for Dart!
Experimental static checker that detects unawaited futures (a common cause of sneaky bugs in async code):
Usage
Defaults vs. debug vs. release
sCiSSors is fine-tuned for fast build in
debugmode (default forpub serve) and small code size inreleasemode (default forpub 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 indebugonly:Prerequisites
If you checked out
scissors‘s sources, you can run. ./script/install_dependencies.shto get all the required dependencies, and skip the rest of this section :-)Installing CSSJanus
You’ll need a local install of CSSJanus for CSS mirroring.
Note that this transformer uses Google’s original cssjanus.py, not its .js port (github.com/cssjanus/cssjanus, which might work if packaged as a binary that consumes css from stdin and outputs mirrored css on stdout).
To install CSSJanus, run the following command in a console (ensure you have something like
export PATH=~/bin:$PATHin your~/.profileor~/.bashrc):Other deps: SassC, pngcrush…
These packages are quite standard, you can get them with
brew installon MacOS X and withsudo apt-get installon Ubuntu:sasscpngcrushUsing the
scissorstransformerThe default transformer will build Sass files in a blink of an eye and will optimize CSS, PNG and SVG assets in
releasemode (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:Valid settings:
pruneCss(boolean):falseby defaultimageInlining: default isinlineInlinedImagesinlineAllUrls: treatsurlasinline-imageinlineInlinedImages: simply honoursinline-imagelinkInlinedImages: replacesinline-imagebyurldisablePass: leavesinline-imageuntouchedoptimizePng(boolean): by default,trueinreleaseonlyoptimizeSvg(boolean): by default,trueinreleaseonlysasscPath: default issassccompiledCssExtension: default isappendappend: append the.cssextension to the SASS / SCSS file name:foo.scsswill be compiled tofoo.scss.css.replace: replace the SASS / SCSS file extension by.css:foo.scsswill be compiled tofoo.css.pngCrushPath: default ispngcrushbidiCss(boolean): default isfalse(note that this istrueby default in thescissors/css_mirroring_transformer, see below)cssJanusPath:cssjanus.pyby default, see prerequisitesLimitations
ViewEncapsulation.None(see section below).ng-class(or if the map has non-string-literal keys),Style Isolation in Angular
Angular(1,2) provide the following strategies:
ShadowDomComponentFactoryin AngularDart 1.x andViewEncapsulation.Nativein Angular2TranscludingComponentFactoryin AngularDart 1.x andViewEncapsulation.Emulatedin Angular2ViewEncapsulation.Nonein Angular2The 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/css_mirroring_transformerSee BidirectionalCss for more details.
Example: see example/mirroring.
pubspec.yaml:Valid settings:
bidiCss(boolean):trueby default (Note: this is not the same default as in thescissorstransformer)originalCssDirection(ltrorrtl):ltrby default, defines the direction of input css.cssJanusPath:cssjanus.pyby default.Limitations
scissors/css_mirroring_transformertransformer only consumes CSS files. If you need Sass support, please use thescissorstransformer withbidiCss: true.@keyframesand@page.Using
scissors/permutations_transformerExample: see example/permutations.
pubspec.yaml:Valid settings:
generatePermutations:trueby defaultltrImportandrtlImport: 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 }.stripSourceMaps:falseby default. Removes thesourceMappingURLlinks from all generated.jsfiles, to avoid provoking 404s in production when sourcemaps aren’t served (relevant only when the$dart2jstransformer has settingsourceMaps: true).reoptimizePermutations:falseby default. Whether to optimize permutations with the Closure Compiler.closureCompilerJarPath:compiler.jarby defaultjavaPath:javaby default.Using
scissors/reloader/transformerThis 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
releasebuilds (pub build), without interfering with source maps.Example: see example/permutations.
Just edit
pubspec.yaml(note: it’s indev_dependencies, notdependencies):And edit
main.dart:Valid settings:
serveTimestamps(boolean): by default,trueindebugonlyremoveReloader(boolean): by default,trueinreleaseonlyUsing
scissors/src/checker/transformerto detect unawaited futuresSee UnawaitedFutures for more details.
Keep in mind that this transformer is very experimental, and slow. It aims to complement Dart’s new strong-mode analyzer with more static checks, some of which could eventually graduate to the analyzer itself.
Example:
pubspec.yaml:Valid settings:
unawaitedFutures(ignore,warningorerror):warningby defaultDevelopment
For things to do, please see issues.
To setup dependencies, please run:
This will download some executables used by Scissors and will export the following environment vars
SASSC_BINCSSJANUS_BINCLOSURE_COMPILER_JARPNGCRUSH_BINPlease run the following command to test your changes + reformat + analyze sources:
Please never force-push to
master: usegit revertto revert changes.