notebook | export notebook | , get cell extension | Search

This code snippet modifies JavaScript code by injecting caching logic into the AST (Abstract Syntax Tree). This optimization likely improves performance and reduces bundle size by caching imported modules.

Run example

npm run import -- "inject cells in to notebooks when built with webpack"

inject cells in to notebooks when built with webpack

var path = require('path');
var importer = require('../Core');
var getArrayAST = importer.import("get ast path array");
var {importsTemplate, cachedTemplate} = importer.import("include require like import");

// TODO: this should be a test in the Core notebook
// inject cellCache and cellIds loaded in to the interpreter so notebooks don't need to be uploaded,
//   and webpack can tree-shake on functions already packed
function injectImports(ast, allImports) {
    var cacheBody = getArrayAST(`//*[/*/ExpressionStatement/CallExpression[
/Identifier[@name == 'cacheAll']]]`, ast)[0];
    var firstCache = getArrayAST(`//ExpressionStatement[/CallExpression[
/Identifier[@name == 'cacheAll']]]`, cacheBody)[0];
    var cacheCode = getArrayAST('*', cachedTemplate(cellsToNotebook(allImports)))[0];
    cacheBody.body.splice(cacheBody.body.indexOf(firstCache), 1, ...cacheCode.body);
    var runContext = getArrayAST(`//AssignmentExpression[
//Identifier[@name == 'runInNewContext']]`, ast)[0];
    var addImports = Object.values(allImports).map(i => i.id).filter((i, j, arr) => arr.indexOf(i) === j)
    var requireCode = getArrayAST('*', importsTemplate(addImports))[0].body[0];
    requireCode.expression.right = runContext.right;
    runContext.right = requireCode;
}

module.exports = injectImports;

What the code could have been:

// Import required modules
const path = require('path');
const { importer } = require('../Core');
const { getArrayAST } = importer.import('get ast path array');
const { importsTemplate, cachedTemplate } = importer.import('include require like import');

/**
 * Injects imports into the given AST.
 * This function injects the cached code and require statements into the given AST.
 * It assumes that the cacheAll function and runInNewContext function are already present in the AST.
 * 
 * @param {object} ast - The Abstract Syntax Tree to be modified.
 * @param {object[]} allImports - An array of import objects containing 'id' and 'cells' properties.
 */
function injectImports(ast, allImports) {
    // Extract the cacheAll function body from the AST
    const cacheBody = getArrayAST('//*[/*/ExpressionStatement/CallExpression[@callee.name == "cacheAll"]]', ast)[0];
    
    // Extract the first cacheAll function call from the cache body
    const firstCacheCall = getArrayAST('//*[ExpressionStatement/CallExpression[@callee.name == "cacheAll"]]', cacheBody)[0];
    
    // Generate the cached code using the cachedTemplate function
    const cacheCode = getArrayAST('*', cachedTemplate(allImports.map(importObject => importObject.cells)))[0];
    
    // Replace the first cache call with the cached code in the cache body
    cacheBody.body = cacheBody.body.slice(0, cacheBody.body.indexOf(firstCacheCall),...cacheCode.body);
    
    // Extract the runInNewContext function from the AST
    const runContext = getArrayAST('//*[AssignmentExpression[@left.name == "runInNewContext"]]', ast)[0];
    
    // Extract the unique import IDs
    const uniqueImportIds = [...new Set(allImports.map(importObject => importObject.id))];
    
    // Generate the require code using the importsTemplate function
    const requireCode = getArrayAST('*', importsTemplate(uniqueImportIds))[0].body[0];
    
    // Replace the right-hand side of the runInNewContext function with the require code
    requireCode.expression.right = runContext.right;
    runContext.right = requireCode;
}

// Export the injectImports function
module.exports = injectImports;

This code snippet appears to be part of a JavaScript project that deals with code transformation and execution, likely within a notebook environment. Let's break it down:

1. Dependencies:

2. Imports:

3. injectImports Function:

4. AST Manipulation:

5. runContext:

Overall:

This code snippet demonstrates a technique for dynamically modifying code at the AST level. It likely aims to optimize the execution of code by caching imports, potentially improving performance and reducing the size of the final bundle.

Let me know if you have any more questions or would like me to elaborate on any specific part!