diff --git a/README.md b/README.md index 57f0235..1dc26c2 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ # Scala.js Webpack loader -[![npm](https://img.shields.io/npm/v/scalajs-loader.svg)](https://www.npmjs.com/package/scalajs-loader) +[![npm](https://img.shields.io/npm/v/scalajs-loader.svg)](https://www.npmjs.com/package/@aappddeevv/scalajs-loader) + +This is an updated version from [https://github.com/mrdziuban/scalajs-loader](https://github.com/mrdziuban/scalajs-loader). ### Usage @@ -31,3 +33,30 @@ Make sure you have the `sbt` binary somewhere in your `PATH`. ### Example Check out the [example](example) directory for a simple Hello World example. + +### Options +Options can be provided to specify the scalajs stage, fullOptJS or fastOptJS. +```js +... as above ... +{ + test: /\.scala$/, + loader: 'scaljs-loader', + options: { + jsStage: 'fullOptJS', + clean: true + } +} +``` +An additional option `dirSegment` appends a directory segment after the standard +scalajs target output directory (such as target/scala-2.12) in case you are +using a sbt plugin like scalajs-bundler that alters the output directory. + +To reduce build times, you may want to keep `clean: false` for dev work and run +clean only for the production build. + +All options: +* verbose: Print messages during processing. +* clean: Clean prior to build. +* dirSegment: Directory segment inserted into the constructed path to find the .js file. +* removeSoruceMapUrl: Remove the source map URL. +* jsStage: "fastOptJS" or or "opt" diff --git a/index.js b/index.js index 81d29cb..73c44a5 100644 --- a/index.js +++ b/index.js @@ -1,27 +1,51 @@ const exec = require('child_process').exec; const path = require('path'); const readFileSync = require('fs').readFileSync; +const loaderUtils = require("loader-utils"); -module.exports = function(source) { - const callback = this.async(); - const cmd = 'sbt clean fastOptJS scalaVersion'; - - var self = this; - exec(cmd, { cwd: this.options.context }, function(error, stdout, _stderr) { - if (error) { return callback(error, null); } +const util = require("util"); - const scalaVersion = stdout.toString().trim().split('\n').pop().replace(/\u001b\[0m/g, '').replace(/^\[info\] (\d+\.\d+)(\.\d+)?/, '$1').trim(); - const outDir = path.join(self.options.context, 'target', `scala-${scalaVersion}`); - - const modName = JSON.parse(readFileSync(path.join(outDir, 'classes', 'JS_DEPENDENCIES')).toString()).origin.moduleName; - const outFile = path.join(outDir, `${modName}-fastopt.js`); +module.exports = function(source) { + const options = Object.assign({}, + {clean: true, dirSegment:"", jsStage: "fastOptJS", + removeSourceMapUrl: false, verbose: false}, + loaderUtils.getOptions(this)); + const verbose = options.verbose; + const dirSegment = options.dirSegment; + const clean = options.clean ? "clean": ""; + const jsStage = options.jsStage; + const stageFileSegment = (jsStage === 'fastOptJS')?'fastopt':'opt'; + const callback = this.async(); + const cmd = `sbt ${clean} ${jsStage} scalaVersion`; + const context = this.options.context; + var self = this; + if(verbose) { + console.log("\nscalajs-loader options: " + util.inspect(options)); + console.log("Running command: " + cmd); + } + exec(cmd, { cwd: context }, function(error, stdout, _stderr) { + if (error) { return callback(error, null); } + const scalaVersion = stdout.toString().trim().split('\n').pop().replace(/\u001b\[0m/g, '').replace(/^\[info\] (\d+\.\d+)(\.\d+)?/, '$1').trim(); + const outDir = path.join(context, 'target', `scala-${scalaVersion}`); - callback( - null, - readFileSync(outFile).toString().replace( - new RegExp(`\\n\/\/# sourceMappingURL=${modName}-fastopt\.js\.map`), - `\n//# sourceMappingURL=${outFile}.map` - ) - ); - }); + const modName = JSON.parse(readFileSync(path.join(outDir, 'classes', 'JS_DEPENDENCIES')).toString()).origin.moduleName; + const jsBasename = `${modName}-${stageFileSegment}.js`; + const outFile = path.join(outDir, dirSegment, jsBasename); + const sourceMapFile = path.join(outDir, dirSegment, `${modName}-${stageFileSegment}.js.map`); + if(verbose) { console.log("Reading source map file: " + sourceMapFile); } + const sourceMap = readFileSync(sourceMapFile).toString(); + const replacement = options.removeSourceMapUrl? '': `\n//# sourceMappingURL=${outFile}.map`; + if(verbose) { + console.log("Processing scala file: " + outFile); + if(options.removeSourceMapUrl) { console.log("Removing sourceMappingURL."); } + else { console.log("Replacing source map url with: " + replacement); } + } + const regex = new RegExp(`\\n\/\/# sourceMappingURL=${modName}-${stageFileSegment}\\.js\\.map`); + const passAlongContent = readFileSync(outFile).toString().replace(regex, replacement); + callback( + null, + passAlongContent, + sourceMap + ); + }); }; diff --git a/package.json b/package.json index 7516f57..c89bd02 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,15 @@ { - "name": "scalajs-loader", - "version": "0.0.1", - "author": "Matt Dziuban", + "name": "@aappddeevv/scalajs-loader", + "version": "0.0.2", + "author": "aappddeevv", "description": "Scala.js loader module for webpack", "dependencies": { + "loader-utils": "^1.1.0" }, "repository": { "type": "git", - "url": "git@github.com:mrdziuban/scalajs-loader" + "url": "git@github.com:aappddeevv/scalajs-loader" }, "license": "MIT" + ,"keywords": ["scalajs", "scala", "webpack"] }