UNPKG

3.26 kBJavaScriptView Raw
1"use strict";
2
3const Plugin = require('broccoli-plugin');
4const fs = require('fs');
5const path = require('path');
6const walkSync = require('walk-sync');
7const getModuleConfig = require('./lib/get-module-config');
8const getModuleSpecifier = require('./lib/get-module-specifier');
9
10function ResolutionMapBuilder(src, config, options) {
11 options = options || {};
12 Plugin.call(this, [src, config], {
13 annotation: options.annotation
14 });
15 this.options = options;
16}
17
18ResolutionMapBuilder.prototype = Object.create(Plugin.prototype);
19
20ResolutionMapBuilder.prototype.constructor = ResolutionMapBuilder;
21
22ResolutionMapBuilder.prototype.build = function() {
23 // Attempt to read config file
24 let configPath = path.join(this.inputPaths[1], this.options.configPath);
25 let config;
26 if (fs.existsSync(configPath)) {
27 let configContents = fs.readFileSync(configPath, { encoding: 'utf8' });
28 config = JSON.parse(configContents);
29 } else {
30 config = {};
31 }
32
33 let moduleConfig = getModuleConfig(config.moduleConfiguration || this.options.defaultModuleConfiguration);
34 if (!moduleConfig) {
35 throw new Error(`The module configuration could not be found. Please add a config file to '${configPath}' and export an object with a 'moduleConfiguration' member.`);
36 }
37
38 let modulePrefix = config.modulePrefix || this.options.modulePrefix;
39 if (!modulePrefix) {
40 throw new Error(`The module prefix could not be found. Add a config file to '${configPath}' and export an object with a 'modulePrefix' member.`);
41 }
42
43 let modulePaths = walkSync(this.inputPaths[0]);
44 let mappedPaths = [];
45 let moduleImports = [];
46 let mapContents = [];
47
48 modulePaths.forEach(function(modulePath) {
49 if (modulePath.indexOf('.') > -1) {
50 let name = modulePath.substring(0, modulePath.lastIndexOf('.'));
51
52 // filter out index module
53 if (name !== 'index' && name !== 'main') {
54 mappedPaths.push(modulePath);
55 }
56 }
57 });
58
59 if (this.options.logSpecifiers) {
60 this.specifiers = [];
61 }
62
63 mappedPaths.forEach(modulePath => {
64 let module = modulePath.substring(0, modulePath.lastIndexOf('.'));
65 let extension = modulePath.substring(modulePath.lastIndexOf('.') + 1);
66 let specifier = getModuleSpecifier(modulePrefix, moduleConfig, module, extension);
67
68 // Only process non-null specifiers returned.
69 // Specifiers may be null in the case of an unresolvable collection (e.g. utils)
70 if (specifier) {
71 let moduleImportPath = '../' + module;
72 let moduleVar = '__' + module.replace(/\//g, '__').replace(/-/g, '_') + '__';
73 let moduleImport = "import { default as " + moduleVar + " } from '" + moduleImportPath + "';";
74 moduleImports.push(moduleImport);
75 mapContents.push("'" + specifier + "': " + moduleVar);
76
77 if (this.options.logSpecifiers) {
78 this.specifiers.push(specifier);
79 }
80 }
81 });
82
83 let destPath = path.join(this.outputPath, 'config');
84 if (!fs.existsSync(destPath)) {
85 fs.mkdirSync(destPath);
86 }
87
88 let contents = moduleImports.join('\n') + '\n' +
89 "export default {" + mapContents.join(',') + "};" + '\n';
90
91 fs.writeFileSync(path.join(this.outputPath, 'config', 'module-map.js'), contents, { encoding: 'utf8' });
92};
93
94module.exports = ResolutionMapBuilder;