-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathindex.js
94 lines (80 loc) · 3.56 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
var loaderUtils = require('loader-utils');
var closureTemplates = require('closure-templates');
var Promise = require('bluebird');
var soynode = Promise.promisifyAll(require('soynode'));
var fs = Promise.promisifyAll(require('fs'));
var rimrafAsync = Promise.promisify(require('rimraf'));
var path = require('path');
// Automatic cleanup of temporary files.
// Run the loader.
module.exports = function(source) {
if (this.cacheable) this.cacheable();
var loaderCallback = this.async();
var query = this.query instanceof Object ? this.query : loaderUtils.parseQuery(this.query);
var inputDir = query.inputDir ? (query.inputDir instanceof String ? query.inputDir : ""+query.inputDir) : process.cwd();
var classpath = query.classpath ? (query.classpath instanceof Array ? query.classpath : [query.classpath]) : [];
var pluginModules = query.pluginModules ? (query.pluginModules instanceof Array ? query.pluginModules : [query.pluginModules]) : [];
// Get the configurable source of the soy runtime utilities, or use default.
var runtimeUtils = require.resolve(query.utils || closureTemplates['soyutils.js']);
// Create a require statement to be injected into the templates for shimming.
runtimeUtils = 'require(\'exports-loader?goog,soy,soydata,soyshim!' + runtimeUtils + '\')';
runtimeUtils = runtimeUtils.replace(/\\/g, '\\\\');
this.addDependency(require.resolve(closureTemplates['soyutils.js']));
soynode.setOptions({
inputDir: inputDir,
outputDir: '/',
uniqueDir: false,
eraseTemporaryFiles: false,
classpath: classpath,
pluginModules: pluginModules
});
// Grab namespace for shimming encapsulated module return value.
var extracted = /\{namespace\s+((\w+)[^\s]*).*\}/.exec(source);
var namespace = extracted[1];
var baseVar = extracted[2]
var tempDir = path.resolve(__dirname, [
'soytemp', // directory prefix
Date.now(), // datestamp
(Math.random() * 0x100000000 + 1).toString(36) // randomized suffix
].join('-'));
// Compile the templates to a temporary directory for reading.
var compileContent = fs.mkdirAsync(tempDir)
// Get the temp directory path
.then(function() {
dirPath = tempDir;
// Handle drive letters in windows environments (C:\)
if (dirPath.indexOf(':') !== -1) {
dirPath = dirPath.split(':')[1];
}
return path.join(dirPath, 'source.soy');
// Write the raw source template into the temp directory
}).then(function(soyPath) {
return fs.writeFileAsync(path.resolve(soyPath), source).return(soyPath);
// Run the compiler on the raw template
}).then(function(soyPath) {
return soynode.compileTemplateFilesAsync([soyPath]).return(soyPath);
// Read the newly compiled source
}).then(function(soyPath) {
return fs.readFileAsync(path.resolve(soyPath) + '.js');
// Return utils and module return value, shimmed for module encapsulation.
}).then(function(template) {
return loaderCallback(null, [
// Shims for encapsulating the soy runtime library. Normally these are exposed globally by
// including soyutils.js. Here we encapsulate them and require them in the template.
'var goog = ' + runtimeUtils + '.goog;',
'var soy = ' + runtimeUtils + '.soy;',
'var soydata = ' + runtimeUtils + '.soydata;',
'var soyshim = ' + runtimeUtils + '.soyshim;',
// Shims for encapsulating the compiled template.
'var ' + baseVar + ';',
template,
'module.exports = ' + namespace + ';'
].join('\n'));
// Handle any errors
}).catch(function(e) {
return loaderCallback(e);
// Cleanup temp directory
}).finally(function(template) {
return rimrafAsync(tempDir).return(template);
});
};