const webpack = require('webpack'); const MemoryFS = require('memory-fs'); const clone = require('lodash.clonedeep'); const path = require('path'); const getCompiler = ({ filename, mfs, config }) => { const compiler = webpack(config); compiler.outputFileSystem = mfs; compiler.inputFileSystem.stat = function(path, callback) { this._statStorage.provide(path, (path, callback) => { if (path === filename) { return mfs.stat(path, callback); } this._stat(path, callback); }, callback); }; compiler.inputFileSystem.readFile = function(path, callback) { this._readFileStorage.provide(path, (path, callback) => { if (path === filename) { return mfs.readFile(path, callback); } this._readFile(path, callback); }, callback); }; return compiler; }; module.exports = ({ source, entrypoint, config }, fn) => { const name = path.basename(entrypoint); const _filename = path.resolve(config.context, entrypoint); const _dirname = path.dirname(_filename); const mfs = new MemoryFS(); mfs.mkdirpSync('/static'); mfs.mkdirpSync(_dirname); mfs.writeFileSync(_filename, source); const compiler = getCompiler({ filename: _filename, mfs, config: Object.assign(clone(config), { target: 'node', output: { path: '/static', filename: name }, entry: [ `./${path.relative(config.context, _filename)}` ] }) }); compiler.run((err, stats) => { if (err) { return fn(err, {}); } const errors = stats.toJson().errors; if (errors && errors.length) { errors.map(err => console.log(err)); return fn(errors, {}); } mfs.readFile(`/static/${name}`, (err, res) => { if (err) { return fn(err); } // TODO read extract css defs let style = mfs.readdirSync('/static/css').filter((file) => { return /\.css$/.test(file); }).map((file) => { try { return mfs.readFileSync(`/static/css/${file}`, 'utf-8'); } catch (err) { return ''; } }).concat('\n'); fn(err, { body: (res && res.toString) ? res.toString() : res, style }); }); }); };