UNPKG

3.4 kBJavaScriptView Raw
1var glslifyBundle = require('glslify-bundle')
2var staticModule = require('static-module')
3var glslifyDeps = require('glslify-deps')
4var glslResolve = require('glsl-resolve')
5var through = require('through2')
6var nodeResolve = require('resolve')
7var extend = require('xtend')
8var path = require('path')
9var fs = require('fs')
10
11module.exports = transform
12module.exports.bundle = bundle
13
14function transform(jsFilename, browserifyOpts) {
15 if (path.extname(jsFilename) === '.json') return through()
16
17 // static-module is responsible for replacing any
18 // calls to glslify in your JavaScript with a string
19 // of our choosing – in this case, our bundled glslify
20 // shader source.
21 var sm = staticModule({
22 glslify: streamBundle
23 }, {
24 vars: {
25 __dirname: path.dirname(jsFilename),
26 __filename: jsFilename,
27 require: {
28 resolve: nodeResolve
29 }
30 }
31 })
32
33 return sm
34
35 function streamBundle(filename, opts) {
36 var stream = through()
37
38 opts = extend({
39 basedir: path.dirname(jsFilename)
40 }, browserifyOpts || {}, opts || {})
41
42 var depper = bundle(filename, opts, function(err, source) {
43 if (err) return sm.emit('error', err)
44
45 stream.push(JSON.stringify(source))
46 stream.push(null)
47 })
48
49 //notify watchify that we have a new dependency
50 depper.on('file', function(file) {
51 sm.emit('file', file)
52 })
53
54 return stream
55 }
56}
57
58function bundle(filename, opts, done) {
59 opts = opts || {}
60
61 var defaultBase = opts.inline
62 ? process.cwd()
63 : path.dirname(filename)
64
65 var base = path.resolve(opts.basedir || defaultBase)
66 var posts = []
67 var files = []
68 var depper = glslifyDeps({
69 cwd: base
70 })
71
72 // Extract and add our local transforms.
73 var transforms = opts.transform || []
74
75 depper.on('file', function(file) {
76 files.push(file)
77 })
78
79 transforms = Array.isArray(transforms) ? transforms : [transforms]
80 transforms.forEach(function(transform) {
81 transform = Array.isArray(transform) ? transform : [transform]
82
83 var name = transform[0]
84 var opts = transform[1] || {}
85
86 if (opts.post) {
87 posts.push({ name: name, opts: opts })
88 } else {
89 depper.transform(name, opts)
90 }
91 })
92
93 if (opts.inline) {
94 depper.inline(filename
95 , base
96 , addedDep)
97 } else {
98 filename = glslResolve.sync(filename, {
99 basedir: base
100 })
101
102 depper.add(filename, addedDep)
103 }
104
105 return depper
106
107 // Builds a dependency tree starting from the
108 // given `filename` using glslify-deps.
109 function addedDep(err, tree) {
110 if (err) return done(err)
111
112 try {
113 // Turn that dependency tree into a GLSL string,
114 // stringified for use in our JavaScript.
115 var source = glslifyBundle(tree)
116 } catch(e) {
117 return done(e)
118 }
119
120 // Finally, this applies our --post transforms
121 next()
122 function next() {
123 var tr = posts.shift()
124 if (!tr) return postDone()
125
126 var target = nodeResolve.sync(tr.name, {
127 basedir: path.dirname(filename)
128 })
129
130 var transform = require(target)
131
132 transform(null, source, {
133 post: true
134 }, function(err, data) {
135 if (err) throw err
136 if (data) source = data
137 next()
138 })
139 }
140
141 function postDone() {
142 done(null, source, opts.inline
143 ? files.slice(1)
144 : files
145 )
146 }
147 }
148}