167 lines
3.8 KiB
JavaScript
167 lines
3.8 KiB
JavaScript
var glslifyBundle = require('glslify-bundle')
|
||
var staticModule = require('static-module')
|
||
var glslifyDeps = require('glslify-deps')
|
||
var glslResolve = require('glsl-resolve')
|
||
var through = require('through2')
|
||
var nodeResolve = require('resolve')
|
||
var extend = require('xtend')
|
||
var path = require('path')
|
||
var fs = require('fs')
|
||
|
||
module.exports = transform
|
||
module.exports.bundle = bundle
|
||
|
||
function transform(jsFilename, browserifyOpts) {
|
||
if (path.extname(jsFilename) === '.json') return through()
|
||
|
||
var streamHasErrored = false
|
||
|
||
// static-module is responsible for replacing any
|
||
// calls to glslify in your JavaScript with a string
|
||
// of our choosing – in this case, our bundled glslify
|
||
// shader source.
|
||
var sm = staticModule({
|
||
glslify: streamBundle
|
||
}, {
|
||
vars: {
|
||
__dirname: path.dirname(jsFilename),
|
||
__filename: jsFilename,
|
||
require: {
|
||
resolve: nodeResolve
|
||
}
|
||
},
|
||
varModules: { path: path }
|
||
})
|
||
|
||
return sm
|
||
|
||
function streamBundle(filename, opts) {
|
||
var stream = through()
|
||
|
||
if (typeof filename === 'object') {
|
||
if (streamHasErrored) return
|
||
|
||
streamHasErrored = true
|
||
setTimeout(function () {
|
||
return sm.emit('error', new Error(
|
||
'You supplied an object as glslify\'s first argument. As of ' +
|
||
'glslify@2.0.0, glslify expects a filename or shader: ' +
|
||
'see https://github.com/stackgl/glslify#migrating-from-glslify1-to-glslify2 for more information'
|
||
))
|
||
})
|
||
|
||
return
|
||
}
|
||
|
||
opts = extend({
|
||
basedir: path.dirname(jsFilename)
|
||
}, browserifyOpts || {}, opts || {})
|
||
|
||
var depper = bundle(filename, opts, function(err, source) {
|
||
if (err) return sm.emit('error', err)
|
||
|
||
stream.push(JSON.stringify(source))
|
||
stream.push(null)
|
||
})
|
||
|
||
//notify watchify that we have a new dependency
|
||
depper.on('file', function(file) {
|
||
sm.emit('file', file)
|
||
})
|
||
|
||
return stream
|
||
}
|
||
}
|
||
|
||
function bundle(filename, opts, done) {
|
||
opts = opts || {}
|
||
|
||
var defaultBase = opts.inline
|
||
? process.cwd()
|
||
: path.dirname(filename)
|
||
|
||
var base = path.resolve(opts.basedir || defaultBase)
|
||
var posts = []
|
||
var files = []
|
||
var depper = glslifyDeps({
|
||
cwd: base
|
||
})
|
||
|
||
// Extract and add our local transforms.
|
||
var transforms = opts.transform || []
|
||
|
||
depper.on('file', function(file) {
|
||
files.push(file)
|
||
})
|
||
|
||
transforms = Array.isArray(transforms) ? transforms : [transforms]
|
||
transforms.forEach(function(transform) {
|
||
transform = Array.isArray(transform) ? transform : [transform]
|
||
|
||
var name = transform[0]
|
||
var opts = transform[1] || {}
|
||
|
||
if (opts.post) {
|
||
posts.push({ name: name, opts: opts })
|
||
} else {
|
||
depper.transform(name, opts)
|
||
}
|
||
})
|
||
|
||
if (opts.inline) {
|
||
depper.inline(filename
|
||
, base
|
||
, addedDep)
|
||
} else {
|
||
filename = glslResolve.sync(filename, {
|
||
basedir: base
|
||
})
|
||
|
||
depper.add(filename, addedDep)
|
||
}
|
||
|
||
return depper
|
||
|
||
// Builds a dependency tree starting from the
|
||
// given `filename` using glslify-deps.
|
||
function addedDep(err, tree) {
|
||
if (err) return done(err)
|
||
|
||
try {
|
||
// Turn that dependency tree into a GLSL string,
|
||
// stringified for use in our JavaScript.
|
||
var source = glslifyBundle(tree)
|
||
} catch(e) {
|
||
return done(e)
|
||
}
|
||
|
||
// Finally, this applies our --post transforms
|
||
next()
|
||
function next() {
|
||
var tr = posts.shift()
|
||
if (!tr) return postDone()
|
||
|
||
var target = nodeResolve.sync(tr.name, {
|
||
basedir: path.dirname(filename)
|
||
})
|
||
|
||
var transform = require(target)
|
||
|
||
transform(null, source, {
|
||
post: true
|
||
}, function(err, data) {
|
||
if (err) throw err
|
||
if (data) source = data
|
||
next()
|
||
})
|
||
}
|
||
|
||
function postDone() {
|
||
done(null, source, opts.inline
|
||
? files.slice(1)
|
||
: files
|
||
)
|
||
}
|
||
}
|
||
}
|