chore: Simplify NPM package wrappers, improve chunk wrapper generator (#5777)

* chore: Clean up NPM package module wrappers

  - Slightly improve documentation for each file based on helpful
    explanations given by @samelhusseini.

  - Removed redundant code---e.g., loading `javascript_compressed.js`
    creates and sets Blockly.JavaScript as a side effect, so there is
    no need to set `Blockly.JavaScript = BlocklyJavaScript` in
    `dist/javascript.js` (generated from `scripts/package/javascript.js`).
  - Remove possibly harmful code---e.g., `Blockly.Msg` is initialised
    with a null-prototype object in `blockly_compressed.js` and that
    initial object should under no circumstances be replaced.
  - Remvoe downright misleading code---e.g., `dist/blocks.js` previously
    _appeared_ to replace Blockly.Blocks with an empty object, but in
    fact the `Blockly` name referred at that point to the exports object
    from `blocks_compressed.js`, which would randomly get a useless
    `{}`-valued `.Blocks` property tacked on to it; similarly, code in
    `dist/browser.js` (generated from `scripts/package/browser/index.js`)
    appeared to copy definitions from `BlocklyBlocks` to `Blockly.Blocks`,
    but the former would always be (the aforementioned) empty object,
    making this code ineffective.

* chore: Improve chunk definition / UMD generation

  Make several improvements to the chunks global and chunkWrapper
  function:

  - Document chunk definition format (and improve the names of
    of the documented properties).

  - Replace the chunk `.namespace` property with two others:
    - `.exports` names the variable/property to be returned by the
      factory function, and which will be set on the global object if
      the module is loaded in a browser.
    - `.importAs` names the parameter that this chunk's exports value
      is to be passed to the factory function of other chunks which
      depend on this one.  (This needs to be different because e.g.
      `Blockly.blocks` is not a valid parameter name.)

  - Change the definition for the blocks chunk to export Blockly.Blocks
    (i.e., the block definition dictionary) as blocks_compressed.js
    did previous to PR #5721 (chunked compilation), rather than the
    (empty and soon to vanish) Blockly.blocks namespace object.

    This is a win for backwards compatibility, though it does mean that
    if we want to expose the `loopTypes` export from `blocks/loops.js`
    we will need to find a different way to do so.
This commit is contained in:
Christopher Allen
2021-12-03 02:21:01 +00:00
committed by GitHub
parent 719e0fbf38
commit 8b3635ab75
14 changed files with 60 additions and 86 deletions

View File

@@ -66,7 +66,25 @@ const NAMESPACE_OBJECT = '$';
/**
* 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.
* on the first chunk. Properties are as follows:
*
* - .name: the name of the chunk. Used to label it when describing
* it to Closure Compiler and forms the prefix of filename the chunk
* will be written to.
* - .entry: the source .js file which is the entrypoint for the
* chunk.
* - .exports: a variable or property that will (prefixed with
* NAMESPACE_OBJECT) be returned from the factory function and which
* (sans prefix) will be set in the global scope to that returned
* value if the module is loaded in a browser.
* - .importAs: the name that this chunk's exports object will be
* given when passed to the factory function of other chunks that
* depend on it. (Needs to be distinct from .exports since (e.g.)
* "Blockly.blocks.all" is not a valid variable name.)
* - .factoryPreamble: code to override the default wrapper factory
* function preamble.
* - .factoryPostamble: code to override the default wrapper factory
* function postabmle.
*
* The function getChunkOptions will, after running
* closure-calculate-chunks, update each chunk to add the following
@@ -81,37 +99,49 @@ const chunks = [
{
name: 'blockly',
entry: 'core/requires.js',
namespace: 'Blockly',
wrapperSetup: `const ${NAMESPACE_OBJECT}={};`,
wrapperCleanup:
exports: 'Blockly',
importAs: 'Blockly',
factoryPreamble: `const ${NAMESPACE_OBJECT}={};`,
factoryPostamble:
`${NAMESPACE_OBJECT}.Blockly.internal_=${NAMESPACE_OBJECT};`,
}, {
name: 'blocks',
entry: 'blocks/all.js',
namespace: 'Blockly.blocks',
exports: 'Blockly.Blocks',
importAs: 'BlocklyBlocks',
}, {
name: 'javascript',
entry: 'generators/javascript/all.js',
namespace: 'Blockly.JavaScript',
exports: 'Blockly.JavaScript',
}, {
name: 'python',
entry: 'generators/python/all.js',
namespace: 'Blockly.Python',
exports: 'Blockly.Python',
}, {
name: 'php',
entry: 'generators/php/all.js',
namespace: 'Blockly.PHP',
exports: 'Blockly.PHP',
}, {
name: 'lua',
entry: 'generators/lua/all.js',
namespace: 'Blockly.Lua',
exports: 'Blockly.Lua',
}, {
name: 'dart',
entry: 'generators/dart/all.js',
namespace: 'Blockly.Dart',
exports: 'Blockly.Dart',
}
];
/**
* The default factory function premable.
*/
const FACTORY_PREAMBLE = `const ${NAMESPACE_OBJECT}=Blockly.internal_;`;
/**
* The default factory function postamble.
*/
const FACTORY_POSTAMBLE = '';
const licenseRegex = `\\/\\*\\*
\\* @license
\\* (Copyright \\d+ (Google LLC|Massachusetts Institute of Technology))
@@ -283,8 +313,8 @@ function chunkWrapper(chunk) {
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(', ');
chunk.dependencies.map(d => `root.${d.exports}`).join(', ');
const imports = chunk.dependencies.map(d => d.importAs).join(', ');
return `// Do not edit this file; automatically generated.
/* eslint-disable */
@@ -294,13 +324,13 @@ function chunkWrapper(chunk) {
} else if (typeof exports === 'object') { // Node.js
module.exports = factory(${cjsDeps});
} else { // Browser
root.${chunk.namespace} = factory(${browserDeps});
root.${chunk.exports} = factory(${browserDeps});
}
}(this, function(${imports}) {
${chunk.wrapperSetup || `const ${NAMESPACE_OBJECT}=Blockly.internal_;`}
${chunk.factoryPreamble || FACTORY_PREAMBLE}
%output%
${chunk.wrapperCleanup || ''}
return ${NAMESPACE_OBJECT}.${chunk.namespace};
${chunk.factoryPostamble || FACTORY_POSTAMBLE}
return ${NAMESPACE_OBJECT}.${chunk.exports};
}));
`;
};

View File

@@ -126,8 +126,8 @@ function packageBlockly() {
*/
function packageBlocks() {
return gulp.src('scripts/package/blocks.js')
.pipe(packageUMD('Blockly.Blocks', [{
name: 'Blockly',
.pipe(packageUMD('BlocklyBlocks', [{
name: 'BlocklyBlocks',
amd: './blocks_compressed',
cjs: './blocks_compressed',
}]))

View File

@@ -5,8 +5,5 @@
*/
/**
* @fileoverview Blockly module.
* @fileoverview Blockly module; just a wrapper for blockly_compressed.js.
*/
/* eslint-disable */
'use strict';

View File

@@ -5,10 +5,5 @@
*/
/**
* @fileoverview Blockly Blocks module.
* @fileoverview Blockly blocks module; just a wrapper for blocks_compressed.js.
*/
/* eslint-disable */
'use strict';
Blockly.Blocks = {};

View File

@@ -14,7 +14,6 @@
// Add a helper method to set the Blockly locale.
Blockly.setLocale = function (locale) {
Blockly.Msg = Blockly.Msg || {};
Object.keys(locale).forEach(function (k) {
Blockly.Msg[k] = locale[k];
});

View File

@@ -15,10 +15,3 @@
// Include the EN Locale by default.
Blockly.setLocale(En);
Blockly.Blocks = Blockly.Blocks || {};
Object.keys(BlocklyBlocks).forEach(function (k) {
Blockly.Blocks[k] = BlocklyBlocks[k];
});
Blockly.JavaScript = BlocklyJS;

View File

@@ -5,10 +5,5 @@
*/
/**
* @fileoverview Dart Generator module.
* @fileoverview Dart generator module; just a wrapper for dart_compressed.js.
*/
/* eslint-disable */
'use strict';
Blockly.Dart = BlocklyDart;

View File

@@ -5,8 +5,7 @@
*/
/**
* @fileoverview Blockly module.
* @fileoverview Blockly module; this is a wrapper which selects
* either browser.js or node.js, depending on which environment we
* are running in.
*/
/* eslint-disable */
'use strict';

View File

@@ -5,10 +5,6 @@
*/
/**
* @fileoverview JavaScript Generator module.
* @fileoverview JavaScript Generator module; just a wrapper for
* javascript_compressed.js.
*/
/* eslint-disable */
'use strict';
Blockly.JavaScript = BlocklyJavaScript;

View File

@@ -5,10 +5,5 @@
*/
/**
* @fileoverview Lua Generator module.
* @fileoverview Lua generator module; just a wrapper for lua_compressed.js.
*/
/* eslint-disable */
'use strict';
Blockly.Lua = BlocklyLua;

View File

@@ -14,7 +14,6 @@
// Add a helper method to set the Blockly locale.
Blockly.setLocale = function (locale) {
Blockly.Msg = Blockly.Msg || {};
Object.keys(locale).forEach(function (k) {
Blockly.Msg[k] = locale[k];
});

View File

@@ -14,18 +14,3 @@
// Include the EN Locale by default.
Blockly.setLocale(En);
Blockly.Blocks = Blockly.Blocks || {};
Object.keys(BlocklyBlocks).forEach(function (k) {
Blockly.Blocks[k] = BlocklyBlocks[k];
});
Blockly.JavaScript = BlocklyJS;
Blockly.Python = BlocklyPython;
Blockly.Lua = BlocklyLua;
Blockly.PHP = BlocklyPHP;
Blockly.Dart = BlocklyDart;

View File

@@ -5,10 +5,5 @@
*/
/**
* @fileoverview PHP Generator module.
* @fileoverview PHP generator module; just a wrapper for php_compressed.js.
*/
/* eslint-disable */
'use strict';
Blockly.PHP = BlocklyPHP;

View File

@@ -5,10 +5,6 @@
*/
/**
* @fileoverview Python Generator module.
* @fileoverview Python generator module; just a wrapper for
* python_compressed.js.
*/
/* eslint-disable */
'use strict';
Blockly.Python = BlocklyPython;