rollup.examples.config.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. import babel from '@rollup/plugin-babel';
  2. import path from 'path';
  3. import os from 'os';
  4. import glob from 'glob';
  5. import babelrc from './.babelrc.json';
  6. const EOL = os.EOL;
  7. function babelCleanup() {
  8. return {
  9. transform( code ) {
  10. // remove comments messed up by babel that break eslint
  11. // example:
  12. // setSize: function ()
  13. // /* width, height */
  14. // {
  15. // ↓
  16. // setSize: function () {
  17. code = code.replace( new RegExp( `\\(\\)${EOL}\\s*\\/\\*([a-zA-Z0-9_, ]+)\\*\\/${EOL}\\s*{`, 'g' ), '( ) {' );
  18. return {
  19. code: code,
  20. map: null
  21. };
  22. }
  23. };
  24. }
  25. function unmodularize() {
  26. return {
  27. renderChunk( code, { fileName } ) {
  28. // Namespace the modules that end with Utils
  29. const fileNameNoExtension = fileName.slice( 0, fileName.indexOf( '.' ) );
  30. const namespace = fileNameNoExtension.endsWith( 'Utils' ) ? fileNameNoExtension : undefined;
  31. // export { Example };
  32. // ↓
  33. // THREE.Example = Example;
  34. code = code.replace( /export { ([a-zA-Z0-9_, ]+) };/g, ( match, p1 ) => {
  35. const exps = p1.split( ', ' );
  36. let output = '';
  37. if ( namespace ) {
  38. output += `THREE.${namespace} = {};${ EOL }`;
  39. output += exps.map( exp => `THREE.${namespace}.${exp} = ${exp};` ).join( EOL );
  40. } else {
  41. output += exps.map( exp => `THREE.${exp} = ${exp};` ).join( EOL );
  42. }
  43. return output;
  44. } );
  45. // import { Example } from '...';
  46. // but excluding imports importing from the libs/ folder
  47. const imports = [];
  48. code = code.replace( /import { ([a-zA-Z0-9_, ]+) } from '((?!libs).)*';/g, ( match, p1 ) => {
  49. const imps = p1.split( ', ' );
  50. imps.reverse();
  51. imports.push( ...imps );
  52. return '';
  53. } );
  54. // import * as Example from '...';
  55. // but excluding imports importing from the libs/ folder
  56. code = code.replace( /import \* as ([a-zA-Z0-9_, ]+) from '((?!libs).)*';/g, ( match, p1 ) => {
  57. const imp = p1;
  58. imports.push( imp );
  59. return '';
  60. } );
  61. // new Example()
  62. // (Example)
  63. // [Example]
  64. // Example2
  65. // ↓
  66. // new THREE.Example()
  67. // (THREE.Example)
  68. // [THREE.Example]
  69. // Example2
  70. function prefixThree( word ) {
  71. code = code.replace( new RegExp( `([\\s([!])${word}([^a-zA-Z0-9_])`, 'g' ), ( match, p1, p2 ) => {
  72. return `${p1}THREE.${word}${p2}`;
  73. } );
  74. }
  75. imports.forEach( prefixThree );
  76. // Do it again for this particular example
  77. // new Example(Example)
  78. // ↓
  79. // new THREE.Example(THREE.Example)
  80. imports.forEach( prefixThree );
  81. // fix for BasisTextureLoader.js
  82. imports.forEach( imp => {
  83. code = code.replace( new RegExp( `${EOL}(\\s)*THREE\\.${imp}:`, 'g' ), ( match, p1 ) => {
  84. return `${EOL}${p1}${imp}:`;
  85. } );
  86. } );
  87. // import * as THREE from '...';
  88. code = code.replace( /import \* as THREE from '(.*)';/g, '' );
  89. // Remove library imports that are exposed as
  90. // global variables in the non-module world
  91. code = code.replace( /import (.*) from '(.*)\/libs\/(.*)';/g, '' );
  92. // remove newline at the start of file
  93. code = code.trimStart();
  94. code = `( function () {${EOL}${code}${EOL}} )();`;
  95. return {
  96. code: code,
  97. map: null
  98. };
  99. }
  100. };
  101. }
  102. const jsFolder = path.resolve( __dirname, '../../examples/js' );
  103. const jsmFolder = path.resolve( __dirname, '../../examples/jsm' );
  104. // list of all .js file nested in the examples/jsm folder
  105. const files = glob.sync( '**/*.js', { cwd: jsmFolder, ignore: [
  106. // don't convert libs
  107. 'libs/**/*',
  108. 'loaders/ifc/**/*',
  109. // no non-module library
  110. // https://unpkg.com/browse/@webxr-input-profiles/[email protected]/dist/
  111. 'webxr/**/*',
  112. // no non-module library
  113. // https://unpkg.com/browse/[email protected]/
  114. 'loaders/IFCLoader.js',
  115. // no non-module library
  116. // https://unpkg.com/browse/[email protected]/dist/
  117. 'loaders/KTX2Loader.js',
  118. 'renderers/webgl/**/*',
  119. 'renderers/webgpu/**/*',
  120. 'renderers/nodes/**/*',
  121. 'nodes/**/*',
  122. 'loaders/NodeMaterialLoader.js',
  123. 'offscreen/**/*',
  124. ] } );
  125. // Create a rollup config for each .js file
  126. export default files.map( file => {
  127. const inputPath = path.join( 'examples/jsm', file );
  128. const outputPath = path.resolve( jsFolder, file );
  129. return {
  130. input: inputPath,
  131. treeshake: false,
  132. external: () => true, // don't bundle anything
  133. plugins: [
  134. babel( {
  135. babelHelpers: 'bundled',
  136. babelrc: false,
  137. ...babelrc
  138. } ),
  139. babelCleanup(),
  140. unmodularize(),
  141. ],
  142. output: {
  143. format: 'esm',
  144. file: outputPath,
  145. }
  146. };
  147. } );