From 2af2af34acd836a696930f586e3ed9e1f0cadaf4 Mon Sep 17 00:00:00 2001 From: Garrett Johnson Date: Wed, 26 Jun 2019 17:15:53 -0700 Subject: [PATCH 1/9] Update the rollup config to support multi-file merge output --- package.json | 3 +- rollup-examples.config.js | 154 +++++++++++++++++++++++++++++--------- 2 files changed, 119 insertions(+), 38 deletions(-) diff --git a/package.json b/package.json index 78ec99e2fd5fef..089d6084ecbee5 100644 --- a/package.json +++ b/package.json @@ -78,7 +78,8 @@ "http-server": "^0.11.1", "qunit": "^2.9.2", "rollup": "^1.16.2", - "typescript": "^3.5.2" + "typescript": "^3.5.2", + "glob": "^7.1.4" }, "jspm": { "files": [ diff --git a/rollup-examples.config.js b/rollup-examples.config.js index 9bbadeb4fec4dd..ed9936dd563f7f 100644 --- a/rollup-examples.config.js +++ b/rollup-examples.config.js @@ -1,35 +1,95 @@ var path = require( 'path' ); var fs = require( 'fs' ); +var glob = require('glob'); -// Creates a rollup config object for the given file to -// be converted to umd -function createOutput( file ) { +var sourceDir = path.resolve( 'examples/jsm/' ); +var outputDir = path.resolve( 'examples/js/' ); - var inputPath = path.resolve( file ); - var outputPath = inputPath.replace( /[\\\/]examples[\\\/]jsm[\\\/]/, '/examples/js/' ); +var mergedFiles = [{ - // Every import is marked as external so the output is 1-to-1. We - // assume that that global object should be the THREE object so we - // replicate the existing behavior. - return { + paths: [ + 'postprocessing/Pass.js', + ], + input: 'postprocessing/EffectComposer.js', + output: 'postprocessing/EffectComposer.js' - input: inputPath, - treeshake: false, - external: p => p !== inputPath, +}, { + + paths: [ + 'nodes/**/*.js' + ], + input: 'nodes/Nodes.js', + output: 'nodes/Nodes.js' + +}]; + +var fileToOutput = {}; + +const threeGlobalPlugin = { + + bundle: function ( options, bundle ) { + + for ( var key in bundle ) { + + bundle[ key ].code = bundle[ key ].code.replace( /three_module_js/g, 'THREE' ); + + } + + } + +}; + +function resolveDependencyPath( p ) { - plugins: [ { + if ( /three\.module\.js$/.test( p ) ) { - generateBundle: function ( options, bundle ) { + return 'three'; - for ( var key in bundle ) { + } else if ( p in fileToOutput ) { - bundle[ key ].code = bundle[ key ].code.replace( /three_module_js/g, 'THREE' ); + return fileToOutput[ p ]; - } + } else { - } + return p; - } ], + } + +} + +function createOutputFileMap() { + + mergedFiles.forEach( f => { + + const paths = f.paths; + const output = f.output; + paths.forEach( p => { + + glob.sync( path.join( sourceDir, p ) ).forEach( fullPath => { + + fileToOutput[ fullPath ] = path.join( outputDir, output ); + + } ); + + } ); + + } ); + +} + +function createMergedFileConfig( f ) { + + const inputPath = path.join( sourceDir, f.input ); + const outputPath = path.join( outputDir, f.output ); + const internalFiles = [ f.input, ...f.paths ].map( p => path.join( sourceDir, p ) ); + + return { + + input: inputPath, + treeshake: false, + external: p => ! internalFiles.includes( p ), + + plugins: [ threeGlobalPlugin ], output: { @@ -38,7 +98,7 @@ function createOutput( file ) { file: outputPath, globals: () => 'THREE', - paths: p => /three\.module\.js$/.test( p ) ? 'three' : p, + paths: p => resolveDependencyPath( p ), extend: true, banner: @@ -53,33 +113,53 @@ function createOutput( file ) { } -// Walk the file structure starting at the given directory and fire -// the callback for every js file. -function walk( dir, cb ) { +function createSingleFileConfig( inputPath ) { + + var relativePath = path.relative( sourceDir, inputPath ); + var outputPath = path.join( outputDir, relativePath ); - var files = fs.readdirSync( dir ); - files.forEach( f => { + return { - var p = path.join( dir, f ); - var stats = fs.statSync( p ); + input: inputPath, + treeshake: false, + external: p => p !== inputPath, - if ( stats.isDirectory() ) { + plugins: [ threeGlobalPlugin ], - walk( p, cb ); + output: { - } else if ( f.endsWith( '.js' ) ) { + format: 'umd', + name: 'THREE', + file: outputPath, - cb( p ); + globals: () => 'THREE', + paths: p => resolveDependencyPath( p ), + extend: true, + + banner: + '/**\n' + + ` * Generated from '${ path.relative( '.', inputPath ).replace( /\\/g, '/' ) }'\n` + + ' */\n', + esModule: false } - } ); + }; } -// Gather up all the files -var files = []; -walk( 'examples/jsm/', p => files.push( p ) ); +createOutputFileMap(); + +var configs = mergedFiles.map( f => createMergedFileConfig( f ) ); +glob.sync( path.join( sourceDir, '**/*.js' ) ) + .forEach( p => { + + if ( ! ( p in fileToOutput ) ) { + + configs.push( createSingleFileConfig( p ) ); + + } + + } ); -// Create a rollup config for each module.js file -export default files.map( p => createOutput( p ) ); +export default configs; From cd3f6cc93755916819df985d0341666a42f6519d Mon Sep 17 00:00:00 2001 From: Garrett Johnson Date: Wed, 26 Jun 2019 17:29:38 -0700 Subject: [PATCH 2/9] Don't indent for minimal changes, fix global name replace --- rollup-examples.config.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/rollup-examples.config.js b/rollup-examples.config.js index ed9936dd563f7f..1e43c99ecbb924 100644 --- a/rollup-examples.config.js +++ b/rollup-examples.config.js @@ -1,5 +1,4 @@ var path = require( 'path' ); -var fs = require( 'fs' ); var glob = require('glob'); var sourceDir = path.resolve( 'examples/jsm/' ); @@ -27,7 +26,7 @@ var fileToOutput = {}; const threeGlobalPlugin = { - bundle: function ( options, bundle ) { + generateBundle: function ( options, bundle ) { for ( var key in bundle ) { @@ -96,6 +95,7 @@ function createMergedFileConfig( f ) { format: 'umd', name: 'THREE', file: outputPath, + indent: false, globals: () => 'THREE', paths: p => resolveDependencyPath( p ), @@ -131,6 +131,7 @@ function createSingleFileConfig( inputPath ) { format: 'umd', name: 'THREE', file: outputPath, + indent: false, globals: () => 'THREE', paths: p => resolveDependencyPath( p ), From 8cd373d7815d4548f352b8b38295e5328d9aa4a6 Mon Sep 17 00:00:00 2001 From: Garrett Johnson Date: Wed, 26 Jun 2019 17:57:08 -0700 Subject: [PATCH 3/9] Fix the libraries global object. --- rollup-examples.config.js | 97 +++++++++++++++++++++++++-------------- 1 file changed, 62 insertions(+), 35 deletions(-) diff --git a/rollup-examples.config.js b/rollup-examples.config.js index 1e43c99ecbb924..c2f51c188f11f5 100644 --- a/rollup-examples.config.js +++ b/rollup-examples.config.js @@ -1,30 +1,56 @@ var path = require( 'path' ); var glob = require('glob'); +var libsDir = path.resolve( 'examples/jsm/libs/' ); var sourceDir = path.resolve( 'examples/jsm/' ); var outputDir = path.resolve( 'examples/js/' ); +// How to merge output files. +// "input": Which jsm file to process. +// "output": The name and location to output the resultant UMD file. +// "paths": Which files should be merged into the file. Any other files +// not in the list will be considered external. var mergedFiles = [{ - paths: [ - 'postprocessing/Pass.js', - ], input: 'postprocessing/EffectComposer.js', - output: 'postprocessing/EffectComposer.js' - -}, { - + output: 'postprocessing/EffectComposer.js', paths: [ - 'nodes/**/*.js' - ], - input: 'nodes/Nodes.js', - output: 'nodes/Nodes.js' + 'postprocessing/Pass.js', + ] }]; +// A map of processed files to the output file that they have been rolled up +// in so references can be corrected. var fileToOutput = {}; -const threeGlobalPlugin = { +createOutputFileMap(); + +// Generate the configs for every merged output and individual file not +// covered in a merged file. +var configs = []; + +mergedFiles.forEach( f => { + + configs.push( createMergedFileConfig( f ) ); + +} ); + +glob.sync( path.join( sourceDir, '**/*.js' ) ) + .forEach( p => { + + if ( ! ( p in fileToOutput ) ) { + + configs.push( createSingleFileConfig( p ) ); + + } + + } ); + +export default configs; + +// Plugin to convert the dfeault "three_module_js" variable name to THREE. +var threeGlobalPlugin = { generateBundle: function ( options, bundle ) { @@ -38,19 +64,36 @@ const threeGlobalPlugin = { }; -function resolveDependencyPath( p ) { +// Resolve which global variable to reference for a given depdency. If a dependency is +// a library we assume it comes from "window" otherwise it is expected to be on "THREE". +function resolveGlobalObject( p ) { + + if ( p.indexOf( libsDir ) === 0 ) { + + return 'window'; + + } else { + + return 'THREE'; + + } + +} + +function resolveDependencyPath( p, inputPath ) { if ( /three\.module\.js$/.test( p ) ) { + // If importing three.js return 'three'; } else if ( p in fileToOutput ) { - return fileToOutput[ p ]; + return path.relative( inputPath, fileToOutput[ p ] ) ; } else { - return p; + return path.relative( inputPath, p ); } @@ -97,8 +140,8 @@ function createMergedFileConfig( f ) { file: outputPath, indent: false, - globals: () => 'THREE', - paths: p => resolveDependencyPath( p ), + globals: p => resolveGlobalObject( p ), + paths: p => resolveDependencyPath( p, inputPath ), extend: true, banner: @@ -133,8 +176,8 @@ function createSingleFileConfig( inputPath ) { file: outputPath, indent: false, - globals: () => 'THREE', - paths: p => resolveDependencyPath( p ), + globals: p => resolveGlobalObject( p ), + paths: p => resolveDependencyPath( p, inputPath ), extend: true, banner: @@ -148,19 +191,3 @@ function createSingleFileConfig( inputPath ) { }; } - -createOutputFileMap(); - -var configs = mergedFiles.map( f => createMergedFileConfig( f ) ); -glob.sync( path.join( sourceDir, '**/*.js' ) ) - .forEach( p => { - - if ( ! ( p in fileToOutput ) ) { - - configs.push( createSingleFileConfig( p ) ); - - } - - } ); - -export default configs; From 47a71e4f5825957beee1a39bd854d52c0497a23e Mon Sep 17 00:00:00 2001 From: Garrett Johnson Date: Wed, 26 Jun 2019 17:59:33 -0700 Subject: [PATCH 4/9] rename variables --- rollup-examples.config.js | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/rollup-examples.config.js b/rollup-examples.config.js index c2f51c188f11f5..aaa5fe59cd5e37 100644 --- a/rollup-examples.config.js +++ b/rollup-examples.config.js @@ -30,9 +30,9 @@ createOutputFileMap(); // covered in a merged file. var configs = []; -mergedFiles.forEach( f => { +mergedFiles.forEach( mergedFileInfo => { - configs.push( createMergedFileConfig( f ) ); + configs.push( createMergedFileConfig( mergedFileInfo ) ); } ); @@ -66,9 +66,9 @@ var threeGlobalPlugin = { // Resolve which global variable to reference for a given depdency. If a dependency is // a library we assume it comes from "window" otherwise it is expected to be on "THREE". -function resolveGlobalObject( p ) { +function resolveGlobalObject( depPath ) { - if ( p.indexOf( libsDir ) === 0 ) { + if ( depPath.indexOf( libsDir ) === 0 ) { return 'window'; @@ -80,34 +80,36 @@ function resolveGlobalObject( p ) { } -function resolveDependencyPath( p, inputPath ) { +function resolveDependencyPath( depPath, inputPath ) { - if ( /three\.module\.js$/.test( p ) ) { + if ( /three\.module\.js$/.test( depPath ) ) { // If importing three.js return 'three'; - } else if ( p in fileToOutput ) { + } else if ( depPath in fileToOutput ) { - return path.relative( inputPath, fileToOutput[ p ] ) ; + // If the file is included in a merged file + return path.relative( inputPath, fileToOutput[ depPath ] ) ; } else { - return path.relative( inputPath, p ); + return path.relative( inputPath, depPath ); } } +// Generate the map the stores the name of each file to the file it is merged into. function createOutputFileMap() { - mergedFiles.forEach( f => { + mergedFiles.forEach( mergedFileInfo => { - const paths = f.paths; - const output = f.output; - paths.forEach( p => { + const paths = mergedFileInfo.paths; + const output = mergedFileInfo.output; + paths.forEach( depPath => { - glob.sync( path.join( sourceDir, p ) ).forEach( fullPath => { + glob.sync( path.join( sourceDir, depPath ) ).forEach( fullPath => { fileToOutput[ fullPath ] = path.join( outputDir, output ); @@ -119,11 +121,11 @@ function createOutputFileMap() { } -function createMergedFileConfig( f ) { +function createMergedFileConfig( mergedFileInfo ) { - const inputPath = path.join( sourceDir, f.input ); - const outputPath = path.join( outputDir, f.output ); - const internalFiles = [ f.input, ...f.paths ].map( p => path.join( sourceDir, p ) ); + const inputPath = path.join( sourceDir, mergedFileInfo.input ); + const outputPath = path.join( outputDir, mergedFileInfo.output ); + const internalFiles = [ mergedFileInfo.input, ...mergedFileInfo.paths ].map( p => path.join( sourceDir, p ) ); return { From 25b660c3d3a7437d9cb80496f95c774ae7c8734d Mon Sep 17 00:00:00 2001 From: Garrett Johnson Date: Wed, 26 Jun 2019 18:11:48 -0700 Subject: [PATCH 5/9] Fix plugin transform --- rollup-examples.config.js | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/rollup-examples.config.js b/rollup-examples.config.js index aaa5fe59cd5e37..6044d43faf5874 100644 --- a/rollup-examples.config.js +++ b/rollup-examples.config.js @@ -24,6 +24,21 @@ var mergedFiles = [{ // in so references can be corrected. var fileToOutput = {}; +// Plugin to convert the dfeault "three_module_js" variable name to THREE. +var threeGlobalPlugin = { + + generateBundle: function ( options, bundle ) { + + for ( var key in bundle ) { + + bundle[ key ].code = bundle[ key ].code.replace( /three_module_js/g, 'THREE' ); + + } + + } + +}; + createOutputFileMap(); // Generate the configs for every merged output and individual file not @@ -49,21 +64,6 @@ glob.sync( path.join( sourceDir, '**/*.js' ) ) export default configs; -// Plugin to convert the dfeault "three_module_js" variable name to THREE. -var threeGlobalPlugin = { - - generateBundle: function ( options, bundle ) { - - for ( var key in bundle ) { - - bundle[ key ].code = bundle[ key ].code.replace( /three_module_js/g, 'THREE' ); - - } - - } - -}; - // Resolve which global variable to reference for a given depdency. If a dependency is // a library we assume it comes from "window" otherwise it is expected to be on "THREE". function resolveGlobalObject( depPath ) { From 7a6a03e7b51989363b8ee7afd47f72aa58bd58ab Mon Sep 17 00:00:00 2001 From: Garrett Johnson Date: Wed, 26 Jun 2019 18:15:55 -0700 Subject: [PATCH 6/9] skip transforming the libraries --- rollup-examples.config.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/rollup-examples.config.js b/rollup-examples.config.js index 6044d43faf5874..b30b7022fe31d7 100644 --- a/rollup-examples.config.js +++ b/rollup-examples.config.js @@ -54,7 +54,7 @@ mergedFiles.forEach( mergedFileInfo => { glob.sync( path.join( sourceDir, '**/*.js' ) ) .forEach( p => { - if ( ! ( p in fileToOutput ) ) { + if ( ! isLibrary( p ) && ! ( p in fileToOutput ) ) { configs.push( createSingleFileConfig( p ) ); @@ -64,11 +64,17 @@ glob.sync( path.join( sourceDir, '**/*.js' ) ) export default configs; +function isLibrary( depPath ) { + + return depPath.indexOf( libsDir ) === 0; + +} + // Resolve which global variable to reference for a given depdency. If a dependency is // a library we assume it comes from "window" otherwise it is expected to be on "THREE". function resolveGlobalObject( depPath ) { - if ( depPath.indexOf( libsDir ) === 0 ) { + if ( isLibrary( depPath ) ) { return 'window'; From b835907a2933a72fcfd29c67327d7aa8827d858e Mon Sep 17 00:00:00 2001 From: Garrett Johnson Date: Wed, 26 Jun 2019 18:21:10 -0700 Subject: [PATCH 7/9] normalize the path before checking if its a library --- rollup-examples.config.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rollup-examples.config.js b/rollup-examples.config.js index b30b7022fe31d7..83bca4727edd8d 100644 --- a/rollup-examples.config.js +++ b/rollup-examples.config.js @@ -54,6 +54,8 @@ mergedFiles.forEach( mergedFileInfo => { glob.sync( path.join( sourceDir, '**/*.js' ) ) .forEach( p => { + p = path.normalize( p ); + if ( ! isLibrary( p ) && ! ( p in fileToOutput ) ) { configs.push( createSingleFileConfig( p ) ); From c1dfc7b2a68511857220de6e9308921e13eb1146 Mon Sep 17 00:00:00 2001 From: Garrett Johnson Date: Wed, 26 Jun 2019 18:25:56 -0700 Subject: [PATCH 8/9] normalize the glob path --- rollup-examples.config.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rollup-examples.config.js b/rollup-examples.config.js index 83bca4727edd8d..c220150559f206 100644 --- a/rollup-examples.config.js +++ b/rollup-examples.config.js @@ -119,6 +119,8 @@ function createOutputFileMap() { glob.sync( path.join( sourceDir, depPath ) ).forEach( fullPath => { + fullPath = path.normalize( fullPath ); + fileToOutput[ fullPath ] = path.join( outputDir, output ); } ); From 0f815a60d780a5bd0d6e8831fef81f6411260f87 Mon Sep 17 00:00:00 2001 From: Garrett Johnson Date: Fri, 6 Sep 2019 11:04:54 -0700 Subject: [PATCH 9/9] comma mistype --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2b4089342140c3..48e244cbbfa80d 100644 --- a/package.json +++ b/package.json @@ -81,7 +81,7 @@ "google-closure-compiler": "20190729.0.0", "http-server": "^0.11.1", "qunit": "^2.9.2", - "glob": "^7.1.4" + "glob": "^7.1.4", "rollup": "^1.19.4", "typescript": "^3.5.3", "rollup-plugin-buble": "^0.19.8"