build method
Generates the outputs for a given BuildStep
.
Implementation
@override
Future build(BuildStep buildStep) async {
final inputId = buildStep.inputId;
if (p.basename(inputId.path).startsWith('_')) {
// Do not produce any output for .scss partials.
log.fine('skipping partial file: $inputId');
return;
}
// Compile the css.
log.fine('compiling file: ${inputId.uri.toString()}');
final compileResult = await sass.compileStringToResultAsync(
await buildStep.readAsString(inputId),
syntax: sass.Syntax.forPath(inputId.path),
importers: [BuildImporter(buildStep)],
style: _getValidOutputStyle(),
url: inputId.uri,
sourceMap: _generateSourceMaps,
);
var cssOutput = compileResult.css;
final sourceMapId = inputId.changeExtension('.css.map');
if (_generateSourceMaps) {
// Add the source mapping information to the generated css
final import = p.url.basename(sourceMapId.path);
cssOutput += '\n\n/*# sourceMappingURL=$import */';
}
Future<void> writeCss() async {
final outputId = inputId.changeExtension(_outputExtension);
await buildStep.writeAsString(outputId, '$cssOutput\n');
log.fine('wrote css file: ${outputId.path}');
}
Future<void> writeSourceMaps() async {
final map = compileResult.sourceMap!.toJson();
// We need to replace source map uris to reflect the paths generated by
// Dart's build system.
final sources = List<String>.of(map['sources']);
for (var i = 0; i < sources.length; i++) {
final uri = Uri.tryParse(sources[i]);
if (uri == null) continue;
final asset = AssetId.resolve(uri, from: inputId);
if (p.url.isWithin('lib', asset.path)) {
// The source is in lib/, which means that webdev and friends will
// serve it under `/packages/<package>/<source_in_lib>`
sources[i] = p.url.join('packages', asset.package,
p.url.relative(asset.path, from: 'lib'));
} else if (asset.package == inputId.package) {
// Assets from the root package are included if they're in web/, so
// we might have a chance to still recover the source.
if (p.url.isWithin('web', asset.path)) {
sources[i] = p.url.relative(asset.path, from: 'web');
}
}
}
map['sources'] = sources;
await buildStep.writeAsString(sourceMapId, json.encode(map));
}
await Future.wait([
writeCss(),
if (_generateSourceMaps) writeSourceMaps(),
]);
}