-
Notifications
You must be signed in to change notification settings - Fork 146
/
Copy pathindex.js
executable file
·139 lines (113 loc) · 5.39 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#!/usr/bin/env node
const acorn = require('acorn');
const fs = require('fs');
const path = require('path');
const inquirer = require('inquirer');
const args = require('minimist')(process.argv.slice(2));
const convertToIntegerKey = require('./utils/convertToIntegerKey');
// ----------------------------------------------------------------------------
// Set up configuration
// ----------------------------------------------------------------------------
const bundleLocation = args._[0] || args.input || args.i;
const outputLocation = args.output || args.o;
const configPath = args.config || args.c;
if (!(bundleLocation && outputLocation && configPath)) {
console.log(`This is a debundler - it takes a bundle and expands it into the source that was used to compile it.`);
console.log();
console.log(`Usage: ${process.argv[1]} [input file] {OPTIONS}`);
console.log();
console.log(`Options:`);
console.log(` --input, -i Bundle to debundle`);
console.log(` --output, -o Directory to debundle code into.`);
console.log(` --config, -c Configuration directory`);
console.log();
process.exit(1);
}
const config = JSON.parse(fs.readFileSync(args.config || args.c));
if (config.knownPaths) {
config.knownPaths = convertToIntegerKey(config.knownPaths);
} else {
throw new Error('config.knownPaths is a required parameter that indicated known paths to a module given its id.');
}
if (!config.moduleAst) {
if (config.type === 'browserify') {
// Where browserify defaultly stores all it's embedded modules as an object
config.moduleAst = ["body", 0, "expression", "arguments", 0];
} else if (config.type === 'webpack') {
// Where webpack defaultly stores all it's embedded modules as an array
config.moduleAst = ["body", 0, "expression", "arguments", 0];
}
console.log(`* Using default AST location for ${config.type}...`);
}
config.replaceRequires = typeof config.replaceRequires === 'undefined' ? "inline" : config.replaceRequires;
// ----------------------------------------------------------------------------
// Read in bundle
// ----------------------------------------------------------------------------
console.log('* Reading bundle...');
const bundleContents = fs.readFileSync(bundleLocation);
let ast = acorn.parse(bundleContents, {});
// Get the entry point in the bundle.
if (config.type === 'browserify' && !config.entryPoint) {
console.log('* Using auto-discovered browserify entry point...');
config.entryPoint = ast.body[0].expression.arguments[2].elements[0].value;
}
if (config.entryPoint === undefined) {
throw new Error('config.entryPoint is a required parameter that indicated the entry point in the bundle.');
}
// ----------------------------------------------------------------------------
// Find all the modules in the bundle via `moduleAst`
// ----------------------------------------------------------------------------
let iifeModules = ast;
let moduleAstPathTriedSoFar = [];
while (true) {
let operation = config.moduleAst.shift();
if (!iifeModules) {
throw new Error(`Locating the module AST failed. Please specifify a valid manual ast path in your config file with the key \`moduleAst\`. We got as far as ${moduleAstPathTriedSoFar.join('.')} before an error occured.`);
} else if (operation === undefined) {
break;
} else {
iifeModules = iifeModules[operation];
moduleAstPathTriedSoFar.push(operation);
}
}
// ------------------------------------------------------------------------------
// Given the path to the modules in the AST and the AST, pull out the modules and normalize
// them to a predefined format.
// ------------------------------------------------------------------------------
console.log('* Decoding modules...');
let modules;
if (config.type === 'browserify') {
// Normalize all require function calls to all contain the module id.
// var a = require('a') => var a = require(1)
const browserifyDecoder = require('./decoders/browserify');
modules = browserifyDecoder(iifeModules);
} else {
const webpackDecoder = require('./decoders/webpack');
modules = webpackDecoder(iifeModules, config.knownPaths);
}
// ------------------------------------------------------------------------------
// Transform the module id in each require call into a relative path to the module.
// var a = require(1) => var a = require('./path/to/a')
// ------------------------------------------------------------------------------
console.log('* Reassembling requires...');
const transformRequires = require('./transformRequires');
modules = transformRequires(modules, config.knownPaths, config.entryPoint, config.type, config.replaceRequires);
// ------------------------------------------------------------------------------
// Take the array of modules and figure out where to put each module on disk.
// module 1 => ./dist/path/to/a.js
// ------------------------------------------------------------------------------
console.log('* Resolving files...');
const lookupTableResolver = require('./lookupTable');
const files = lookupTableResolver(
modules,
config.knownPaths,
config.entryPoint,
config.type,
outputLocation
);
// ------------------------------------------------------------------------------
// Finally, write the bundle to disk in the specified output location.
// ------------------------------------------------------------------------------
console.log('* Writing to disk...');
const writeToDisk = require('./writeToDisk');
writeToDisk(files);