gulpfile.js 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984
  1. var gulp = require("gulp");
  2. var uglify = require("gulp-uglify");
  3. var typescript = require("gulp-typescript");
  4. var sourcemaps = require("gulp-sourcemaps");
  5. var srcToVariable = require("gulp-content-to-variable");
  6. var appendSrcToVariable = require("./gulp-appendSrcToVariable");
  7. var addDtsExport = require("./gulp-addDtsExport");
  8. var addModuleExports = require("./gulp-addModuleExports");
  9. var addES6Exports = require("./gulp-addES6Exports");
  10. var babylonModuleExports = require("./gulp-babylonModule");
  11. var babylonES6ModuleExports = require("./gulp-es6ModuleExports");
  12. var dtsModuleSupport = require("./gulp-dtsModuleSupport");
  13. let calculateDependencies = require("./gulp-calculateDependencies");
  14. var merge2 = require("merge2");
  15. var concat = require("gulp-concat");
  16. var rename = require("gulp-rename");
  17. var cleants = require("gulp-clean-ts-extends");
  18. var changedInPlace = require("gulp-changed-in-place");
  19. var runSequence = require("run-sequence");
  20. var replace = require("gulp-replace");
  21. var uncommentShader = require("./gulp-removeShaderComments");
  22. var expect = require("gulp-expect-file");
  23. var optimisejs = require("gulp-optimize-js");
  24. var webserver = require("gulp-webserver");
  25. var path = require("path");
  26. var sass = require("gulp-sass");
  27. var webpack = require("webpack-stream");
  28. var typedoc = require("gulp-typedoc");
  29. var validateTypedoc = require("./gulp-validateTypedoc");
  30. var request = require('request');
  31. var fs = require("fs");
  32. var karmaServer = require('karma').Server;
  33. var config = require("./config.json");
  34. var del = require("del");
  35. var debug = require("gulp-debug");
  36. var includeShadersStream;
  37. var shadersStream;
  38. var workersStream;
  39. var extendsSearchRegex = /var\s__extends[\s\S]+?\}\)\(\);/g;
  40. var decorateSearchRegex = /var\s__decorate[\s\S]+?\};/g;
  41. var referenceSearchRegex = /\/\/\/ <reference.*/g;
  42. /**
  43. * TS configurations shared in the gulp file.
  44. */
  45. var tsConfig = {
  46. noResolve: true,
  47. target: "ES5",
  48. declarationFiles: true,
  49. typescript: require("typescript"),
  50. experimentalDecorators: true,
  51. isolatedModules: false,
  52. noImplicitAny: true,
  53. noImplicitReturns: true,
  54. noImplicitThis: true,
  55. noUnusedLocals: true,
  56. strictNullChecks: true,
  57. strictFunctionTypes: true,
  58. types: []
  59. };
  60. var tsProject = typescript.createProject(tsConfig);
  61. var externalTsConfig = {
  62. noResolve: false,
  63. target: "ES5",
  64. declarationFiles: true,
  65. typescript: require("typescript"),
  66. experimentalDecorators: true,
  67. isolatedModules: false,
  68. noImplicitAny: true,
  69. noImplicitReturns: true,
  70. noImplicitThis: true,
  71. noUnusedLocals: true,
  72. strictNullChecks: true,
  73. types: []
  74. };
  75. var minimist = require("minimist");
  76. var commandLineOptions = minimist(process.argv.slice(2), {
  77. boolean: "public"
  78. });
  79. function processDependency(kind, dependency, filesToLoad, firstLevelOnly) {
  80. if (!firstLevelOnly && dependency.dependUpon) {
  81. for (var i = 0; i < dependency.dependUpon.length; i++) {
  82. var dependencyName = dependency.dependUpon[i];
  83. var parent = config.workloads[dependencyName];
  84. processDependency(kind, parent, filesToLoad);
  85. }
  86. }
  87. var content = dependency[kind];
  88. if (!content) {
  89. return;
  90. }
  91. for (var i = 0; i < content.length; i++) {
  92. var file = content[i];
  93. if (filesToLoad.indexOf(file) === -1) {
  94. filesToLoad.push(file);
  95. }
  96. }
  97. }
  98. function determineFilesToProcess(kind) {
  99. var currentConfig = config.build.currentConfig;
  100. var buildConfiguration = config.buildConfigurations[currentConfig];
  101. var filesToLoad = [];
  102. for (var index = 0; index < buildConfiguration.length; index++) {
  103. var dependencyName = buildConfiguration[index];
  104. var dependency = config.workloads[dependencyName];
  105. if (kind === "directFiles" && !dependency) {
  106. filesToLoad.push("../../dist/preview release/" + dependencyName);
  107. }
  108. else if (dependency) {
  109. processDependency(kind, dependency, filesToLoad);
  110. }
  111. }
  112. if (kind === "shaderIncludes") {
  113. for (var index = 0; index < filesToLoad.length; index++) {
  114. filesToLoad[index] = "../../src/Shaders/ShadersInclude/" + filesToLoad[index] + ".fx";
  115. }
  116. } else if (kind === "shaders") {
  117. for (var index = 0; index < filesToLoad.length; index++) {
  118. var name = filesToLoad[index];
  119. filesToLoad[index] = "../../src/Shaders/" + filesToLoad[index] + ".fx";
  120. }
  121. }
  122. return filesToLoad;
  123. }
  124. /*
  125. * Shader Management.
  126. */
  127. function shadersName(filename) {
  128. return path.basename(filename)
  129. .replace(".fragment", "Pixel")
  130. .replace(".vertex", "Vertex")
  131. .replace(".fx", "Shader");
  132. }
  133. function includeShadersName(filename) {
  134. return path.basename(filename).replace(".fx", "");
  135. }
  136. /*
  137. * Main necessary files stream Management.
  138. */
  139. gulp.task("includeShaders", function (cb) {
  140. var filesToProcess = determineFilesToProcess("shaderIncludes");
  141. includeShadersStream = gulp.src(filesToProcess).
  142. pipe(expect.real({ errorOnFailure: true }, filesToProcess)).
  143. pipe(uncommentShader()).
  144. pipe(srcToVariable({
  145. variableName: "BABYLON.Effect.IncludesShadersStore", asMap: true, namingCallback: includeShadersName
  146. }));
  147. cb();
  148. });
  149. gulp.task("shaders", ["includeShaders"], function (cb) {
  150. var filesToProcess = determineFilesToProcess("shaders");
  151. shadersStream = gulp.src(filesToProcess).
  152. pipe(expect.real({ errorOnFailure: true }, filesToProcess)).
  153. pipe(uncommentShader()).
  154. pipe(srcToVariable({
  155. variableName: "BABYLON.Effect.ShadersStore", asMap: true, namingCallback: shadersName
  156. }));
  157. cb();
  158. });
  159. gulp.task("workers", function (cb) {
  160. workersStream = config.workers.map(function (workerDef) {
  161. return gulp.src(workerDef.files).
  162. pipe(expect.real({ errorOnFailure: true }, workerDef.files)).
  163. pipe(uglify()).
  164. pipe(srcToVariable({
  165. variableName: workerDef.variable
  166. }));
  167. });
  168. cb();
  169. });
  170. /**
  171. * Build tasks to concat minify uflify optimise the BJS js in different flavor (workers...).
  172. */
  173. gulp.task("buildWorker", ["workers", "shaders"], function () {
  174. var filesToProcess = determineFilesToProcess("files");
  175. return merge2(
  176. gulp.src(filesToProcess).
  177. pipe(expect.real({ errorOnFailure: true }, filesToProcess)),
  178. shadersStream,
  179. includeShadersStream,
  180. workersStream
  181. )
  182. .pipe(concat(config.build.minWorkerFilename))
  183. .pipe(cleants())
  184. .pipe(replace(extendsSearchRegex, ""))
  185. .pipe(replace(decorateSearchRegex, ""))
  186. .pipe(addModuleExports("BABYLON"))
  187. .pipe(uglify())
  188. .pipe(optimisejs())
  189. .pipe(gulp.dest(config.build.outputDirectory));
  190. });
  191. gulp.task("build", ["shaders"], function () {
  192. var filesToProcess = determineFilesToProcess("files");
  193. var directFilesToProcess = determineFilesToProcess("directFiles");
  194. let mergedStreams = merge2(
  195. gulp.src(filesToProcess).
  196. pipe(expect.real({ errorOnFailure: true }, filesToProcess)),
  197. shadersStream,
  198. includeShadersStream,
  199. gulp.src(directFilesToProcess)
  200. )
  201. return merge2(
  202. mergedStreams
  203. .pipe(concat(config.build.filename))
  204. .pipe(cleants())
  205. .pipe(replace(extendsSearchRegex, ""))
  206. .pipe(replace(decorateSearchRegex, ""))
  207. .pipe(addModuleExports("BABYLON"))
  208. .pipe(gulp.dest(config.build.outputDirectory))
  209. .pipe(rename(config.build.minFilename))
  210. .pipe(uglify())
  211. .pipe(optimisejs())
  212. .pipe(gulp.dest(config.build.outputDirectory)),
  213. mergedStreams
  214. .pipe(concat("es6.js"))
  215. .pipe(cleants())
  216. .pipe(replace(extendsSearchRegex, ""))
  217. .pipe(replace(decorateSearchRegex, ""))
  218. .pipe(addES6Exports("BABYLON"))
  219. .pipe(gulp.dest(config.build.outputDirectory))
  220. );
  221. });
  222. /*
  223. * Compiles all typescript files and creating a js and a declaration file.
  224. */
  225. gulp.task("typescript-compile", function () {
  226. var tsResult = gulp.src(config.typescript)
  227. .pipe(sourcemaps.init())
  228. .pipe(tsProject());
  229. //If this gulp task is running on travis, file the build!
  230. if (process.env.TRAVIS) {
  231. tsResult.once("error", function () {
  232. tsResult.once("finish", function () {
  233. console.log("Typescript compile failed");
  234. process.exit(1);
  235. });
  236. });
  237. }
  238. return merge2([
  239. tsResult.dts
  240. .pipe(concat(config.build.declarationFilename))
  241. .pipe(addDtsExport("BABYLON", "babylonjs"))
  242. .pipe(gulp.dest(config.build.outputDirectory)),
  243. tsResult.js
  244. .pipe(sourcemaps.write("./",
  245. {
  246. includeContent: false,
  247. sourceRoot: (filePath) => {
  248. return "";
  249. }
  250. }))
  251. .pipe(gulp.dest(config.build.srcOutputDirectory))
  252. ])
  253. });
  254. /**
  255. * Helper methods to build external library (mat, post processes, ...).
  256. */
  257. var buildExternalLibraries = function (settings) {
  258. var tasks = settings.libraries.map(function (library) {
  259. return buildExternalLibrary(library, settings, false);
  260. });
  261. let mergedTasks = merge2(tasks);
  262. if (settings.build.buildAsModule) {
  263. mergedTasks.on("end", function () {
  264. //generate js file list
  265. let files = settings.libraries.filter(function (lib) {
  266. return !lib.doNotIncludeInBundle;
  267. }).map(function (lib) {
  268. return config.build.outputDirectory + settings.build.distOutputDirectory + lib.output;
  269. });
  270. var outputDirectory = config.build.outputDirectory + settings.build.distOutputDirectory;
  271. let srcTask = gulp.src(files)
  272. .pipe(concat(settings.build.outputFilename + ".js"))
  273. .pipe(replace(extendsSearchRegex, ""))
  274. .pipe(replace(decorateSearchRegex, ""))
  275. .pipe(replace(referenceSearchRegex, ""))
  276. .pipe(addModuleExports(settings.build.moduleDeclaration, true, settings.build.extendsRoot))
  277. .pipe(gulp.dest(outputDirectory))
  278. .pipe(cleants())
  279. .pipe(rename({ extname: ".min.js" }))
  280. .pipe(uglify())
  281. .pipe(optimisejs())
  282. .pipe(gulp.dest(outputDirectory));
  283. let dtsFiles = files.map(function (filename) {
  284. return filename.replace(".js", ".d.ts");
  285. });
  286. let dtsTask = gulp.src(dtsFiles)
  287. .pipe(concat(settings.build.outputFilename + ".module.d.ts"))
  288. .pipe(replace(referenceSearchRegex, ""))
  289. .pipe(addDtsExport(settings.build.moduleDeclaration, settings.build.moduleName, true, settings.build.extendsRoot))
  290. .pipe(gulp.dest(outputDirectory));
  291. return merge2([srcTask, dtsTask]);
  292. });
  293. }
  294. return mergedTasks;
  295. }
  296. var buildExternalLibrary = function (library, settings, watch) {
  297. var tsProcess = gulp.src(library.files, { base: settings.build.srcOutputDirectory })
  298. .pipe(sourcemaps.init())
  299. .pipe(typescript(externalTsConfig));
  300. var includeShader = gulp.src(library.shadersIncludeFiles || [], { base: settings.build.srcOutputDirectory })
  301. .pipe(uncommentShader())
  302. .pipe(appendSrcToVariable("BABYLON.Effect.IncludesShadersStore", includeShadersName, library.output + ".include.fx"))
  303. .pipe(gulp.dest(settings.build.srcOutputDirectory));
  304. var shader = gulp.src(library.shaderFiles || [], { base: settings.build.srcOutputDirectory })
  305. .pipe(uncommentShader())
  306. .pipe(appendSrcToVariable("BABYLON.Effect.ShadersStore", shadersName, library.output + ".fx"))
  307. .pipe(gulp.dest(settings.build.srcOutputDirectory));
  308. var dev = tsProcess.js
  309. .pipe(sourcemaps.write("./", {
  310. includeContent: false,
  311. sourceRoot: (filePath) => {
  312. return "";
  313. }
  314. })).pipe(gulp.dest(settings.build.srcOutputDirectory));
  315. var outputDirectory = config.build.outputDirectory + settings.build.distOutputDirectory;
  316. var css = gulp.src(library.sassFiles || [])
  317. .pipe(sass().on("error", sass.logError))
  318. .pipe(concat(library.output.replace(".js", ".css")))
  319. .pipe(gulp.dest(outputDirectory));
  320. if (watch) {
  321. return merge2([shader, includeShader, dev, css]);
  322. }
  323. else {
  324. /*if (library.bundle) {
  325. // Don't remove extends and decorate functions
  326. var code = merge2([tsProcess.js, shader, includeShader])
  327. .pipe(concat(library.output));
  328. if (library.buildAsModule) {
  329. code = code.pipe(addModuleExports(library.moduleDeclaration, true))
  330. }
  331. code.pipe(gulp.dest(outputDirectory))
  332. .pipe(cleants())
  333. .pipe(rename({ extname: ".min.js" }))
  334. .pipe(uglify())
  335. .pipe(optimisejs())
  336. .pipe(gulp.dest(outputDirectory));
  337. } else {*/
  338. var code = merge2([tsProcess.js, shader, includeShader])
  339. .pipe(concat(library.output))
  340. if (library.buildAsModule) {
  341. code = code.pipe(replace(extendsSearchRegex, ""))
  342. .pipe(replace(decorateSearchRegex, ""))
  343. .pipe(addModuleExports(library.moduleDeclaration, true, library.extendsRoot))
  344. }
  345. code = code.pipe(gulp.dest(outputDirectory))
  346. .pipe(cleants())
  347. .pipe(rename({ extname: ".min.js" }))
  348. .pipe(uglify())
  349. .pipe(optimisejs())
  350. .pipe(gulp.dest(outputDirectory));
  351. /*}*/
  352. var dts = tsProcess.dts
  353. .pipe(concat(library.output))
  354. .pipe(replace(referenceSearchRegex, ""))
  355. .pipe(rename({ extname: ".d.ts" }))
  356. .pipe(gulp.dest(outputDirectory));
  357. var waitAll;
  358. if (library.buildAsModule) {
  359. var dts2 = tsProcess.dts
  360. .pipe(concat(library.output))
  361. .pipe(replace(referenceSearchRegex, ""))
  362. .pipe(addDtsExport(library.moduleDeclaration, library.moduleName, true, library.extendsRoot))
  363. .pipe(rename({ extname: ".module.d.ts" }))
  364. .pipe(gulp.dest(outputDirectory));
  365. waitAll = merge2([dev, code, css, dts, dts2]);
  366. } else {
  367. waitAll = merge2([dev, code, css, dts]);
  368. }
  369. if (library.webpack) {
  370. return waitAll.on("end", function () {
  371. return webpack(require(library.webpack))
  372. .pipe(rename(library.output.replace(".js", library.noBundleInName ? '.js' : ".bundle.js")))
  373. .pipe(addModuleExports(library.moduleDeclaration, false, false, true))
  374. .pipe(uglify())
  375. .pipe(optimisejs())
  376. .pipe(gulp.dest(outputDirectory))
  377. });
  378. }
  379. else {
  380. return waitAll;
  381. }
  382. }
  383. }
  384. /**
  385. * The default task, concat and min the main BJS files.
  386. */
  387. gulp.task("default", function (cb) {
  388. runSequence("typescript-all", "intellisense", "typedoc-all", "tests-unit", "tests-validation-virtualscreen", "tests-validation-browserstack", cb);
  389. });
  390. gulp.task("mainBuild", function (cb) {
  391. runSequence("buildWorker", "build", cb);
  392. });
  393. /**
  394. * Build the releasable files.
  395. */
  396. gulp.task("typescript", function (cb) {
  397. runSequence("typescript-compile", "mainBuild", cb);
  398. });
  399. /**
  400. * Dynamic module creation.
  401. */
  402. config.modules.map(function (module) {
  403. gulp.task(module, function () {
  404. return buildExternalLibraries(config[module]);
  405. });
  406. });
  407. gulp.task("typescript-libraries", config.modules, function () {
  408. });
  409. /**
  410. * Dynamic custom configurations.
  411. */
  412. config.buildConfigurations.distributed.map(function (customConfiguration) {
  413. gulp.task(customConfiguration, function (cb) {
  414. config.build.currentConfig = customConfiguration;
  415. config.build.outputDirectory = config.build.outputCustomConfigurationsDirectory + "/" + customConfiguration;
  416. runSequence("typescript-compile", "build", cb);
  417. });
  418. });
  419. gulp.task("typescript-customConfigurations", function (cb) {
  420. runSequence(config.buildConfigurations.distributed, cb);
  421. });
  422. /**
  423. * Custom build with full path file control; used by profile.html
  424. */
  425. gulp.task("build-custom", function (cb) {
  426. runSequence("typescript-compile", "build", cb);
  427. });
  428. /**
  429. * Do it all.
  430. */
  431. gulp.task("typescript-all", function (cb) {
  432. runSequence("typescript", "typescript-libraries", "typescript-customConfigurations", cb);
  433. });
  434. /**
  435. * Watch ts files from typescript .
  436. */
  437. gulp.task("srcTscWatch", function () {
  438. // Reuse The TSC CLI from gulp to enable -w.
  439. process.argv[2] = "-w";
  440. process.argv[3] = "-p";
  441. process.argv[4] = "../../src/tsconfig.json";
  442. require("./node_modules/typescript/lib/tsc.js");
  443. });
  444. /**
  445. * Watch ts files and fire repective tasks.
  446. */
  447. gulp.task("watch", ["srcTscWatch"], function () {
  448. var interval = 1000;
  449. var tasks = [];
  450. config.modules.map(function (module) {
  451. config[module].libraries.map(function (library) {
  452. tasks.push(gulp.watch(library.files, { interval: interval }, function () {
  453. console.log(library.output);
  454. return buildExternalLibrary(library, config[module], true)
  455. .pipe(debug());
  456. }));
  457. tasks.push(gulp.watch(library.shaderFiles, { interval: interval }, function () {
  458. console.log(library.output);
  459. return buildExternalLibrary(library, config[module], true)
  460. .pipe(debug())
  461. }));
  462. tasks.push(gulp.watch(library.sassFiles, { interval: interval }, function () {
  463. console.log(library.output);
  464. return buildExternalLibrary(library, config[module], true)
  465. .pipe(debug())
  466. }));
  467. });
  468. });
  469. return tasks;
  470. });
  471. gulp.task("intellisense", function () {
  472. gulp.src(config.build.intellisenseSources)
  473. .pipe(concat(config.build.intellisenseFile))
  474. .pipe(replace(/^\s*_.*?$/gm, ""))
  475. .pipe(replace(/^\s*private .*?$/gm, ""))
  476. .pipe(replace(/^\s*public _.*?$/gm, ""))
  477. .pipe(replace(/^\s*protected .*?$/gm, ""))
  478. .pipe(replace(/^\s*public static _.*?$/gm, ""))
  479. .pipe(replace(/^\s*static _.*?$/gm, ""))
  480. .pipe(gulp.dest(config.build.playgroundDirectory));
  481. });
  482. /**
  483. * Embedded local dev env management.
  484. */
  485. gulp.task("deployLocalDev", function () {
  486. gulp.src("../../localDev/template/**.*")
  487. .pipe(gulp.dest("../../localDev/src/"));
  488. });
  489. /**
  490. * Embedded webserver for test convenience.
  491. */
  492. gulp.task("webserver", function () {
  493. var options = {
  494. port: 1338,
  495. livereload: false
  496. };
  497. if (commandLineOptions.public) {
  498. options.host = "0.0.0.0";
  499. }
  500. gulp.src("../../.").pipe(webserver(options));
  501. });
  502. /**
  503. * Combine Webserver and Watch as long as vscode does not handle multi tasks.
  504. */
  505. gulp.task("run", ["watch", "webserver"], function () {
  506. });
  507. /**
  508. * Cleans map and js files from the src folder.
  509. */
  510. gulp.task("clean-JS-MAP", function () {
  511. return del([
  512. "../../src/**/*.js.map", "../../src/**/*.js"
  513. ], { force: true });
  514. });
  515. // this is needed for the modules for the declaration files.
  516. gulp.task("modules-compile", function () {
  517. var tsResult = gulp.src(config.typescript)
  518. .pipe(sourcemaps.init())
  519. .pipe(tsProject());
  520. // If this gulp task is running on travis
  521. if (process.env.TRAVIS) {
  522. tsResult.once("error", function () {
  523. tsResult.once("finish", function () {
  524. console.log("Typescript compile failed");
  525. process.exit(1);
  526. });
  527. });
  528. }
  529. return merge2([
  530. tsResult.dts
  531. .pipe(gulp.dest(config.build.srcOutputDirectory)),
  532. tsResult.js
  533. .pipe(sourcemaps.write("./",
  534. {
  535. includeContent: false,
  536. sourceRoot: (filePath) => {
  537. return "";
  538. }
  539. }))
  540. .pipe(gulp.dest(config.build.srcOutputDirectory))
  541. ]);
  542. });
  543. // this holds the declared objects in each module
  544. let declared = {}
  545. let perFile = {};
  546. let dependencyTree = {};
  547. gulp.task('prepare-for-modules', /*["modules-compile"],*/ function () {
  548. let tasks = [];
  549. Object.keys(config.workloads).forEach((moduleName) => {
  550. let dtsFiles = config.workloads[moduleName].files.map(f => f.replace(".js", ".d.ts"))
  551. let dtsTask = gulp.src(dtsFiles)
  552. .pipe(dtsModuleSupport(moduleName, false, declared, perFile));
  553. tasks.push(dtsTask);
  554. });
  555. // now calculate internal dependencies in the .ts files!
  556. /*Object.keys(config.workloads).forEach((moduleName) => {
  557. let tsFiles = config.workloads[moduleName].files.map(f => f.replace(".js", ".ts"))
  558. let depTask = gulp.src(tsFiles)
  559. .pipe(calculateDependencies(moduleName, perFile, dependencyTree));
  560. tasks.push(depTask);
  561. });*/
  562. return merge2(tasks);
  563. });
  564. gulp.task('prepare-dependency-tree', ["prepare-for-modules"], function () {
  565. let tasks = [];
  566. // now calculate internal dependencies in the .ts files!
  567. Object.keys(config.workloads).forEach((moduleName) => {
  568. let tsFiles = config.workloads[moduleName].files.map(f => f.replace(".js", ".ts"))
  569. let depTask = gulp.src(tsFiles)
  570. .pipe(calculateDependencies(moduleName, perFile, declared, dependencyTree));
  571. tasks.push(depTask);
  572. });
  573. return merge2(tasks);
  574. });
  575. // generate the modules directory, along with commonjs modules and es6 modules
  576. // Note - the generated modules are UNMINIFIED! The user will choose whether they want to minify or not.
  577. gulp.task("modules", ["prepare-dependency-tree"], function () {
  578. let tasks = [];
  579. Object.keys(config.workloads)
  580. .forEach((moduleName) => {
  581. let shadersFiles = [];
  582. processDependency("shaders", config.workloads[moduleName], shadersFiles, true);
  583. for (var index = 0; index < shadersFiles.length; index++) {
  584. shadersFiles[index] = "../../src/Shaders/" + shadersFiles[index] + ".fx";
  585. }
  586. let shaderIncludeFiles = [];
  587. processDependency("shaderIncludes", config.workloads[moduleName], shaderIncludeFiles, true);
  588. for (var index = 0; index < shaderIncludeFiles.length; index++) {
  589. shaderIncludeFiles[index] = "../../src/Shaders/ShadersInclude/" + shaderIncludeFiles[index] + ".fx";
  590. }
  591. let commonJsTask = merge2([
  592. gulp.src(config.workloads[moduleName].files)
  593. .pipe(replace(extendsSearchRegex, ""))
  594. .pipe(replace(decorateSearchRegex, ""))
  595. .pipe(replace(referenceSearchRegex, ""))
  596. .pipe(replace(/var BABYLON;\n/g, ""))
  597. .pipe(babylonModuleExports(moduleName, dependencyTree, false, perFile, shadersFiles.length, shaderIncludeFiles.length))
  598. .pipe(rename(function (path) {
  599. path.basename = path.basename.split(".").pop()
  600. path.extname = ".js"
  601. })),
  602. gulp.src(shadersFiles)
  603. .pipe(expect.real({ errorOnFailure: true }, shadersFiles))
  604. .pipe(uncommentShader())
  605. .pipe(appendSrcToVariable("BABYLON.Effect.ShadersStore", shadersName, config.build.outputDirectory + '/commonjs/' + moduleName + ".fx", "commonjs"))
  606. .pipe(rename("shaders.js")),
  607. gulp.src(shaderIncludeFiles)
  608. .pipe(expect.real({ errorOnFailure: true }, shaderIncludeFiles))
  609. .pipe(uncommentShader())
  610. .pipe(appendSrcToVariable("BABYLON.Effect.IncludesShadersStore", includeShadersName, config.build.outputDirectory + '/commonjs/' + moduleName + ".include.fx", "commonjs"))
  611. .pipe(rename("shaderIncludes.js")),
  612. gulp.src(config.workloads[moduleName].files)
  613. .pipe(concat('index.js'))
  614. .pipe(babylonModuleExports(moduleName, dependencyTree, true, perFile))
  615. ]).pipe(gulp.dest(config.build.outputDirectory + '/modules/' + moduleName + '/'))
  616. let es6Tasks = merge2([
  617. gulp.src(config.workloads[moduleName].files)
  618. .pipe(replace(extendsSearchRegex, ""))
  619. .pipe(replace(decorateSearchRegex, ""))
  620. .pipe(replace(referenceSearchRegex, ""))
  621. .pipe(replace(/var BABYLON;\n/g, ""))
  622. .pipe(babylonES6ModuleExports(moduleName, dependencyTree, false, perFile, shadersFiles.length, shaderIncludeFiles.length))
  623. .pipe(rename(function (path) {
  624. path.basename = path.basename.split(".").pop()
  625. path.extname = ".js"
  626. })),
  627. gulp.src(shadersFiles)
  628. .pipe(expect.real({ errorOnFailure: true }, shadersFiles))
  629. .pipe(uncommentShader())
  630. .pipe(appendSrcToVariable("BABYLON.Effect.ShadersStore", shadersName, config.build.outputDirectory + '/es6/' + moduleName + ".fx", "es6"))
  631. .pipe(rename("shaders.js")),
  632. gulp.src(shaderIncludeFiles)
  633. .pipe(expect.real({ errorOnFailure: true }, shaderIncludeFiles))
  634. .pipe(uncommentShader())
  635. .pipe(appendSrcToVariable("BABYLON.Effect.IncludesShadersStore", includeShadersName, config.build.outputDirectory + '/es6/' + moduleName + ".include.fx", "es6"))
  636. .pipe(rename("shaderIncludes.js")),
  637. gulp.src(config.workloads[moduleName].files)
  638. .pipe(concat('index.js'))
  639. .pipe(babylonES6ModuleExports(moduleName, dependencyTree, true, perFile))
  640. ]).pipe(gulp.dest(config.build.outputDirectory + '/modules/' + moduleName + '/es6/'))
  641. //commonjs js generation task
  642. /*let jsTask = merge2([
  643. gulp.src(config.workloads[moduleName].files),
  644. gulp.src(shadersFiles).
  645. //pipe(expect.real({ errorOnFailure: true }, shadersFiles)).
  646. pipe(uncommentShader()).
  647. pipe(appendSrcToVariable("BABYLON.Effect.ShadersStore", shadersName, config.build.outputDirectory + '/commonjs/' + moduleName + ".fx", true)),
  648. gulp.src(shaderIncludeFiles).
  649. //pipe(expect.real({ errorOnFailure: true }, shaderIncludeFiles)).
  650. pipe(uncommentShader()).
  651. pipe(appendSrcToVariable("BABYLON.Effect.IncludesShadersStore", includeShadersName, config.build.outputDirectory + '/commonjs/' + moduleName + ".include.fx", true))
  652. ]).pipe(concat('index.js'))
  653. .pipe(replace(extendsSearchRegex, ""))
  654. .pipe(replace(decorateSearchRegex, ""))
  655. .pipe(replace(referenceSearchRegex, ""))
  656. .pipe(babylonModuleExports(moduleName, config.workloads[moduleName].dependUpon))
  657. .pipe(gulp.dest(config.build.outputDirectory + '/modules/' + moduleName + '/'));*/
  658. // es6 modules generation task
  659. /*let es6Task = merge2([
  660. gulp.src(config.workloads[moduleName].files),
  661. gulp.src(shadersFiles).
  662. //pipe(expect.real({ errorOnFailure: true }, shadersFiles)).
  663. pipe(uncommentShader()).
  664. pipe(appendSrcToVariable("BABYLON.Effect.ShadersStore", shadersName, config.build.outputDirectory + '/commonjs/' + moduleName + ".fx", true)),
  665. gulp.src(shaderIncludeFiles).
  666. //pipe(expect.real({ errorOnFailure: true }, shaderIncludeFiles)).
  667. pipe(uncommentShader()).
  668. pipe(appendSrcToVariable("BABYLON.Effect.IncludesShadersStore", includeShadersName, config.build.outputDirectory + '/commonjs/' + moduleName + ".include.fx", true))
  669. ]).pipe(concat('es6.js'))
  670. .pipe(replace(extendsSearchRegex, ""))
  671. .pipe(replace(decorateSearchRegex, ""))
  672. .pipe(replace(referenceSearchRegex, ""))
  673. .pipe(replace(/var BABYLON;/g, ""))
  674. .pipe(babylonES6ModuleExports(moduleName, config.workloads[moduleName].dependUpon))
  675. .pipe(gulp.dest(config.build.outputDirectory + '/modules/' + moduleName + '/'));
  676. // dts genration task
  677. let dtsFiles = config.workloads[moduleName].files.map(f => f.replace(".js", ".d.ts"))
  678. let dtsTask = gulp.src(dtsFiles)
  679. .pipe(concat("index.d.ts"))
  680. .pipe(replace(/declare module BABYLON {/g, `declare module 'babylonjs/${moduleName}' {`))
  681. .pipe(replace(/\ninterface /g, `\nexport interface `))
  682. .pipe(dtsModuleSupport(moduleName, true, declared, perFile, dependencyTree))
  683. .pipe(gulp.dest(config.build.outputDirectory + '/modules/' + moduleName + '/'));
  684. */
  685. tasks.push(commonJsTask, es6Tasks);
  686. });
  687. // run da tasks man!
  688. return merge2(tasks);
  689. })
  690. /**
  691. * Generate the TypeDoc JSON output in order to create code metadata.
  692. */
  693. gulp.task("typedoc-generate", function () {
  694. return gulp
  695. .src(["../../dist/preview release/babylon.d.ts"])
  696. .pipe(typedoc({
  697. // TypeScript options (see typescript docs)
  698. mode: "modules",
  699. module: "commonjs",
  700. target: "es5",
  701. includeDeclarations: true,
  702. // Output options (see typedoc docs)
  703. json: config.build.typedocJSON,
  704. // TypeDoc options (see typedoc docs)
  705. ignoreCompilerErrors: true,
  706. readme: "none",
  707. excludeExternals: true,
  708. excludePrivate: true,
  709. excludeProtected: true,
  710. entryPoint: ["\"babylon.d\"", "BABYLON"]
  711. }));
  712. });
  713. /**
  714. * Validate the TypeDoc JSON output against the current baselin to ensure our code is correctly documented.
  715. * (in the newly introduced areas)
  716. */
  717. gulp.task("typedoc-validate", function () {
  718. return gulp.src(config.build.typedocJSON)
  719. .pipe(validateTypedoc(config.build.typedocValidationBaseline, "BABYLON", true, false));
  720. });
  721. /**
  722. * Generate the validation reference to ensure our code is correctly documented.
  723. */
  724. gulp.task("typedoc-generateValidationBaseline", function () {
  725. return gulp.src(config.build.typedocJSON)
  726. .pipe(validateTypedoc(config.build.typedocValidationBaseline, "BABYLON", true, true));
  727. });
  728. /**
  729. * Validate the code comments and style case convention through typedoc and
  730. * generate the new baseline.
  731. */
  732. gulp.task("typedoc-all", function (cb) {
  733. runSequence("typedoc-generate", "typedoc-validate", "typedoc-generateValidationBaseline", cb);
  734. });
  735. /**
  736. * Validate compile the code and check the comments and style case convention through typedoc
  737. */
  738. gulp.task("typedoc-check", function (cb) {
  739. runSequence("typescript-compile", "typedoc-generate", "typedoc-validate", cb);
  740. });
  741. /**
  742. * Launches the KARMA validation tests in chrome in order to debug them.
  743. * (Can only be launch locally.)
  744. */
  745. gulp.task("tests-validation-karma", function (done) {
  746. var kamaServerOptions = {
  747. configFile: __dirname + "/../../tests/validation/karma.conf.js",
  748. singleRun: false
  749. };
  750. var server = new karmaServer(kamaServerOptions, done);
  751. server.start();
  752. });
  753. /**
  754. * Launches the KARMA validation tests in ff or virtual screen ff on travis for a quick analysis during the build.
  755. * (Can only be launch on any branches.)
  756. */
  757. gulp.task("tests-validation-virtualscreen", function (done) {
  758. var kamaServerOptions = {
  759. configFile: __dirname + "/../../tests/validation/karma.conf.js",
  760. singleRun: true,
  761. browsers: ['Firefox']
  762. };
  763. var server = new karmaServer(kamaServerOptions, done);
  764. server.start();
  765. });
  766. /**
  767. * Launches the KARMA validation tests in browser stack for remote and cross devices validation tests.
  768. * (Can only be launch from secure branches.)
  769. */
  770. gulp.task("tests-validation-browserstack", function (done) {
  771. if (!process.env.BROWSER_STACK_USERNAME) {
  772. done();
  773. return;
  774. }
  775. var kamaServerOptions = {
  776. configFile: __dirname + "/../../tests/validation/karma.conf.browserstack.js",
  777. singleRun: true
  778. };
  779. var server = new karmaServer(kamaServerOptions, done);
  780. server.start();
  781. });
  782. /**
  783. * Transpiles typescript unit tests.
  784. */
  785. gulp.task("tests-unit-transpile", function (done) {
  786. var tsProject = typescript.createProject('../../tests/unit/tsconfig.json');
  787. var tsResult = gulp.src("../../tests/unit/**/*.ts", { base: "../../" })
  788. .pipe(tsProject());
  789. tsResult.once("error", function () {
  790. tsResult.once("finish", function () {
  791. console.log("Typescript compile failed");
  792. process.exit(1);
  793. });
  794. });
  795. return tsResult.js.pipe(gulp.dest("../../"));
  796. });
  797. /**
  798. * Launches the KARMA unit tests in phantomJS.
  799. * (Can only be launch on any branches.)
  800. */
  801. gulp.task("tests-unit-debug", ["tests-unit-transpile"], function (done) {
  802. var kamaServerOptions = {
  803. configFile: __dirname + "/../../tests/unit/karma.conf.js",
  804. singleRun: false,
  805. browsers: ['Chrome']
  806. };
  807. var server = new karmaServer(kamaServerOptions, done);
  808. server.start();
  809. });
  810. /**
  811. * Launches the KARMA unit tests in phantomJS.
  812. * (Can only be launch on any branches.)
  813. */
  814. gulp.task("tests-unit", ["tests-unit-transpile"], function (done) {
  815. var kamaServerOptions = {
  816. configFile: __dirname + "/../../tests/unit/karma.conf.js",
  817. singleRun: true
  818. };
  819. var server = new karmaServer(kamaServerOptions, done);
  820. server.start();
  821. });
  822. gulp.task("tests-whatsnew", function(done) {
  823. // Only checks on Travis
  824. if (!process.env.TRAVIS) {
  825. done();
  826. return;
  827. }
  828. // Only checks on Pull Requests
  829. if (process.env.TRAVIS_PULL_REQUEST == "false") {
  830. done();
  831. return;
  832. }
  833. // Do not check deploy
  834. if (process.env.TRAVIS_BRANCH == "preview") {
  835. done();
  836. return;
  837. }
  838. // Compare what's new with the current one in the preview release folder.
  839. const https = require("https");
  840. const url = "https://rawgit.com/BabylonJS/Babylon.js/master/dist/preview%20release/what's%20new.md";
  841. https.get(url, res => {
  842. res.setEncoding("utf8");
  843. let oldData = "";
  844. res.on("data", data => {
  845. oldData += data;
  846. });
  847. res.on("end", () => {
  848. fs.readFile("../../dist/preview release/what's new.md", "utf-8", function(err, newData) {
  849. if (err || oldData != newData) {
  850. done();
  851. return;
  852. }
  853. console.error("What's new file did not change.");
  854. process.exit(1);
  855. });
  856. });
  857. });
  858. });