UNPKG

2.87 kBJavaScriptView Raw
1var through = require('through');
2var estraverse = require('estraverse');
3var esprima = require('esprima');
4var path = require('path');
5var minimatch = require('minimatch');
6var typeName = require('type-name');
7
8function debug() {
9 if (process.env.DEBUG) { console.log.apply(console, arguments); }
10}
11
12function isDynamicModule(moduleName, options) {
13 if (options.targetModules) {
14 if (moduleName[0] === ".") {
15 moduleName = path.resolve(path.dirname(options.file), moduleName);
16 moduleName = "./" + path.relative(options.baseDir, moduleName);
17 }
18 var patterns = options.targetModules;
19 patterns = typeName(patterns) === 'Array' ? patterns : [ patterns ];
20 for (var i=0, len=patterns.length; i<len; i++) {
21 var pattern = patterns[i];
22 debug("**** pattern : ", pattern, " => module : ", moduleName, "*****");
23 if (/[\*\?\!\{\}]/.test(pattern) ? minimatch(moduleName, pattern) : moduleName === pattern) {
24 debug(" <<< matched >>> ");
25 return true;
26 }
27 }
28 } else {
29 return true;
30 }
31}
32
33function fixModulePath(moduleName, options) {
34 if (moduleName[0] === ".") {
35 moduleName = path.resolve(path.dirname(options.file), moduleName);
36 moduleName = "./" + path.relative(options.baseDir, moduleName);
37 }
38 return moduleName;
39}
40
41function swapRequire(code, newRequireName, options) {
42 var chunks = [], start = 0;
43 var ast = esprima.parse(code, { range: true });
44 estraverse.traverse(ast, {
45 enter: function(node, parent, parent2) {
46 if (parent && parent.type === 'CallExpression' &&
47 node.type === 'Identifier' && node.name === 'require' &&
48 parent.arguments.length === 1 && parent.arguments[0].type === 'Literal') {
49 var moduleName = parent.arguments[0].value;
50 if (isDynamicModule(moduleName, options)) {
51 console.log(moduleName, ' is dynamic');
52 chunks.push(code.substring(start, parent.range[0]));
53 chunks.push(newRequireName + "('" + fixModulePath(moduleName, options) + "')");
54 start = parent.range[1];
55 } else {
56 console.log(moduleName, ' is not dynamic');
57 }
58 }
59 }
60 });
61 chunks.push(code.substring(start));
62 return chunks.join('');
63}
64
65function swap(file, options) {
66 if (/\.json$/.test(file)) {
67 return through();
68 }
69 var swappingTo = options.fn || 'dynRequire';
70 var chunks = [];
71 var stream = through(write, end);
72 function write(chunk, enc) {
73 chunks.push(chunk.toString(enc));
74 }
75 function end() {
76 var code = chunks.join('');
77 try {
78 code = swapRequire(code, swappingTo, {
79 baseDir: options.baseDir || process.cwd(),
80 targetModules: options.module || options.modules,
81 file: file
82 });
83 } catch(e) {
84 stream.emit('error', e);
85 }
86 stream.queue(code);
87 stream.queue(null);
88 }
89 return stream;
90}
91
92module.exports = swap;