Skip to content

MaximeKjaer/scalajs-webpack-loader

Repository files navigation

scalajs-webpack-loader

Webpack logo Scala.js logo

Webpack loader for Scala.js.
Import Scala.js code in a Webpack project, without having to set up a separate Scala build.

Build Status npm version Gitter

scalajs-webpack-loader is similar to scalajs-bundler in that it is a tool that uses Webpack to bundle Scala.js code alongside JavaScript code. Use scalajs-bundler if your build tool is SBT, and use scalajs-webpack-loader if your build tool is Webpack.

The loader supports Scala.js 1.x. It should also work on Scala.js 0.6.15 – 0.6.33, but note that only 1.x is tested for and explicitly supported.

Installing

Install scalajs-webpack-loader as a dev-dependency of your NPM package by running:

$ npm install --save-dev scalajs-webpack-loader

scalajs-webpack-loader currently requires at least Node v10.0. Check your version using:

$ node -v

Usage

Basic usage

This example assumes the following directory structure:

├── src/
|   ├── js/
|   |   └── index.js
|   └── scala/
|       ├── .sjsproject
|       └── HelloWorld.scala
├── webpack.config.js
└── package.json

scalajs-webpack-loader allows you to import a Scala.js module into another Webpack module. A Scala.js module is a directory containing *.scala files, with an empty .sjsproject file at the root. Here, we can define HelloWorld.scala as follows:

import scalajs.js.annotation._

@JSExportTopLevel("HelloWorld")
object HelloWorld {
  @JSExport
  def sayHello(): Unit = {
    println("Hello world!")
  }
}

You can then import the Scala.js module in index.js as follows:

import { HelloWorld } from "../scala/.sjsproject";

HelloWorld.sayHello();

You should add scalajs-webpack-loader to your webpack.config.js:

module.exports = {
  // Configure entry and output paths:
  entry: "src/js/index.js",
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "bundle.js"
  },
  // ...
  // Add scalajs-webpack-loader:
  module: {
    rules: [
      {
        test: /\.sjsproject$/,
        use: [
          {
            loader: "scalajs-webpack-loader",
            options: {
              // verbosity: "warn",
              // mainMethod: "Main.main",
              // etc. See "Loader options" below
            }
          }
        ]
      }
    ]
  }
};

Run npx webpack to create the output bundle. The loader will download dependencies, compile the Scala.js code to the target folder, and bundle it with the JS module. Executing the output bundle in Node.js gives the following output:

$ node dist/bundle.js
Hello world!

Loader options

Option key Type Default Description
mainMethod string or undefined undefined Execute the specified main(Array[String]) method on startup
verbosity "trace", "debug", "info", "warn", "error" or "silent" "info" Do not display log levels below specified verbosity
targetDirectory string "target" Target directory for intermediary Scala build artifacts
scalaVersion string "2.13.1" Version of the Scala compiler
scalaJSVersion string "1.0.0" Version of the Scala.js compiler
libraryDependencies array of strings [] List of Scala.js dependencies, e.g. ["com.lihaoyi:::upickle:0.9.9"]
scalacOptions array of strings [] List of scalac options, e.g. ["-Xfatal-warnings"]

For the libraryDependencies options, use the Mill format for dependencies. You can use Scaladex to see what that looks like for your specific dependencies. Use ::: to get the Scala.js artifact (e.g. com.lihaoyi:::upickle:0.9.9), and :: for the Scala artifact (e.g. org.scala-lang.modules::scala-async:0.10.0).

Development

To develop the code in this repo, you will need to have sbt and npm installed on your system. Run npm install after cloning the repo to get all JS dependencies of this project.

All development commands can be run with NPM. Note that some of these commands depend on the NODE_ENV environment variable, which can either be set to production or development; if it isn't set, it's interpreted as development. Depending on the environment variable, some commands will execute in development (fast) mode or in production (slow, optimized) mode.

npm run ... Description
build Run a full build
build:scalajs Build Scala.js sources in mode dictated by NODE_ENV
build:scalajs:production Build Scala.js sources in production mode (fullOptJS)
build:scalajs:development Build Scala.js sources in development mode (fastOptJS)
build:bundle Build final output bundle in mode dictated by NODE_ENV
test Run all tests
test:package Test that package.json is valid
test:format:scala Test formatting of Scala files with scalafmt
test:format:js Test formatting of JS and config files
test:integration Run integration tests
test:unit Run Scala.js unit tests
fix Run all automatic fixes
fix:format:scala Run scalafmt fixes for all Scala files
fix:format:js Run Prettier fixes for all JS and config files
clean Delete all build artifacts
clean:scalajs Delete Scala.js build artifacts
clean:bundle Clean Webpack's dist/bundle.js
clean:fixtures Clean local caches and build artifacts from integration test fixtures

Remember to build before testing.

Scalafmt commands try to run the CLI, and fall back to using SBT. If you run these commands frequently, you may want to install the scalafmt CLI for faster execution of these commands (coursier install scalafmt if you have Coursier installed on your PATH).

To release a new version, run npm version patch, npm version minor or npm version major. Travis CI will automatically deploy the new version once the CI build passes.