scalajs-bundler
scalajs-bundler copied to clipboard
...-loader.js refers window even if target is node
I am trying to use scalajs-bundler to bundle app and node_modules into one file, targeting to node.js runtime. However, when the bundled file (...-bundle.js) is invoked on node. a ReferenceError (window is not defined) occurs.
Environment
- sbt-scalajs-bundler: "0.12.0"
- sbt-scalajs: "0.6.22"
- build.sbt
lazy val foo= Project("foo")
.enablePlugins(ScalaJSPlugin)
.enablePlugins(ScalaJSBundlerPlugin)
.settings(
webpackBundlingMode := BundlingMode.LibraryAndApplication(),
emitSourceMaps := false,
webpackConfigFile in fastOptJS := Some(baseDirectory.value / "webpack.config.js"),
webpackConfigFile in fullOptJS := Some(baseDirectory.value / "webpack.config.js")
)
// other settings
- webpack.config.js (Since scalajs-bundler is very limited to configure webpack):
var config = require("./scalajs.webpack.config.js");
config.target = "node";
config.output.libraryTarget = "commonjs2";
config.externals = ["aws-sdk"];
module.exports = config;
What happens
In the above circrumstance, the generated foo-opt-loader.js is like below
var exports = window;
exports.require = window["ScalaJSBundlerLibrary"].require;
I believe these lines causes window is not defined error.
I referred Output- Webpack and tried several output.libraryTarget such as var (default of scalajs-bundler), this, commonjs and commonjs2.
It looks like foo-opt-library.js respects output.libraryTarget config and changes its form.
However, foo-opt-loader.js does not respect the config and keep var exports = window line.
Any ideas?
I suspects these lines. https://github.com/scalacenter/scalajs-bundler/blob/b80a1b9763769d5ab43bc4e54c7abf75c60a4ac1/sbt-scalajs-bundler/src/main/scala/scalajsbundler/util/JSBundler.scala#L9-L13
I am trying to use scalajs-bundler to bundle app and node_modules into one file, targeting to node.js runtime.
If you target the Node.js runtime, you shouldn't even bundle. Node.js can load the non-bundled CommonJS module in the regular fastopt.js.
Bundling is for browsers. It doesn't make sense for Node.js.
Ah, I see why it generates var exports = window.
I expected webpack, not only to bundle dependencies, but also to minify them, for environment where sizes matter. More specifically, it is AWS Lambda and similar Function as a Service. Minifying node_module is not uncommon for the domain. E.g., https://github.com/serverless/serverless-optimizer-plugin is for such purpose.
Webpack can minimize but you need to configure it. E.g. with the uglify plugin
@cquiroz Thanks for let me know the uglify plugin.
Can we use such plugin with scalajs-bundler, without fixing loader script (var exports = window)?
Those are independent concepts. I think the window call is very much fixed on the creation of webpack’s config for scala js
any idea what can cause this error to occur? I randomly get it also. I usually need to delete my target directories in my sbt project and rebuild.
In my chrome browser console, it says:
Uncaught TypeError: Cannot read property 'require' of undefined at client-fastopt-loader.js:3
and all there is in that file is:
var exports = window;
exports.require = window["ScalaJSBundlerLibrary"].require;