From 01e7c448f5f3a4ccdb832448ab549fdc2acebc92 Mon Sep 17 00:00:00 2001 From: Vladyslav Batyrenko Date: Thu, 22 Mar 2018 07:59:20 +0200 Subject: [PATCH] Add GLSL assets support (#831) --- package.json | 2 + src/Parser.js | 4 + src/Resolver.js | 5 +- src/assets/GLSLAsset.js | 62 +++++++++ test/glsl.js | 32 +++++ test/integration/glsl/compiled.glsl | 11 ++ test/integration/glsl/index.js | 9 ++ test/integration/glsl/lib.glsl | 4 + test/integration/glsl/local.frag | 9 ++ test/integration/glsl/local.glsl | 9 ++ test/integration/glsl/local.vert | 9 ++ yarn.lock | 193 ++++++++++++++++++++++++++-- 12 files changed, 335 insertions(+), 14 deletions(-) create mode 100644 src/assets/GLSLAsset.js create mode 100644 test/glsl.js create mode 100644 test/integration/glsl/compiled.glsl create mode 100644 test/integration/glsl/index.js create mode 100644 test/integration/glsl/lib.glsl create mode 100644 test/integration/glsl/local.frag create mode 100644 test/integration/glsl/local.glsl create mode 100644 test/integration/glsl/local.vert diff --git a/package.json b/package.json index 6c96f7c7c5c..edb54da86da 100644 --- a/package.json +++ b/package.json @@ -71,6 +71,8 @@ "coffeescript": "^2.0.3", "cross-env": "^5.1.1", "eslint": "^4.13.0", + "glslify-bundle": "^5.0.0", + "glslify-deps": "^1.3.0", "graphql": "^0.11.7", "graphql-tag": "^2.6.0", "husky": "^0.14.3", diff --git a/src/Parser.js b/src/Parser.js index 2002a879108..759e0e55c7c 100644 --- a/src/Parser.js +++ b/src/Parser.js @@ -38,6 +38,10 @@ class Parser { this.registerExtension('webmanifest', './assets/WebManifestAsset'); + this.registerExtension('glsl', './assets/GLSLAsset'); + this.registerExtension('vert', './assets/GLSLAsset'); + this.registerExtension('frag', './assets/GLSLAsset'); + let extensions = options.extensions || {}; for (let ext in extensions) { this.registerExtension(ext, extensions[ext]); diff --git a/src/Resolver.js b/src/Resolver.js index 1da3574567f..64a33ff1512 100644 --- a/src/Resolver.js +++ b/src/Resolver.js @@ -41,7 +41,10 @@ class Resolver { } // Get file extensions to search - let extensions = Object.keys(this.options.extensions); + let extensions = Array.isArray(this.options.extensions) + ? this.options.extensions.slice() + : Object.keys(this.options.extensions); + if (parent) { // parent's extension given high priority const parentExt = path.extname(parent); diff --git a/src/assets/GLSLAsset.js b/src/assets/GLSLAsset.js new file mode 100644 index 00000000000..6b88f8cde92 --- /dev/null +++ b/src/assets/GLSLAsset.js @@ -0,0 +1,62 @@ +const Asset = require('../Asset'); +const localRequire = require('../utils/localRequire'); +const path = require('path'); +const promisify = require('../utils/promisify'); +const Resolver = require('../Resolver'); + +class GLSLAsset extends Asset { + constructor(name, pkg, options) { + super(name, pkg, options); + this.type = 'js'; + } + + async parse() { + const glslifyDeps = await localRequire('glslify-deps', this.name); + + // Use the Parcel resolver rather than the default glslify one. + // This adds support for parcel features like alises, and tilde paths. + const resolver = new Resolver({ + extensions: ['.glsl', '.vert', '.frag'], + rootDir: this.options.rootDir + }); + + // Parse and collect dependencies with glslify-deps + let cwd = path.dirname(this.name); + let depper = glslifyDeps({ + cwd, + resolve: async (target, opts, next) => { + try { + let res = await resolver.resolve( + target, + path.join(opts.basedir, 'index') + ); + next(null, res.path); + } catch (err) { + next(err); + } + } + }); + + return await promisify(depper.inline.bind(depper))(this.contents, cwd); + } + + collectDependencies() { + for (let dep of this.ast) { + if (!dep.entry) { + this.addDependency(dep.file, {includedInParent: true}); + } + } + } + + async generate() { + // Generate the bundled glsl file + const glslifyBundle = await localRequire('glslify-bundle', this.name); + let glsl = glslifyBundle(this.ast); + + return { + js: `module.exports=${JSON.stringify(glsl)};` + }; + } +} + +module.exports = GLSLAsset; diff --git a/test/glsl.js b/test/glsl.js new file mode 100644 index 00000000000..7fcc4db3bc6 --- /dev/null +++ b/test/glsl.js @@ -0,0 +1,32 @@ +const assert = require('assert'); +const fs = require('fs'); +const {bundle, run, assertBundleTree} = require('./utils'); + +describe('glsl', function() { + it('should support requiring GLSL files via glslify', async function() { + let b = await bundle(__dirname + '/integration/glsl/index.js'); + + assertBundleTree(b, { + name: 'index.js', + assets: ['index.js', 'local.glsl', 'local.vert', 'local.frag'], + childBundles: [ + { + type: 'map' + } + ] + }); + + let shader = fs.readFileSync( + __dirname + '/integration/glsl/compiled.glsl', + 'utf8' + ); + + let output = run(b); + assert.equal(typeof output, 'function'); + assert.ok( + output().reduce((acc, requiredShader) => { + return acc && shader === requiredShader; + }, true) + ); + }); +}); diff --git a/test/integration/glsl/compiled.glsl b/test/integration/glsl/compiled.glsl new file mode 100644 index 00000000000..a233d86262e --- /dev/null +++ b/test/integration/glsl/compiled.glsl @@ -0,0 +1,11 @@ +#version 300 es + +void someUniqFunction() { +} + +precision mediump float; +#define GLSLIFY 1 + +void main() { + someUniqFunction(); +} diff --git a/test/integration/glsl/index.js b/test/integration/glsl/index.js new file mode 100644 index 00000000000..8bfa54194c3 --- /dev/null +++ b/test/integration/glsl/index.js @@ -0,0 +1,9 @@ +const shaders = [ + require('./local.glsl'), + require('./local.vert'), + require('./local.frag'), +]; + +module.exports = function () { + return shaders; +}; diff --git a/test/integration/glsl/lib.glsl b/test/integration/glsl/lib.glsl new file mode 100644 index 00000000000..244ebe994e5 --- /dev/null +++ b/test/integration/glsl/lib.glsl @@ -0,0 +1,4 @@ +void someUniqFunction() { +} + +#pragma glslify: export(someUniqFunction) diff --git a/test/integration/glsl/local.frag b/test/integration/glsl/local.frag new file mode 100644 index 00000000000..296cafe5180 --- /dev/null +++ b/test/integration/glsl/local.frag @@ -0,0 +1,9 @@ +#version 300 es + +#pragma glslify: test = require('./lib') + +precision mediump float; + +void main() { + test(); +} diff --git a/test/integration/glsl/local.glsl b/test/integration/glsl/local.glsl new file mode 100644 index 00000000000..e3ec16040eb --- /dev/null +++ b/test/integration/glsl/local.glsl @@ -0,0 +1,9 @@ +#version 300 es + +#pragma glslify: test = require('./lib.glsl') + +precision mediump float; + +void main() { + test(); +} diff --git a/test/integration/glsl/local.vert b/test/integration/glsl/local.vert new file mode 100644 index 00000000000..4d03ca28284 --- /dev/null +++ b/test/integration/glsl/local.vert @@ -0,0 +1,9 @@ +#version 300 es + +#pragma glslify: test = require('~/lib') + +precision mediump float; + +void main() { + test(); +} diff --git a/yarn.lock b/yarn.lock index 6257320bda4..479a0ecc052 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1310,6 +1310,10 @@ colormin@^1.0.5: css-color-names "0.0.4" has "^1.0.1" +colors@~0.6.0-1: + version "0.6.2" + resolved "https://registry.yarnpkg.com/colors/-/colors-0.6.2.tgz#2423fe6678ac0c5dae8852e5d0e5be08c997abcc" + colors@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63" @@ -1334,6 +1338,10 @@ commander@^2.11.0, commander@^2.9.0, commander@~2.15.0: version "2.15.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.0.tgz#ad2a23a1c3b036e392469b8012cec6b33b4c1322" +commander@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.1.0.tgz#d121bbae860d9992a3d517ba96f56588e47c6781" + commander@~2.13.0: version "2.13.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c" @@ -2036,7 +2044,7 @@ etag@~1.8.1: version "1.8.1" resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" -events@^1.0.0: +events@^1.0.0, events@^1.0.2: version "1.1.1" resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" @@ -2248,6 +2256,13 @@ find-up@^2.1.0: dependencies: locate-path "^2.0.0" +findup@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/findup/-/findup-0.1.5.tgz#8ad929a3393bac627957a7e5de4623b06b0e2ceb" + dependencies: + colors "~0.6.0-1" + commander "~2.1.0" + flat-cache@^1.2.1: version "1.3.0" resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.3.0.tgz#d3030b32b38154f4e3b7e9c709f490f7ef97c481" @@ -2507,6 +2522,98 @@ globule@^1.0.0: lodash "~4.17.4" minimatch "~3.0.2" +glsl-inject-defines@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/glsl-inject-defines/-/glsl-inject-defines-1.0.3.tgz#dd1aacc2c17fcb2bd3fc32411c6633d0d7b60fd4" + dependencies: + glsl-token-inject-block "^1.0.0" + glsl-token-string "^1.0.1" + glsl-tokenizer "^2.0.2" + +glsl-resolve@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/glsl-resolve/-/glsl-resolve-0.0.1.tgz#894bef73910d792c81b5143180035d0a78af76d3" + dependencies: + resolve "^0.6.1" + xtend "^2.1.2" + +glsl-token-assignments@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/glsl-token-assignments/-/glsl-token-assignments-2.0.2.tgz#a5d82ab78499c2e8a6b83cb69495e6e665ce019f" + +glsl-token-defines@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/glsl-token-defines/-/glsl-token-defines-1.0.0.tgz#cb892aa959936231728470d4f74032489697fa9d" + dependencies: + glsl-tokenizer "^2.0.0" + +glsl-token-depth@^1.1.0, glsl-token-depth@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/glsl-token-depth/-/glsl-token-depth-1.1.2.tgz#23c5e30ee2bd255884b4a28bc850b8f791e95d84" + +glsl-token-descope@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/glsl-token-descope/-/glsl-token-descope-1.0.2.tgz#0fc90ab326186b82f597b2e77dc9e21efcd32076" + dependencies: + glsl-token-assignments "^2.0.0" + glsl-token-depth "^1.1.0" + glsl-token-properties "^1.0.0" + glsl-token-scope "^1.1.0" + +glsl-token-inject-block@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/glsl-token-inject-block/-/glsl-token-inject-block-1.1.0.tgz#e1015f5980c1091824adaa2625f1dfde8bd00034" + +glsl-token-properties@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/glsl-token-properties/-/glsl-token-properties-1.0.1.tgz#483dc3d839f0d4b5c6171d1591f249be53c28a9e" + +glsl-token-scope@^1.1.0, glsl-token-scope@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/glsl-token-scope/-/glsl-token-scope-1.1.2.tgz#a1728e78df24444f9cb93fd18ef0f75503a643b1" + +glsl-token-string@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/glsl-token-string/-/glsl-token-string-1.0.1.tgz#59441d2f857de7c3449c945666021ece358e48ec" + +glsl-token-whitespace-trim@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/glsl-token-whitespace-trim/-/glsl-token-whitespace-trim-1.0.0.tgz#46d1dfe98c75bd7d504c05d7d11b1b3e9cc93b10" + +glsl-tokenizer@^2.0.0, glsl-tokenizer@^2.0.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/glsl-tokenizer/-/glsl-tokenizer-2.1.2.tgz#720307522e03c57af35c00551950c4a70ef2dfb9" + dependencies: + through2 "^0.6.3" + +glslify-bundle@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/glslify-bundle/-/glslify-bundle-5.0.0.tgz#0252ada1ef9df30b660006e0bb21fd130b486e42" + dependencies: + glsl-inject-defines "^1.0.1" + glsl-token-defines "^1.0.0" + glsl-token-depth "^1.1.1" + glsl-token-descope "^1.0.2" + glsl-token-scope "^1.1.1" + glsl-token-string "^1.0.1" + glsl-token-whitespace-trim "^1.0.0" + glsl-tokenizer "^2.0.2" + murmurhash-js "^1.0.0" + shallow-copy "0.0.1" + +glslify-deps@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/glslify-deps/-/glslify-deps-1.3.0.tgz#0b2234c8ea9e3d3fd7f6b3cb7f03ae59e6b51a59" + dependencies: + events "^1.0.2" + findup "^0.1.5" + glsl-resolve "0.0.1" + glsl-tokenizer "^2.0.0" + graceful-fs "^4.1.2" + inherits "^2.0.1" + map-limit "0.0.1" + resolve "^1.0.0" + graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.4: version "4.1.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" @@ -3819,6 +3926,12 @@ map-cache@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" +map-limit@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/map-limit/-/map-limit-0.0.1.tgz#eb7961031c0f0e8d001bf2d56fab685d58822f38" + dependencies: + once "~1.3.0" + map-obj@^1.0.0, map-obj@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" @@ -4012,6 +4125,10 @@ ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" +murmurhash-js@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/murmurhash-js/-/murmurhash-js-1.0.0.tgz#b06278e21fc6c37fa5313732b0412bcb6ae15f51" + mute-stream@0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" @@ -4346,6 +4463,12 @@ once@^1.3.0, once@^1.3.3: dependencies: wrappy "1" +once@~1.3.0: + version "1.3.3" + resolved "https://registry.yarnpkg.com/once/-/once-1.3.3.tgz#b2e261557ce4c314ec8304f3fa82663e4297ca20" + dependencies: + wrappy "1" + onetime@^1.0.0: version "1.1.0" resolved "http://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789" @@ -4933,6 +5056,10 @@ private@^0.1.6, private@^0.1.7: version "0.1.8" resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" +process-nextick-args@~1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" + process-nextick-args@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" @@ -5068,9 +5195,30 @@ read-pkg@^1.0.0: normalize-package-data "^2.3.2" path-type "^1.0.0" -readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@~2.3.3: - version "2.3.5" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.5.tgz#b4f85003a938cbb6ecbce2a124fb1012bd1a838d" +"readable-stream@>=1.0.33-1 <1.1.0-0": + version "1.0.34" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.2.2, readable-stream@^2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.3.tgz#368f2512d79f9d46fdfc71349ae7878bbc1eb95c" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~1.0.6" + safe-buffer "~5.1.1" + string_decoder "~1.0.3" + util-deprecate "~1.0.1" + +readable-stream@^2.1.5, readable-stream@~2.3.3: + version "2.3.4" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.4.tgz#c946c3f47fa7d8eabc0b6150f4a12f69a4574071" dependencies: core-util-is "~1.0.0" inherits "~2.0.3" @@ -5297,6 +5445,16 @@ resolve-url@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" +resolve@^0.6.1: + version "0.6.3" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-0.6.3.tgz#dd957982e7e736debdf53b58a4dd91754575dd46" + +resolve@^1.0.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.6.0.tgz#0fbd21278b27b4004481c395349e7aba60a9ff5c" + dependencies: + path-parse "^1.0.5" + resolve@^1.1.5, resolve@^1.4.0: version "1.5.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.5.0.tgz#1f09acce796c9a762579f31b2c1cc4c3cddf9f36" @@ -5489,7 +5647,7 @@ sha.js@^2.4.0, sha.js@^2.4.8: inherits "^2.0.1" safe-buffer "^5.0.1" -shallow-copy@~0.0.1: +shallow-copy@0.0.1, shallow-copy@~0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/shallow-copy/-/shallow-copy-0.0.1.tgz#415f42702d73d810330292cc5ee86eae1a11a170" @@ -5788,18 +5946,16 @@ string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" -string_decoder@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.0.tgz#384f322ee8a848e500effde99901bba849c5d403" - dependencies: - safe-buffer "~5.1.0" - -string_decoder@~1.0.3: +string_decoder@^1.0.0, string_decoder@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab" dependencies: safe-buffer "~5.1.0" +string_decoder@~0.10.x: + version "0.10.31" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + stringify-object@^3.2.0: version "3.2.2" resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-3.2.2.tgz#9853052e5a88fb605a44cd27445aa257ad7ffbcd" @@ -5970,6 +6126,13 @@ text-table@~0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" +through2@^0.6.3: + version "0.6.5" + resolved "https://registry.yarnpkg.com/through2/-/through2-0.6.5.tgz#41ab9c67b29d57209071410e1d7a7a968cd3ad48" + dependencies: + readable-stream ">=1.0.33-1 <1.1.0-0" + xtend ">=4.0.0 <4.1.0-0" + through2@^2.0.0, through2@~2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be" @@ -6330,10 +6493,14 @@ ws@^4.0.0: async-limiter "~1.0.0" safe-buffer "~5.1.0" -xtend@^4.0.0, xtend@~4.0.1: +"xtend@>=4.0.0 <4.1.0-0", xtend@^4.0.0, xtend@~4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" +xtend@^2.1.2: + version "2.2.0" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-2.2.0.tgz#eef6b1f198c1c8deafad8b1765a04dad4a01c5a9" + y18n@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41"