UNPKG

3.88 kBJavaScriptView Raw
1const mdeps = require('module-deps-sortable');
2const path = require('path');
3const babelify = require('babelify');
4const concat = require('concat-stream');
5const moduleFilters = require('../module_filters');
6const { standardBabelParserPlugins } = require('../parsers/parse_to_ast');
7const smartGlob = require('../smart_glob.js');
8
9const STANDARD_BABEL_CONFIG = {
10 sourceMaps: false,
11 compact: false,
12 cwd: path.resolve(__dirname, '../../'),
13 presets: ['@babel/preset-react', '@babel/preset-env', '@babel/preset-flow'],
14 parserOpts: { plugins: standardBabelParserPlugins },
15 plugins: [
16 // Stage 0
17 '@babel/plugin-proposal-function-bind',
18 // Stage 1
19 '@babel/plugin-proposal-export-default-from',
20 '@babel/plugin-proposal-logical-assignment-operators',
21 '@babel/plugin-proposal-optional-chaining',
22 ['@babel/plugin-proposal-pipeline-operator', { proposal: 'minimal' }],
23 ['@babel/plugin-proposal-nullish-coalescing-operator', { loose: false }],
24 '@babel/plugin-proposal-do-expressions',
25 // Stage 2
26 ['@babel/plugin-proposal-decorators', { decoratorsBeforeExport: true }],
27 '@babel/plugin-proposal-function-sent',
28 '@babel/plugin-proposal-export-namespace-from',
29 '@babel/plugin-proposal-numeric-separator',
30 '@babel/plugin-proposal-throw-expressions',
31 // Stage 3
32 '@babel/plugin-syntax-dynamic-import',
33 '@babel/plugin-syntax-import-meta',
34 ['@babel/plugin-proposal-class-properties', { loose: false }],
35 '@babel/plugin-proposal-json-strings'
36 ]
37};
38
39/**
40 * Returns a readable stream of dependencies, given an array of entry
41 * points and an object of options to provide to module-deps.
42 *
43 * This stream requires filesystem access, and thus isn't suitable
44 * for a browser environment.
45 *
46 * @param indexes paths to entry files as strings
47 * @param config optional options passed
48 * @returns results
49 */
50function dependencyStream(indexes, config) {
51 const babelConfig = config.babel
52 ? { configFile: path.resolve(__dirname, '../../../../', config.babel) }
53 : STANDARD_BABEL_CONFIG;
54 const md = mdeps({
55 /**
56 * Determine whether a module should be included in documentation
57 * @param {string} id path to a module
58 * @returns {boolean} true if the module should be included.
59 */
60 filter: id => !!config.external || moduleFilters.internalOnly(id),
61 extensions: []
62 .concat(config.requireExtension || [])
63 .map(ext => '.' + ext.replace(/^\./, ''))
64 .concat(['.mjs', '.js', '.json', '.es6', '.jsx']),
65 transform: [babelify.configure(babelConfig)],
66 postFilter: moduleFilters.externals(indexes, config),
67 resolve:
68 config.resolve === 'node' &&
69 ((id, opts, cb) => {
70 const r = require('resolve');
71 opts.basedir = path.dirname(opts.filename);
72 r(id, opts, cb);
73 })
74 });
75 smartGlob(indexes, config.parseExtension).forEach(index => {
76 md.write(path.resolve(index));
77 });
78 md.end();
79
80 return new Promise((resolve, reject) => {
81 md.once('error', reject);
82 md.pipe(
83 concat(function(inputs) {
84 resolve(
85 inputs
86 .filter(
87 input =>
88 // At this point, we may have allowed a JSON file to be caught by
89 // module-deps, or anything else allowed by requireExtension.
90 // otherwise module-deps would complain about
91 // it not being found. But Babel can't parse JSON, so we filter non-JavaScript
92 // files away.
93 config.parseExtension.indexOf(
94 path.extname(input.file).replace(/^\./, '')
95 ) > -1
96 )
97 .map(input => {
98 // remove source file, since it's transformed anyway
99 delete input.source;
100 return input;
101 })
102 );
103 })
104 );
105 });
106}
107
108module.exports = dependencyStream;