• Stars
    star
    365
  • Rank 106,935 (Top 3 %)
  • Language
    Scala
  • License
    Other
  • Created about 10 years ago
  • Updated 23 days ago

Reviews

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

Repository Details

Library for building sbt plugins for the web

sbt-web

Build Status

This project provides the building blocks for web oriented sbt plugins by bringing together the following concerns:

  • File directory layout conventions for resources intended to be served by a web server (otherwise known as assets)
  • Incremental execution of fine-grained operations within sbt tasks
  • Utilities for managing WebJars including the ability to extract a WebJar's contents on to disk
  • Standardised reporting of compilation style errors

sbt-web was driven from the desire to factor out client-side web concerns from the Play Framework. However, sbt-web is entirely independent of Play and can be used for any project that uses sbt as its build system.

Available Plugins

The following is a list of plugins we know of that are built on sbt-web:

Ideas for Plugins

Plugins in Development

  • C'mon community, get involved! Watch the talk on the anatomy of an sbt-web plugin

File Directory Layout

The following directory layout is declared by sbt-web with an indication of the associated settings:

+ src
--+ main
----+ assets .....(Assets / sourceDirectory)
------+ js
----+ public .....(Assets / resourceDirectory)
------+ css
------+ images
------+ js
--+ test
----+ assets .....(TestAssets / sourceDirectory)
------+ js
----+ public .....(TestAssets / resourceDirectory)
------+ css
------+ images
------+ js

+ target
--+ web ............(webTarget)
----+ public
------+ main .......(Assets / resourceManaged)
--------+ css
--------+ images
--------+ js
------+ test .......(TestAssets / resourceManaged)
--------+ css
--------+ images
--------+ js
----+ stage ........(stagingDirectory)

The plugin introduces the notion of assets to sbt. Assets are public resources that are intended for client-side consumption e.g. by a browser. This is also distinct from sbt's existing notion of resources as project resources are generally not made public by a web server.

In sbt, asset source files are considered the source for plugins that process them. When they are processed any resultant files go into a public directory in the classpath. By configuration, sbt-web apps serve static assets from the public directory on the classpath. For example a CoffeeScript plugin would use files from Assets / sourceDirectory and produce them to Assets / resourceManaged.

All assets whether they need processing or are static in nature, will be copied to the resourceManaged destinations.

Assets can be organized however desired within the assets directory.

One last thing regarding the public and public-test folders... any WebJar depended on by the project will be automatically extracted into these folders e.g. target/web/public/main/lib/jquery/jquery.js. In addition, the public-test folder receives the contents of the public folder as well as test assets. This eases the support of test frameworks given that all files are locatable from one root.

The "stage" directory is product of processing the asset pipeline and results in files prepared for deployment to a web server.

Configurations

sbt holds the notion of configurations which are similar to Maven's phases. Configurations aggregate settings and tasks. Familiar configurations will be Compile and Test. sbt-web introduces two new configurations named Assets and TestAssets correlating roughly with Compile and Test, but for web assets.

Incremental Execution

The incremental task API lets tasks run more quickly when they are called more than once. The idea is to do less work when tasks are called a second time, by skipping any work that has already been done. In other words, tasks only perform the "incremental" work that is necessary since they were last run.

To analyse which work needs to be done, a task's work is broken up into a number of sub-operations, each of which can be run independently. Each operation takes input parameters and can read and write files. The incremental task API keeps a record of which operations have been run so that those operations don't need to be repeated in the future.

Asset Pipeline

There are two categories of sbt-web based tasks:

  • those that operate on source files
  • those that operate on web assets

Examples of source file tasks as plugins are CoffeeScript, LESS and JSHint. Some of these take a source file and produce a target web asset e.g. CoffeeScript produces JS files. Plugins in this category are mutually exclusive to each other in terms of their function i.e. only one CoffeeScript plugin will take CoffeeScript sources and produce target JS files. In summary, source file plugins produce web assets.

Asset tasks operate on web assets directly. The assets they operate on depend on a "stage" in the asset pipeline. Examples of web asset tasks as plugins include RequireJs optimisation, gzip and md5 hashing.

Source file tasks can be considered to provide files for the first stage of asset pipeline processing and they will be executed often e.g. for each compilation of your project's source files. Asset pipeline tasks are generally executed at the time that you wish to prepare a distribution for deployment into, say, production.

Exporting Assets

Assets are automatically available across subproject dependencies using sbt's classpath setup. The assets are exported in the webjar format and are imported in the same way as other webjar dependencies.

So given a project dependency like this, where project A depends on project B:

lazy val a = (project in file("a"))
  .enablePlugins(SbtWeb)
  .dependsOn(b)

lazy val b = (project in file("b"))
  .enablePlugins(SbtWeb)

Assets from project B are available to project A under lib/b/.

The module name for imported assets is the same as the project module name (the normalized name of the project). This can be changed with the Assets / moduleName setting.

Test assets are also exported if a test dependency is specified. For example:

lazy val a = (project in file("a"))
  .enablePlugins(SbtWeb)
  .dependsOn(b % "compile;test->test")

Packaging and Publishing

The packaging and publishing behavior is documented for sbt-web version 1.1.0 and above.

Assets are automatically packaged and published along with project classes at the following path inside the jar: META-INF/resources/webjars/module/version/. This means that assets can be shared as external library dependencies. Simply publish the project and use as a library dependency. The assets will be extracted and available under lib/module/ in the same way as other webjar dependencies or internal dependencies.

To package all assets for production there is a Assets / packageBin task, web-assets:package in the sbt shell. This packages the result of the asset pipeline. An optional path prefix can be specified with the packagePrefix in Assets setting. For example, to have assets packaged under a public directory, as used for Play Framework distributions:

Assets / WebKeys.packagePrefix := "public/"

To automatically add the production-ready assets to classpath, the following might be useful:

(Runtime / managedClasspath) += (Assets / packageBin).value

Writing a Source File task

The following represents the minimum amount of code required in a build.sbt to create a task that operates on source files i.e. those files that are available for processing from src/main/assets. Source file tasks are resource generators in sbt terms.

val mySourceFileTask = taskKey[Seq[File]]("Some source file task")

mySourceFileTask := Nil

Assets / sourceGenerators += mySourceFileTask.taskValue

The addition of the mySourceFileTask to Assets / sourceGenerators declares the task as a resource generator and, as such, will be executed in parallel with other resource generators during the WebKeys.assets task execution. Using sbt's show command will yield the directory where all source file assets have been written to e.g.:

show web-assets:assets

Source file tasks take input, typically from Assets / sourceDirectory (and/or TestAssets) and produce a sequence of files that have been generated from that input.

The following code illustrates a more complete example where input files matching *.coffee are taken and copied to an output folder:

mySourceFileTask := {
  // translate .coffee files into .js files
  val sourceDir = (Assets / sourceDirectory).value
  val targetDir = webTarget.value / "cs-plugin"
  val sources = sourceDir ** "*.coffee"
  val mappings = sources pair relativeTo(sourceDir)
  val renamed = mappings map { case (file, path) => file -> path.replaceAll("coffee", "js") }
  val copies = renamed map { case (file, path) => file -> (Assets / resourceManaged).value / path }
  IO.copy(copies)
  copies map (_._2)
}

Using the WebKeys.assets task will perform source file tasks in parallel. If you find yourself using a source file task across many projects then consider wrapping it with an sbt plugin. Example source file plugins are sbt-jshint, sbt-coffeescript and sbt-stylus.

As a final note, if you plugin depends on node modules e.g. those that are extracted from WebJars or from NPM, then you will need to have your task depend on the node module extraction task. The following illustrates how given the Assets scope:

mySourceFileTask := Def.task {
  Nil
}.dependsOn(Assets / WebKeys.nodeModules).value

If you're wrapping the task within a plugin then you will need the Plugin's scope as opposed to the Assets scope i.e.:

mySourceFileTask := Def.task {
  Nil
}.dependsOn(Plugin / WebKeys.nodeModules).value

Writing an Asset Pipeline task

The following represents the minimum amount of code required to create a pipeline stage in a build.sbt file:

import com.typesafe.sbt.web.pipeline.Pipeline

val myPipelineTask = taskKey[Pipeline.Stage]("Some pipeline task")

myPipelineTask := identity

pipelineStages := Seq(myPipelineTask)

myPipelineTask is a function that receives a Seq[PathMapping] and produces a Seq[PathMapping]. PathMapping is a tuple of (File, String) where the first member provides the full path to a file, and the second member declares the portion of that path which is to be considered relative. For example (file("/a/b/c"), "b/c"). PathMapping` types are commonly used in sbt and are useful in terms of providing access to a file and preserving information about its relative path; the latter being typically useful for copying files to a target folder where the relative portion of the path must be retained.

In the above example an identity function is used i.e. what is passed in is simply returned. The task is included within a sequence and assigned to pipelineStages i.e. the sequence represents the asset pipeline. Each stage in the asset pipeline is executed after any previous stage has completed. A stage therefore receives the product of files any previous stage as input. A stage's output then becomes the input to any subsequent stage. The first stage will always receive the output of having executed source file tasks as its input.

If you have some need for the assets produced by the pipelineStages in your development environment (during play run), then you can scope the pipelineStages to the Assets config.

Assets / pipelineStages := Seq(myPipelineTask)

To perform the asset pipeline tasks use the WebKeys.stage task. If you use sbt's show command from the console then you will see the directory that the pipeline has been written to e.g.:

show web-stage

Returning what is passed in is not particularly useful. Stages tend to add and remove files from the input as expressed in the output returned. The following expanded task simulates minifying some js files and consequently adds files to the pipeline:

myPipelineTask := { mappings: Seq[PathMapping] =>
  // pretend to combine all .js files into one .min.js file
  val targetDir = webTarget.value / "myPipelineTask" / "target"
  val (js, other) = mappings partition (_._2.endsWith(".js"))
  val minFile = targetDir / "js" / "all.min.js"
  IO.touch(minFile)
  val minMappings = Seq(minFile) pair relativeTo(targetDir)
  minMappings ++ other
}

If you find yourself commonly using a pipeline stage task across projects then you should consider wrapping it with an sbt plugin. Examples of such plugins are sbt-digest, sbt-gzip, sbt-rjs and sbt-uglify. The first two illustrate stages implemented using JVM based libraries while the latter two illustrate invoking JavaScript via js-engine.

WebDriver and js-engine

The WebDriver and js-engine projects build on sbt-web and provide a DOM oriented and DOM-less means of JavaScript execution respectively. sbt-web plugins will use one of the two of these plugins depending on their DOM requirements.

Releasing sbt-web

  1. Tag the release: git tag -s 1.2.3
  2. Push tag: git push upstream 1.2.3
  3. GitHub action workflow does the rest: https://github.com/sbt/sbt-web/actions/workflows/publish.yml

More Repositories

1

sbt

sbt, the interactive build tool
Scala
4,685
star
2

sbt-native-packager

sbt Native Packager
Scala
1,577
star
3

sbt-dependency-graph

sbt plugin to create a dependency graph for your project
Scala
1,246
star
4

sbt-jmh

"Trust no one, bench everything." - sbt plugin for JMH (Java Microbenchmark Harness)
Scala
774
star
5

sbt-eclipse

Plugin for sbt to create Eclipse project definitions
Scala
721
star
6

sbt-release

A release plugin for sbt
Scala
630
star
7

sbt-buildinfo

I know this because build.sbt knows this.
Scala
541
star
8

sbt-git

A git plugin for sbt
Scala
342
star
9

zinc

Scala incremental compiler library, used by sbt and other build tools
Scala
314
star
10

docker-sbt

Official sbt docker images
Dockerfile
301
star
11

sbt-dynver

An sbt plugin to dynamically set your version from git
Scala
286
star
12

sbt-ci-release

sbt plugin to automate Sonatype releases from GitHub Actions
Scala
270
star
13

sbt-onejar

Packages your project using One-JARβ„’
Scala
268
star
14

sbt-scalariform

sbt plugin adding support for source code formatting using Scalariform
Scala
259
star
15

sbt-fresh

sbt-plugin to create an opinionated fresh sbt project
Scala
235
star
16

sbt-header

sbt-header is an sbt plugin for creating file headers, e.g. copyright headers
Scala
190
star
17

sbt-github-actions

An sbt plugin which makes it easier to build with GitHub Actions
Scala
185
star
18

sbt-bintray

fresh packages delivered from your sbt console
Scala
180
star
19

sbt-site

Site generation for sbt
Scala
176
star
20

sbt-protobuf

sbt plugin for compiling protobuf files
Scala
173
star
21

sbt-start-script

SBT Plugin to create a "start" script to run the program
Scala
144
star
22

sbt-pgp

PGP plugin for sbt
Scala
141
star
23

sbt-groll

sbt plugin to roll the Git history
Scala
134
star
24

junit-interface

Implementation of sbt's test interface for JUnit
Java
132
star
25

sbt-unidoc

sbt plugin to create a unified Scaladoc or Javadoc API document across multiple subprojects.
Scala
124
star
26

sbt-jni

SBT Plugin to ease working with JNI
Scala
122
star
27

sbt-jacoco

an sbt plugin for JaCoCo Code Coverage
Scala
122
star
28

sbt-projectmatrix

Scala
114
star
29

sbt-boilerplate

sbt plugin for generating scala.Tuple/Function related boilerplate code
Scala
110
star
30

sbt-proguard

Proguard sbt plugin
Scala
99
star
31

sbt-atmos

sbt plugin for running Typesafe Console in development
Scala
98
star
32

sbt-launcher-package

Packaging for sbt so you can run it.
Scala
90
star
33

sbt-dirty-money

clean Ivy2 cache
Scala
87
star
34

sbt-license-report

Report on licenses used in an sbt project.
Scala
85
star
35

sbt-doge

sbt plugin to aggregate tasks across subprojects and their crossScalaVersions
Scala
78
star
36

website

The source for scala-sbt.org
Scala
74
star
37

sbt-pom-reader

Translates xml -> awesome. Maven-ish support for sbt.
Scala
74
star
38

sbt-aspectj

AspectJ sbt plugin
Scala
73
star
39

sbt-remote-control

Create and manage sbt process using unicorns and forks
Scala
73
star
40

sbt-scalabuff

SBT plugin which generate case classes and support for serialization from Google Protocol Buffer definitions using ScalaBuff
Scala
72
star
41

contraband

http://www.scala-sbt.org/contraband/
Scala
68
star
42

sbt-s3

sbt-s3 is a simple sbt plugin to manipulate objects on Amazon S3
Scala
62
star
43

sbt-multi-jvm

Multi-JVM testing in sbt
Scala
53
star
44

sbt-javaagent

sbt plugin for adding java agents to projects
Scala
52
star
45

sbt-cpd

Copy & Paste Detector plugin using PMD for sbt.
Scala
49
star
46

sbt-findbugs

FindBugs static analysis plugin for sbt.
Scala
47
star
47

sbt-man

Looks up scaladoc.
Scala
46
star
48

librarymanagement

librarymanagement module for sbt
Scala
46
star
49

sbt-osgi

sbt plugin for creating OSGi bundles
Scala
45
star
50

io

IO module for sbt
Scala
41
star
51

sbt-less

Scala
41
star
52

sbt-js-engine

Support for sbt plugins that use JavaScript
Scala
40
star
53

launcher

The sbt launcher as its own project. Can launch any ivy/maven published project with a main class, with some fancy features.
Scala
40
star
54

ipcsocket

IPC: Unix Domain Socket and Windows Named Pipes for Java
Java
38
star
55

sbt-autoversion

Scala
34
star
56

sbt-digest

sbt-web plugin for checksum files
Scala
30
star
57

sbt-jupiter-interface

Implementation of SBT's test interface for JUnit Jupiter
Java
29
star
58

sbt-slash

unified slash syntax for both shell and build.sbt
Scala
29
star
59

sbt-avro

sbt plugin for compiling Avro schemas, similar to sbt-protobuf
Java
26
star
60

sbt-java-formatter

An sbt plugin for formating Java code
Scala
25
star
61

sbt-unique-version

emulates Maven's uniqueVersion snapshots
Scala
24
star
62

sbt-gzip

sbt-web plugin for gzipping assets
Scala
24
star
63

sbt.github.com

See https://github.com/sbt/website for the source
HTML
22
star
64

sbt-duplicates-finder

Find classes and resources conflicts in your build
Scala
22
star
65

sbt-pull-request-validator

Plugin that optimizes pull request validation to only validate sub projects that have changed
Scala
21
star
66

sbt-autoplugin.g8

giter8 template for sbt 0.13.5+ AutoPlugin
Scala
20
star
67

sbt-cucumber

Cucumber plugin for SBT.
Scala
20
star
68

sbt-jcstress

Trust no-one, and especially not memory visibility.
HTML
19
star
69

sbt-sriracha

Scala
18
star
70

adept

adept helps you find, declare, and download dependencies. http://groups.google.com/group/adept-dev/
18
star
71

sbt-mocha

SBT plugin for running mocha JavaScript unit tests on node
Scala
17
star
72

util

util modules for sbt
Scala
15
star
73

sbt-export-repo

exports your dependency graph to a preloaded local repository
Scala
15
star
74

sbt-xjc

SBT plugin to compile an XML Schema with XJC
Scala
14
star
75

sbt-multi-release-jar

Support for JDK9's Multi Release JAR Files (JEP 238)
Scala
14
star
76

sbt-nocomma

sbt-nocomma reduces commas from your build.sbt.
Scala
13
star
77

serialization

serialization facility for sbt
Scala
13
star
78

sbt-core-next

sbt APIs targeted for eventual inclusion in sbt core
Scala
12
star
79

sbt-houserules

House rules for sbt modules.
Scala
12
star
80

sbt-maven-resolver

An sbt plugin to resolve dependencies using Aether
Scala
11
star
81

sbt-pamflet

sbt plugin to run Pamflet (and Pamflet plugin to run sbt)
Scala
11
star
82

sbt-appbundle

A plugin for the simple-build-tool to create an OS X application bundle.
Scala
10
star
83

sbt-sdlc

Scaladoc link checker for sbt
Scala
10
star
84

bintry

your packages, delivered fresh
Scala
10
star
85

sbt-fmpp

FreeMarker Scala/Java Templating Plugin for SBT
Scala
9
star
86

sbt-ynolub

Scala
9
star
87

sbt-testng

Implementation of the sbt testing interface for TestNG, bundled with an sbt plug-in for convenience.
Scala
9
star
88

sbt-concat

sbt-web plugin for concatenating web assets
Scala
8
star
89

sbt-ant

SBT plug-in to call Ant targets from within SBT builds
Scala
7
star
90

sbt-community-plugins

All community plugins that opt into an uber-build
Scala
6
star
91

helloworld-one

An example build for sbt 1.0.0.
Scala
5
star
92

sbtn-dist

Shell
5
star
93

sbt-giter8-resolver

Scala
5
star
94

sbt-vimquit

an sbt plugin that adds :q command.
Scala
4
star
95

sbt-sequential

adds sequential tasks to sbt
Scala
4
star
96

sbt-scalashim

generates sys.error.
Scala
4
star
97

sbt-experimental

Experimental APIs to fix rough edges in sbt
Scala
3
star
98

sbt-web-build-base

Scala
3
star
99

sbt-validator

Builds sbt 1.0.x against recent versions of the sbt modules
Shell
3
star
100

sbt-dbuild

Scala
3
star