mirror of
https://github.com/google/blockly.git
synced 2026-01-10 02:17:09 +01:00
chore(build): Generate chunk wrappers
A first pass; this does not have support for a namespace object yet.
This commit is contained in:
@@ -32,20 +32,34 @@ var {getPackageJson} = require('./helper_tasks');
|
||||
// Build //
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Suffix to add to compiled output files.
|
||||
*/
|
||||
const COMPILED_SUFFIX = '_compressed';
|
||||
|
||||
/**
|
||||
* A list of chunks. Order matters: later chunks can depend on
|
||||
* earlier ones, but not vice-versa. All chunks are assumed to depend
|
||||
* on the first chunk.
|
||||
*
|
||||
* Output files will be named <chunk_name>_compressed.js.
|
||||
* The function getChunkOptions will, after running
|
||||
* closure-calculate-chunks, update each chunk to add the following
|
||||
* properties:
|
||||
*
|
||||
* - .dependencies: a list of the chunks the chunk depends upon.
|
||||
* - .wrapper: the chunk wrapper.
|
||||
*
|
||||
* Output files will be named <chunk.name><COMPILED_SUFFIX>.js.
|
||||
*/
|
||||
const CHUNKS = [
|
||||
const chunks = [
|
||||
{
|
||||
name: 'blockly',
|
||||
entry: 'core/requires.js'
|
||||
entry: 'core/requires.js',
|
||||
namespace: 'Blockly',
|
||||
}, {
|
||||
name: 'blocks',
|
||||
entry: 'blocks/all.js'
|
||||
entry: 'blocks/all.js',
|
||||
namespace: 'Blockly.blocks',
|
||||
}, {
|
||||
name: 'javascript',
|
||||
entry: 'generators/javascript/all.js',
|
||||
@@ -460,13 +474,44 @@ function buildLangfiles(done) {
|
||||
done();
|
||||
};
|
||||
|
||||
/**
|
||||
* A helper method to return an closure compiler chunk wrapper that
|
||||
* wraps the compiler output for the given chunk in a Universal Module
|
||||
* Definition.
|
||||
*/
|
||||
function chunkWrapper(chunk) {
|
||||
const fileNames = chunk.dependencies.map(
|
||||
d => JSON.stringify(`./${d.name}${COMPILED_SUFFIX}.js`));
|
||||
const amdDeps = fileNames.join(', ');
|
||||
const cjsDeps = fileNames.map(f => `require(${f})`).join(', ');
|
||||
const browserDeps =
|
||||
chunk.dependencies.map(d => `root.${d.namespace}`).join(', ');
|
||||
const imports = chunk.dependencies.map(d => d.namespace).join(', ');
|
||||
return `// Do not edit this file; automatically generated.
|
||||
|
||||
/* eslint-disable */
|
||||
;(function(root, factory) {
|
||||
if (typeof define === 'function' && define.amd) { // AMD
|
||||
define([${amdDeps}], factory);
|
||||
} else if (typeof exports === 'object') { // Node.js
|
||||
module.exports = factory(${cjsDeps});
|
||||
} else { // Browser
|
||||
root.${chunk.namespace} = factory(${browserDeps});
|
||||
}
|
||||
}(this, function(${imports}) {
|
||||
%output%
|
||||
return ${chunk.namespace};
|
||||
}));
|
||||
`;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get chunking options to pass to Closure Compiler by using
|
||||
* closure-calculate-chunks (hereafter "ccc") to generate them based
|
||||
* on the deps.js file (which must be up to date!).
|
||||
*
|
||||
* The generated options are modified to use the original chunk names
|
||||
* given in CHUNKS instead of the entry-point based names used by ccc.
|
||||
* given in chunks instead of the entry-point based names used by ccc.
|
||||
*
|
||||
* @return {{chunk: !Array<string>, js: !Array<string>}} The chunking
|
||||
* information, in the same form as emitted by
|
||||
@@ -478,7 +523,7 @@ function getChunkOptions() {
|
||||
const cccArgs = [
|
||||
'--closure-library-base-js-path ./closure/goog/base.js',
|
||||
'--deps-file ./tests/deps.js',
|
||||
...(CHUNKS.map(chunk => `--entrypoint '${chunk.entry}'`)),
|
||||
...(chunks.map(chunk => `--entrypoint '${chunk.entry}'`)),
|
||||
];
|
||||
const cccCommand = `closure-calculate-chunks ${cccArgs.join(' ')}`;
|
||||
const rawOptions= JSON.parse(String(execSync(cccCommand)));
|
||||
@@ -503,21 +548,32 @@ function getChunkOptions() {
|
||||
// This is designed to be passed directly as-is as the options
|
||||
// object to the Closure Compiler node API, but we want to replace
|
||||
// the unhelpful entry-point based chunk names (let's call these
|
||||
// "nicknames") with the ones from CHUNKS. Luckily they will be in
|
||||
// "nicknames") with the ones from chunks. Luckily they will be in
|
||||
// the same order that the entry points were supplied in - i.e.,
|
||||
// they correspond 1:1 with the entries in CHUNKS.
|
||||
// they correspond 1:1 with the entries in chunks.
|
||||
const chunkByNickname = Object.create(null);
|
||||
const chunkList = rawOptions.chunk.map((element, index) => {
|
||||
const [nickname, numJsFiles, depNicks] = element.split(':');
|
||||
const chunk = CHUNKS[index];
|
||||
const [nickname, numJsFiles, dependencyNicks] = element.split(':');
|
||||
const chunk = chunks[index];
|
||||
chunkByNickname[nickname] = chunk;
|
||||
const depNames = depNicks ?
|
||||
depNicks.split(',').map(nick => chunkByNickname[nick].name) .join(',')
|
||||
: '';
|
||||
return `${chunk.name}:${numJsFiles}:${depNames}`;
|
||||
if (!dependencyNicks) { // Chunk has no dependencies.
|
||||
chunk.dependencies = [];
|
||||
return `${chunk.name}:${numJsFiles}`;
|
||||
}
|
||||
chunk.dependencies =
|
||||
dependencyNicks.split(',').map(nick => chunkByNickname[nick]);
|
||||
const dependencyNames =
|
||||
chunk.dependencies.map(dependency => dependency.name).join(',');
|
||||
return `${chunk.name}:${numJsFiles}:${dependencyNames}`;
|
||||
});
|
||||
|
||||
return {chunk: chunkList, js: rawOptions.js};
|
||||
// Generate a chunk wrapper for each chunk.
|
||||
for (const chunk of chunks) {
|
||||
chunk.wrapper = chunkWrapper(chunk);
|
||||
}
|
||||
|
||||
const chunkWrappers = chunks.map(chunk => `${chunk.name}:${chunk.wrapper}`);
|
||||
return {chunk: chunkList, js: rawOptions.js, chunk_wrapper: chunkWrappers};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -581,11 +637,11 @@ function buildCompiled(done) {
|
||||
hide_warnings_for: 'node_modules',
|
||||
// dependency_mode: 'PRUNE',
|
||||
externs: ['./externs/svg-externs.js', /* './externs/goog-externs.js' */],
|
||||
output_wrapper: outputWrapperUMD('Blockly', []),
|
||||
define: 'Blockly.VERSION="' + packageJson.version + '"',
|
||||
chunk: chunkOptions.chunk,
|
||||
chunk_wrapper: chunkOptions.chunk_wrapper,
|
||||
// Don't supply the list of source files in chunkOptions.js as an
|
||||
// option to Closure Compiler; instead feed them to gulp.src.
|
||||
// option to Closure Compiler; instead feed them as input via gulp.src.
|
||||
};
|
||||
if (argv.debug || argv.strict) {
|
||||
options.jscomp_error = [...JSCOMP_ERROR];
|
||||
@@ -602,7 +658,7 @@ function buildCompiled(done) {
|
||||
.pipe(gulp.sourcemaps.init())
|
||||
.pipe(gulp.rename(flattenCorePaths))
|
||||
.pipe(closureCompiler(options, pluginOptions))
|
||||
.pipe(gulp.rename({suffix: '_compressed'}))
|
||||
.pipe(gulp.rename({suffix: COMPILED_SUFFIX}))
|
||||
.pipe(gulp.sourcemaps.mapSources(unflattenCorePaths))
|
||||
.pipe(
|
||||
gulp.sourcemaps.write('.', {includeContent: false, sourceRoot: './'}))
|
||||
|
||||
Reference in New Issue
Block a user