Skip to content

Instantly share code, notes, and snippets.

@bradennapier
Created September 15, 2017 01:44
Show Gist options
  • Save bradennapier/ba223514f970640da527126453312a05 to your computer and use it in GitHub Desktop.
Save bradennapier/ba223514f970640da527126453312a05 to your computer and use it in GitHub Desktop.
Start of Webpack Plugin
// @flow
import ModuleFilenameHelpers from 'webpack/lib/ModuleFilenameHelpers';
import type {
FormatConfig,
PluginConfigurationType,
UserPluginConfigurationType,
} from './types';
import path from 'path';
import Doc from 'documentation';
import streamArray from 'stream-array';
import fs from 'fs';
import vfs from 'vinyl-fs';
import mkdir from 'mkdirp';
const defaultConfiguration: PluginConfigurationType = {
formats: [
{
format: 'html',
output: './documentation/html',
},
],
shallow: false,
external: [],
exclude: /node_modules/,
hljs: {
highlightAuto: false,
},
};
const nonEntryChunkPreamble =
'__assumeDataProperty(global, "webpackJsonp", __abstract("function"))';
const isEntryChunk = (chunk: Object) => {
return chunk.hasRuntime() && chunk.isInitial();
};
function handleOutput(
{ formatted, format, ast },
config: PluginConfigurationType,
) {
return new Promise((resolve, reject) => {
if (typeof format.handler === 'function') {
return resolve(
format.handler(
{
format,
formatted,
ast,
},
config,
),
);
} else {
switch (format.format) {
case 'html': {
return resolve(streamArray(formatted).pipe(vfs.dest(format.output)));
}
case 'markdown': {
return mkdir(format.output, err => {
if (err) {
throw err;
} else {
return resolve(fs.writeFileSync(format.output, formatted));
}
});
}
case 'json': {
return ast;
}
case 'ast': {
return ast;
}
default: {
throw new Error(
`[documentation-plugin]: Unable to handle format ${format.format}. Did you forget the 'handler' function when using a custom format?`,
);
}
}
}
});
}
function handleOutputs(outputs, config: PluginConfigurationType) {
return outputs.map(output => handleOutput(output, config));
}
export default class DocumentationPlugin {
config: PluginConfigurationType;
constructor(userConfiguration?: UserPluginConfigurationType) {
this.config = {
...defaultConfiguration,
...userConfiguration,
};
}
apply(compiler: Object) {
console.log('Documentation Plugin: Applying');
console.log(Object.keys(this));
const { config } = this;
let formats;
if (Array.isArray(config.formats)) {
formats = config.formats;
} else if (typeof config.format === 'object') {
formats = [config.format];
} else {
formats = [
{
format: 'html',
output: './documentation/html',
},
];
}
compiler.plugin('emit', (compilation, callback) => {
console.log(
'\n\u001B[33m%s\u001B[0m',
'[Documentation] Start generating\n',
);
// console.log(Object.keys(compilation));
const { fileDependencies } = compilation;
const matches = new Set(
fileDependencies.filter(d => {
if (this.config.include && this.config.include.test(d)) {
return true;
} else if (this.config.exclude && this.config.exclude.test(d)) {
return false;
}
return true;
}),
);
// console.log([...matches]);
Doc.build([...matches], {
external: config.external,
shallow: config.shallow,
order: config.order,
access: config.access,
hljs: config.hljs,
inferPrivate: config.inferPrivate,
extension: config.extension,
})
.then(ast => {
const promises = formats.map(format => {
if (format.format === 'ast') {
return Promise.resolve().then(() => {
return {
format,
ast,
formatted: ast,
};
});
}
return Doc.formats
[format.format](ast, format.config)
.then(formatted => {
return {
format,
ast,
formatted,
};
});
});
return Promise.all(promises);
})
.then(outputs => {
return handleOutputs(outputs, config);
})
.then(() => {
callback();
});
});
compiler.plugin('done', stats => {
console.log(
'\u001B[33m%s\u001B[0m',
'[Documentation] Finished generating',
);
console.log(
'\u001B[33m%s\u001B[0m',
'[Documentation] TOTAL TIME:',
stats.endTime - stats.startTime,
);
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment