Skip to content

Commit

Permalink
Build improvements for preloads/minification and startup logic, see #764
Browse files Browse the repository at this point in the history
  • Loading branch information
jonathanolson committed Jul 6, 2019
1 parent 0e1cf7b commit ea74603
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 24 deletions.
57 changes: 34 additions & 23 deletions js/grunt/buildRunnable.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ module.exports = async function( repo, minifyOptions, instrument, allHTML, brand
}

const packageObject = grunt.file.readJSON( `../${repo}/package.json` );

const encoder = new nodeHTMLEncoder.Encoder( 'entity' );

// All html files share the same build timestamp
Expand All @@ -85,27 +84,19 @@ module.exports = async function( repo, minifyOptions, instrument, allHTML, brand
minify: false
};

const productionJS = minify( requireJS, minifyOptions );
const debugJS = minify( requireJS, debugMinifyOptions );

// After all media plugins have completed (which happens in requirejs:build), report which media files in the repository are unused.
reportUnusedMedia( packageObject.phet.requirejsNamespace );

// After all strings have been loaded, report which of the translatable strings are unused.
reportUnusedStrings( repo, packageObject.phet.requirejsNamespace );

const rawPreloads = getPreloads( repo, brand, true ).map( filename => grunt.file.read( filename ) );
const productionPreloads = rawPreloads.map( js => minify( js, minifyOptions ) );
const debugPreloads = rawPreloads.map( js => minify( js, debugMinifyOptions ) );

const phetLibs = getPhetLibs( repo, brand );
const allLocales = [ ChipperConstants.FALLBACK_LOCALE, ...getLocalesFromRepository( repo ) ];
const locales = localesOption === '*' ? allLocales : localesOption.split( ',' );
const dependencies = await getDependencies( repo );
const version = packageObject.version; // Include the one-off name in the version
const thirdPartyEntries = getAllThirdPartyEntries( repo, brand );
const stringMap = getStringMap( allLocales, phetLibs );
const mipmapsJavaScript = await buildMipmaps();

const simTitleStringKey = getTitleStringKey( repo );
const englishTitle = stringMap[ ChipperConstants.FALLBACK_LOCALE ][ simTitleStringKey ];
Expand Down Expand Up @@ -142,20 +133,40 @@ module.exports = async function( repo, minifyOptions, instrument, allHTML, brand
'University of Colorado. Contact phethelp@colorado.edu regarding licensing.';
}

const stringsJS = grunt.file.read( '../chipper/templates/chipper-strings.js' );
const productionStringsJS = minify( stringsJS, minifyOptions );
const debugStringsJS = minify( stringsJS, debugMinifyOptions );
// Scripts that are run before our main minifiable content
const startupScripts = [
// Splash image
`window.PHET_SPLASH_DATA_URI="${loadFileAsDataURI( `../brand/${brand}/images/splash.svg` )}";`,

// Mipmaps
await buildMipmaps()
];

const minifiableScripts = [
// Preloads
...getPreloads( repo, brand, true ).map( filename => grunt.file.read( filename ) ),

// Strings code (requires preloads first, and should be done before requireJS)
grunt.file.read( '../chipper/templates/chipper-strings.js' ),

// Our main require.js content, wrapped in a function called in the startup below
requireJS,

const startupJS = grunt.file.read( '../chipper/templates/chipper-startup.js' );
const productionStartupJS = minify( startupJS, minifyOptions );
const debugStartupJS = minify( startupJS, debugMinifyOptions );
// Main startup
grunt.file.read( '../chipper/templates/chipper-startup.js' )
];

const splashScript = `window.PHET_SPLASH_DATA_URI="${loadFileAsDataURI( `../brand/${brand}/images/splash.svg` )}";`;
const productionScripts = [
...startupScripts,
...minifiableScripts.map( js => minify( js, minifyOptions ) )
];
const debugScripts = [
...startupScripts,
...minifiableScripts.map( js => minify( js, debugMinifyOptions ) )
];

grunt.log.ok( `Minification for ${brand} complete` );
grunt.log.ok( `Require.js: ${productionJS.length} bytes` );
grunt.log.ok( `Preloads: ${_.sum( productionPreloads.map( preload => preload.length ) )} bytes` );
grunt.log.ok( `Mipmaps: ${mipmapsJavaScript.length} bytes` );
grunt.log.ok( `Production scripts: ${_.sum( productionScripts.map( js => js.length ) )} bytes` );

const commonInitializationOptions = {
brand: brand,
Expand Down Expand Up @@ -184,7 +195,7 @@ module.exports = async function( repo, minifyOptions, instrument, allHTML, brand
stringMap: stringMap,
htmlHeader: htmlHeader,
locale: locale,
scripts: [ initializationScript, splashScript, mipmapsJavaScript, ...productionPreloads, productionStringsJS, productionJS, productionStartupJS ]
scripts: [ initializationScript, ...productionScripts ]
} ) );
}
}
Expand All @@ -203,7 +214,7 @@ module.exports = async function( repo, minifyOptions, instrument, allHTML, brand
stringMap: stringMap,
htmlHeader: htmlHeader,
locale: ChipperConstants.FALLBACK_LOCALE,
scripts: [ initializationScript, splashScript, mipmapsJavaScript, ...productionPreloads, productionStringsJS, productionJS, productionStartupJS ]
scripts: [ initializationScript, ...productionScripts ]
} );

grunt.file.write( allHTMLFilename, allHTMLContents );
Expand All @@ -222,7 +233,7 @@ module.exports = async function( repo, minifyOptions, instrument, allHTML, brand
stringMap: stringMap,
htmlHeader: htmlHeader,
locale: ChipperConstants.FALLBACK_LOCALE,
scripts: [ debugInitializationScript, splashScript, mipmapsJavaScript, ...debugPreloads, debugStringsJS, debugJS, debugStartupJS ]
scripts: [ debugInitializationScript, ...debugScripts ]
} ) );

// XHTML build (ePub compatibility, etc.)
Expand All @@ -238,7 +249,7 @@ module.exports = async function( repo, minifyOptions, instrument, allHTML, brand
brand: brand,
stringMap: stringMap,
htmlHeader: htmlHeader,
scripts: [ xhtmlInitializationScript, splashScript, mipmapsJavaScript, ...productionPreloads, productionStringsJS, productionJS, productionStartupJS ]
scripts: [ xhtmlInitializationScript, ...productionScripts ]
} );

// dependencies.json
Expand Down
6 changes: 5 additions & 1 deletion js/grunt/requireBuild.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ const requirejs = require( 'requirejs' );
module.exports = function( repo, mainConfigFile, options ) {

const {
// {string|null} - If provided, the contents of the require.js build will be wrapped inside a function that is
// assigned to the given path (e.g. phet.chipper.runRequireJS).
wrapPath = null,

insertRequire = false,
instrument = false,
brand = 'phet'
Expand All @@ -43,6 +46,7 @@ module.exports = function( repo, mainConfigFile, options ) {

const instrumenter = instrument ? new istanbul.Instrumenter() : null;

// All options are documented at https://github.com/requirejs/r.js/blob/master/build/example.build.js
const config = {

// Includes a require.js stub called almond, so that we don't have to include the full require.js runtime
Expand All @@ -54,7 +58,7 @@ module.exports = function( repo, mainConfigFile, options ) {
optimize: 'none',

wrap: wrapPath ? {
start: 'phet.chipper.runRequireJS = function() {',
start: `${wrapPath} = function() {`,
end: '};'
} : false,

Expand Down

0 comments on commit ea74603

Please sign in to comment.