- How to use a custom webpack configuration file?
- Sharing webpack configuration among configuration files
- How to use npm modules from Scala code?
- How to publish a facade for an npm module?
- How to use an existing facade assuming the JS library to be exposed to the global namespace?
- How to bundle an application having several entry points as exports?
- How to improve the performance of the bundling process?
- How to select specific files from the BundlingMode.Library output
- How to rebuild and reload your page on code changes?
- How to pass extra parameters to webpack
- How to use webpack 4
- How to get and use a list of assets
First, configure the
webpackConfigFile setting to refer to your configuration file:
Or, if you want to use the same configuration file for both
Then, you can write your configuration in file
We recommend that you reuse the configuration file generated by scalajs-bundler
and extend it, rather than writing a configuration file from scratch.
You can do so as follows (in file `my.custom.webpack.config.js``):
The key part is the
require('./scalajs.webpack.config'). It loads the configuration
file generated by scalajs-bundler so that you can tweak it. It works because your configuration
file will be copied into the internal target directory, where the scalajs-bundler generates
its configuration file, and where all the npm dependencies have been downloaded (so you can
require these dependencies).
webpack task only actually launches webpack if it detects changes in
settings or in the custom webpack config file. Depending on your usage scenario, you might
want to monitor some other files as well (for example, if your webpack config references
some additional resources). This can be achieved by using
More fine-grained control over the list of monitored files is possible by overriding the
You can find a working example of custom configuration file here.
It is also possible to configure a webpack config file to be used in reload workflow and when running the tests.
This configuration may not contain
output configuration but can be used to configure loaders etc.
These configuration files are configured using
webpackConfigFile in reloadTask or
webpackConfigFile in Test.
In addition to the configured webpack config file, all .js files in the project base directory
(as configured using the
webpackResources setting) are copied to the target directory so they can be imported
from the various configuration files.
Here are the steps to share the loader configuration among your prod and dev config files. This uses webpack-merge for convenience. The same result could be accomplished using plain js only.
- Put configuration in a common.webpack.config.js file:
- Add webpack-merge to your
- Merge in the common configuration in your dev.webpack.js file:
You can find a working example of a project using a shared configuration file here.
Once you have added npm dependencies to the packages you are interested in, you have to import them from your code to effectively use them.
The recommended way to do that is to:
Let’s illustrate this with an example. Say that you want to write a facade for the following npm module:
The corresponding Scala.js facade looks like the following:
There are several points worth highlighting:
- The first parameter of the
@JSImportannotation is the npm module path. This is the value you would pass to the Nodejs
- The second parameter of
@JSImportis the name of the imported member, or like in our case,
JSImport.Namespace, to import the whole module instead of just one particular member ;
- The facade is concrete. It can either be a Scala
- The facade has a “JS native” type.
Finally, in your Scala code, just refer to the
Create a project for the facade and enable the
ScalaJSBundlerPlugin as described
Implement the facade as explained in the above section.
Publish the Scala.js project as usual.
Finally, to use the facade from another Scala.js project, this one needs both to add a
dependency on the facade and to enable the
Projects that use the facade also have to enable the
ScalaJSBundlerPluginplugin, otherwise the dependencies of the facade will not be resolved.
Webpack is able to require external modules by using imports-loader and expose them to the global namespace by using expose-loader. Thus, you can write a custom webpack configuration file that uses this loaders to expose the required modules to the global namespace. Typically, this file will look like this:
Also, tweak your
build.sbt to add the corresponding NPM dependencies and to use the
custom webpack configuration file:
You can find a fully working example here.
ScalaJSBundlerPlugin assumes that your application only has a main class, activated through
scalaJSUseMainModuleInitializer := true, and disregards top-level exports. If you have exports that
need to be exposed as several entry points, this will not work.
In such a case, you can use
Then, assuming that you defined the following library:
You can enable the library-only bundling mode and disable source maps:
In library-only bundling mode and
library with application bundling mode, the
produces multiple files. In order to determine which of these files is, for instance, the
can use the
_.metadata property of the files, like this:
scalajs-bundler includes a simple wrapper over webpack-dev-server to simplify your
workflow. It is exposed as two stage-level tasks (
The standard work session looks like this:
- Spawn background server process:
By default the server is started on port
webpackDevServerPortsetting to change this.
- Instruct SBT to rebuild on source changes:
- Now each time you change a source file, Scala.js recompiles it, and webpack-dev-server switches to the updated version.
- Shut down the background process:
Additional arguments can be passed to webpack-dev-server via
setting. For example, you can add the following to your
build.sbt to make your page
reload on every change:
webpack with a configuration generated either automatically from the build or set with
webpack is then called with the following arguments:
You can add extra params to the
webpack call, for example, to increase debugging
Note Params are passed verbatim, they are not sanitized and could produce errors when passed to webpack.
In particular, don't attempt to override the
scalajs-bundler (version 0.12.0 onwards) supports webpack 4. To enable webpack 4, set the correct versions in
Additionally, you need to update any webpack plugins your config uses, to Webpack 4 compatible versions.
Webpack 4 has the potential to substantially reduce your webpack compilation times (80% reductions have been observed but your mileage may vary)
scalajs-bundler (version 0.13.0 onwards) will export a list of all assets produced by webpack. You can read that list on sbt
You can this list e.g. with sbt-native-packager` to add mappings as:
This will add all artifacts produced by the fully optimized Scala.JS run to the 'assets' directory of the target archive.
If you need to package additional libraries that have been downloaded by
scalajs-bundler, you can do something like:
Also, any static resources that you would like to have in the resulting archive (i.e.
index.html), should live inside the
src/universal directory of your project.