Created
November 28, 2017 14:10
-
-
Save ccapndave/4f49fb821d23b2b7f35a2fdfb185ddd0 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//import { File, WorkFlowContext, Plugin } from "fuse-box"; | |
import { File, WorkFlowContext, Plugin } from "../../fuse-box/.dev"; | |
import { ChildProcess } from "child_process"; | |
import { resolve } from "path"; | |
import { readFile } from "fs"; | |
import { tmpName } from "tmp"; | |
import * as spawn from "cross-spawn"; | |
import { findAllDependencies } from "find-elm-dependencies" | |
const tmp = () => | |
new Promise((resolve, reject) => | |
tmpName((err, path) => (err ? reject(err) : resolve(path))) | |
); | |
export interface ElmPluginOptions { | |
warn?: boolean; | |
debug?: boolean; | |
} | |
export class ElmPluginClass implements Plugin { | |
// Match Elm files | |
public test: RegExp = /\.elm$/; | |
public context: WorkFlowContext; | |
public options: ElmPluginOptions; | |
constructor(options: ElmPluginOptions = {}) { | |
this.options = { ...options }; | |
} | |
public init(context: WorkFlowContext): void { | |
this.context = context; | |
context.allowExtension(".elm"); | |
} | |
public getElmMakePath(): string { | |
try { | |
return resolve("node_modules/.bin/elm-make"); | |
} catch (_) {} | |
return "elm-make"; | |
} | |
public async transform(file: File): Promise<any> { | |
if (this.context.useCache) { | |
if (file.loadFromCache()) { | |
return; | |
} | |
} | |
file.loadContents(); | |
// Get the path to elm-make | |
const elmMakePath: string = this.getElmMakePath(); | |
// Create temporary JS file | |
const tmpFilename: string = `${await tmp()}.js`; | |
return new Promise((resolve, reject) => { | |
// Construct the arguments for elm-make | |
const args = [ | |
"--yes", | |
"--output", | |
tmpFilename, | |
this.options.warn ? "--warn" : null, | |
this.options.debug ? "--debug" : null, | |
file.absPath | |
].filter(x => x !== null); | |
const proc: ChildProcess = spawn(elmMakePath, args, { stdio: "inherit" }); | |
proc.on("error", (err: NodeJS.ErrnoException) => { | |
if (err.code === "ENOENT") { | |
reject( | |
`Could not find Elm compiler @ "${elmMakePath}" | |
\nHave you installed elm yet? If not, please install "elm" via npm` | |
); | |
} else if (err.code === "EACCES") { | |
reject( | |
`Elm compiler @ "${elmMakePath}" did not have permission to run | |
\nYou may need give it executable permissions` | |
); | |
} else { | |
reject( | |
`Error attempting to run Elm compiler @ "${elmMakePath}" \n ${err}` | |
); | |
} | |
}); | |
proc.on("close", (code: Number) => { | |
if (code === 0) { | |
readFile(tmpFilename, (err: NodeJS.ErrnoException, data: Buffer) => { | |
if (err) { | |
reject(err); | |
} else { | |
file.contents = data.toString(); | |
findAllDependencies(file.absPath) | |
.then((paths: string[]) => { | |
file.analysis.dependencies = paths; | |
if (this.context.useCache) { | |
//this.context.emitJavascriptHotReload(file); | |
this.context.cache.writeStaticCache(file, file.sourceMap); | |
} | |
resolve(file); | |
}) | |
.catch((err: string) => { | |
reject(err); | |
}); | |
} | |
}); | |
} else { | |
reject("Failed to compile Elm."); | |
} | |
}); | |
}); | |
} | |
} | |
export const ElmPlugin = (options?: ElmPluginOptions) => | |
new ElmPluginClass(options); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment