Last active
July 1, 2022 00:54
-
-
Save impaler/2fa322625bfd366fd4c1698170a4f855 to your computer and use it in GitHub Desktop.
Compile webpack with typescript in memory
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
// based on code from https://stackoverflow.com/questions/38779924/compiling-webpack-in-memory-but-resolving-to-node-modules-on-disk | |
import * as webpack from 'webpack' | |
import * as MemoryFileSystem from 'memory-fs' | |
import * as path from 'path' | |
import * as fs from 'fs' | |
import * as promisify from 'util.promisify' | |
const memFs = new MemoryFileSystem() | |
const statOrig = memFs.stat.bind(memFs) | |
const readFileOrig = memFs.readFile.bind(memFs) | |
memFs.stat = function (_path, cb) { | |
statOrig(_path, function (err, result) { | |
if (err) { | |
return fs.stat(_path, cb) | |
} else { | |
return cb(err, result) | |
} | |
}) | |
} | |
memFs.readFile = function (path, cb) { | |
readFileOrig(path, function (err, result) { | |
if (err) { | |
return fs.readFile(path, cb) | |
} else { | |
return cb(err, result) | |
} | |
}) | |
} | |
export default async function compile (code) { | |
// Setup webpack | |
// create a directory structure in MemoryFS that matches | |
// the real filesystem | |
const rootDir = __dirname | |
//write code snippet to memoryfs | |
const outputName = `file.js` | |
const entryName = `file.ts` | |
const entry = path.join(rootDir, entryName) | |
const rootExists = memFs.existsSync(rootDir) | |
if (!rootExists) { | |
memFs.mkdirpSync(rootDir) | |
} | |
memFs.writeFileSync(entry, code) | |
//point webpack to memoryfs for the entry file | |
const compiler = webpack({ | |
entry: entry, | |
output: { | |
filename: outputName, | |
}, | |
module: { | |
loaders: [ | |
{ | |
test: /\.tsx?$/, | |
loaders: [ | |
'ts-loader?' + JSON.stringify({ | |
transpileOnly: true, | |
configFileName: 'tsconfig.json', | |
}), | |
], | |
}, | |
{ | |
test: /\.json$/, loader: 'json', | |
}, | |
], | |
}, | |
}) as any | |
compiler.run = promisify(compiler.run) | |
// direct webpack to use memoryfs for file input | |
compiler.inputFileSystem = memFs | |
compiler.resolvers.normal.fileSystem = memFs | |
//direct webpack to output to memoryfs rather than to disk | |
compiler.outputFileSystem = memFs | |
const stats = await compiler.run() | |
// remove entry from memory. we're done with it | |
memFs.unlinkSync(entry) | |
const errors = stats.compilation.errors | |
if (errors && errors.length > 0) { | |
// if there are errors, throw the first one | |
throw errors[0] | |
} | |
// retrieve the output of the compilation | |
const res = stats.compilation.assets[outputName].source() | |
return res | |
} |
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 * as compile from 'compile' | |
// Usage example | |
const code = 'import * as R from "ramda"' | |
const bundle = compile(code) | |
.then((result) => { | |
console.log(result) | |
}) | |
.catch(error => { | |
console.error(error) | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment