From d819f2e01c659b42833a0a3aafe0f10d15a6edee Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Sun, 26 Feb 2017 10:54:19 +0100 Subject: [PATCH] Remove lib directory --- .gitignore | 1 + lib/blueprint.js | 93 ---------- lib/file-require-transform.js | 295 -------------------------------- lib/generate-snapshot-script.js | 78 --------- 4 files changed, 1 insertion(+), 466 deletions(-) delete mode 100644 lib/blueprint.js delete mode 100644 lib/file-require-transform.js delete mode 100644 lib/generate-snapshot-script.js diff --git a/.gitignore b/.gitignore index 81ce827..87eacac 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /node_modules/ .DS_Store npm-debug.log +lib diff --git a/lib/blueprint.js b/lib/blueprint.js deleted file mode 100644 index 965d0af..0000000 --- a/lib/blueprint.js +++ /dev/null @@ -1,93 +0,0 @@ -var snapshotResult = (function () { - let process = {} - Object.defineProperties(process, { - 'platform': {value: 'darwin', enumerable: false}, - 'argv': {value: [], enumerable: false}, - 'env': {value: {}, enumerable: false} - }) - function get_process () { - return process - } - - let document = {} - function get_document () { - return document - } - - let global = {} - Object.defineProperties(global, { - 'document': {value: document, enumerable: false}, - 'process': {value: process, enumerable: false}, - 'WeakMap': {value: WeakMap, enumerable: false} - }) - function get_global () { - return global - } - - let window = {} - Object.defineProperties(window, { - 'document': {value: document, enumerable: false}, - 'location': {value: {href: ''}, enumerable: false} - }) - function get_window () { - return window - } - - let require = () => { throw new Error('To use Node require you need to call setGlobals on snapshotResult first!') } - - function customRequire (modulePath) { - if (!customRequire.cache[modulePath]) { - const module = {exports: {}} - const dirname = modulePath.split('/').slice(0, -1).join('/') - - function define (callback) { - callback(customRequire, module.exports, module) - } - - if (customRequire.definitions.hasOwnProperty(modulePath)) { - // Prevent cyclic requires by assigning an empty value to the cache before - // evaluating the module definition. - customRequire.cache[modulePath] = {} - customRequire.definitions[modulePath].apply(module.exports, [module.exports, module, modulePath, dirname, customRequire, define]) - } else { - module.exports = require(modulePath) - } - customRequire.cache[modulePath] = module.exports - } - return customRequire.cache[modulePath] - } - customRequire.extensions = {} - customRequire.cache = {} - customRequire.definitions = {} - customRequire.resolve = function (mod) { - return require.resolve(mod) - } - - customRequire(mainModuleRequirePath) - return { - customRequire, - setGlobals: function (newGlobal, newProcess, newWindow, newDocument, nodeRequire) { - for (let key of Object.keys(global)) { - newGlobal[key] = global[key] - } - global = newGlobal - - for (let key of Object.keys(process)) { - newProcess[key] = process[key] - } - process = newProcess - - for (let key of Object.keys(window)) { - newWindow[key] = window[key] - } - window = newWindow - - for (let key of Object.keys(document)) { - newDocument[key] = document[key] - } - document = newDocument - - require = nodeRequire - } - } -})() diff --git a/lib/file-require-transform.js b/lib/file-require-transform.js deleted file mode 100644 index cbf8a61..0000000 --- a/lib/file-require-transform.js +++ /dev/null @@ -1,295 +0,0 @@ -const assert = require('assert') -const path = require('path') -const recast = require('recast') -const astUtil = require('ast-util') -const b = recast.types.builders -const resolve = require('resolve') - -const GLOBALS = new Set(['global', 'window', 'process', 'document']) -const NODE_CORE_MODULES = new Set([ - 'assert', 'buffer', 'child_process', 'cluster', 'constants', 'crypto', - 'dgram', 'dns', 'domain', 'events', 'fs', 'http', 'https', 'module', 'net', - 'os', 'path', 'punycode', 'querystring', 'readline', 'repl', 'stream', - 'string_decoder', 'tls', 'tty', 'url', 'util', 'v8', 'vm', 'zlib' -]) - -module.exports = class FileRequireTransform { - constructor (options) { - this.options = options - } - - apply () { - let source = this.options.source - if (this.options.filePath && path.extname(this.options.filePath) === '.json') { - // Replace line separator and paragraph separator character (which aren't - // supported inside javascript strings) with escape unicode sequences. - source = "module.exports = " + source.replace(/\u2028/g, '\\u2028').replace(/\u2029/g, '\\u2029') - } - this.ast = recast.parse(source) - this.lazyRequireFunctionsByVariableName = new Map() - this.replaceDeferredRequiresWithLazyFunctions() - this.replaceReferencesToDeferredRequiresWithFunctionCalls() - this.replaceReferencesToGlobalsWithFunctionCalls() - return recast.print(this.ast).code - } - - replaceDeferredRequiresWithLazyFunctions () { - const self = this - recast.types.visit(this.ast, { - visitCallExpression: function (astPath) { - if (isStaticRequire(astPath)) { - const moduleName = astPath.node.arguments[0].value - const absoluteModulePath = self.resolveModulePath(moduleName) - if (absoluteModulePath) { - let relativeModulePath = path.relative(self.options.baseDirPath, absoluteModulePath) - if (!relativeModulePath.startsWith('.')) { - relativeModulePath = './' + relativeModulePath - } - astPath.get('arguments', 0).replace(b.literal(relativeModulePath)) - } - - const deferRequire = NODE_CORE_MODULES.has(moduleName) || self.options.didFindRequire(moduleName, absoluteModulePath || moduleName) - if (deferRequire && isTopLevelASTPath(astPath)) { - self.replaceAssignmentOrDeclarationWithLazyFunction(astPath) - } - } else if (isStaticRequireResolve(astPath)) { - const moduleName = astPath.node.arguments[0].value - const absoluteModulePath = self.resolveModulePath(moduleName) - if (absoluteModulePath) { - let relativeModulePath = path.relative(self.options.baseDirPath, absoluteModulePath) - if (!relativeModulePath.startsWith('.')) { - relativeModulePath = './' + relativeModulePath - } - astPath.get('arguments', 0).replace(b.literal(relativeModulePath)) - } - } - this.traverse(astPath) - } - }) - - let foundReferenceToLazyRequire = true - while (foundReferenceToLazyRequire) { - foundReferenceToLazyRequire = false - recast.types.visit(this.ast, { - visitIdentifier: function (astPath) { - if (isTopLevelASTPath(astPath) && self.isReferenceToLazyRequire(astPath)) { - astPath.replace(b.callExpression(b.identifier(self.lazyRequireFunctionsByVariableName.get(astPath.node.name)), [])) - self.replaceAssignmentOrDeclarationWithLazyFunction(astPath) - foundReferenceToLazyRequire = true - this.abort() - } else { - this.traverse(astPath) - } - } - }) - } - } - - replaceReferencesToDeferredRequiresWithFunctionCalls () { - const self = this - recast.types.visit(this.ast, { - visitIdentifier: function (astPath) { - if (!isTopLevelASTPath(astPath) && self.isReferenceToLazyRequire(astPath) && !isReferenceToShadowedVariable(astPath)) { - astPath.replace(b.callExpression(b.identifier(self.lazyRequireFunctionsByVariableName.get(astPath.node.name)), [])) - } - this.traverse(astPath) - } - }) - } - - replaceReferencesToGlobalsWithFunctionCalls () { - recast.types.visit(this.ast, { - visitIdentifier: function (astPath) { - if (astUtil.isReference(astPath) && !isReferenceToShadowedVariable(astPath) && GLOBALS.has(astPath.node.name)) { - astPath.replace(b.callExpression(b.identifier(`get_${astPath.node.name}`), [])) - } - this.traverse(astPath) - } - }) - } - - replaceAssignmentOrDeclarationWithLazyFunction (astPath) { - let parentPath = astPath.parent - while (parentPath != null && parentPath.scope === astPath.scope) { - const parentNode = parentPath.node - if (parentNode.type === 'AssignmentExpression') { - const lazyRequireFunctionName = `get_${parentNode.left.name}` - - let ifStatementPath = parentPath.parent - while (ifStatementPath && ifStatementPath.node.type !== 'IfStatement') { - ifStatementPath = ifStatementPath.parent - } - - // Ensure we're assigning to a variable declared in this scope. - let assignmentLhs = parentNode.left - while (assignmentLhs.type === 'MemberExpression') { - assignmentLhs = assignmentLhs.object - } - assert.equal(assignmentLhs.type, 'Identifier') - assert( - astPath.scope.declares(assignmentLhs.name), - `${this.options.filePath}\nAssigning a deferred module to a variable that was not declared in this scope is not supported!` - ) - - // Replace assignment with lazy function - let replacement = null - if (ifStatementPath) { - if (!this.lazyRequireFunctionsByVariableName.has(parentNode.left.name)) { - ifStatementPath.insertBefore(b.variableDeclaration( - 'let', - [b.variableDeclarator(b.identifier(lazyRequireFunctionName), null)] - )) - } - - replacement = b.assignmentExpression('=', b.identifier(lazyRequireFunctionName), b.functionExpression(null, [], b.blockStatement([ - b.returnStatement( - b.assignmentExpression('=', parentNode.left, b.logicalExpression('||', parentNode.left, parentNode.right)) - ) - ]))) - } else { - replacement = b.functionDeclaration(b.identifier(lazyRequireFunctionName), [], b.blockStatement([ - b.returnStatement( - b.assignmentExpression('=', parentNode.left, b.logicalExpression('||', parentNode.left, parentNode.right)) - ) - ])) - } - - if (parentPath.parent.node.type === 'SequenceExpression') { - const sequenceExpressionPath = parentPath.parent - const expressionContainerPath = sequenceExpressionPath.parent - if (sequenceExpressionPath.node.expressions.length === 1) { - expressionContainerPath.replace(replacement) - } else { - expressionContainerPath.insertBefore(replacement) - parentPath.replace() - } - } else { - parentPath.replace(replacement) - } - - this.lazyRequireFunctionsByVariableName.set(parentNode.left.name, lazyRequireFunctionName) - return - } else if (parentNode.type === 'VariableDeclarator') { - // Replace variable declaration with lazy function - const variableDeclarationPath = parentPath.parent - const variableDeclarationNode = variableDeclarationPath.node - if (variableDeclarationNode.kind === 'const') { - variableDeclarationNode.kind = 'let' - } - - if (parentNode.id.type === 'ObjectPattern') { - parentPath.replace(b.variableDeclarator(parentNode.id, b.objectExpression([]))) - for (const property of parentNode.id.properties.slice().reverse()) { - const lazyRequireFunctionName = `get_${property.key.name}` - variableDeclarationPath.insertAfter(b.functionDeclaration(b.identifier(lazyRequireFunctionName), [], b.blockStatement([ - b.returnStatement( - b.assignmentExpression('=', property.key, b.logicalExpression('||', property.key, b.memberExpression(parentNode.init, property.key))) - ) - ]))) - this.lazyRequireFunctionsByVariableName.set(property.key.name, lazyRequireFunctionName) - } - } else { - parentPath.replace(b.variableDeclarator(parentNode.id, null)) - const lazyRequireFunctionName = `get_${parentNode.id.name}` - variableDeclarationPath.insertAfter(b.functionDeclaration(b.identifier(lazyRequireFunctionName), [], b.blockStatement([ - b.returnStatement( - b.assignmentExpression('=', parentNode.id, b.logicalExpression('||', parentNode.id, parentNode.init)) - ) - ]))) - this.lazyRequireFunctionsByVariableName.set(parentNode.id.name, lazyRequireFunctionName) - } - - return - } - parentPath = parentPath.parent - } - - throw new Error( - `${this.options.filePath}\n` + - `Cannot replace with lazy function because the supplied node does not belong to an assignment expression or a variable declaration!` - ) - } - - isReferenceToLazyRequire (astPath) { - const scope = astPath.scope - const lazyRequireFunctionName = this.lazyRequireFunctionsByVariableName.get(astPath.node.name) - return ( - lazyRequireFunctionName != null && - (scope.node.type !== 'FunctionDeclaration' || lazyRequireFunctionName !== astPath.scope.node.id.name) && - (scope.node.type !== 'FunctionExpression' || scope.path.parent.node.type !== 'AssignmentExpression' || lazyRequireFunctionName !== scope.path.parent.node.left.name) && - (astPath.parent.node.type !== 'Property' || astPath.parent.parent.node.type !== 'ObjectPattern') && - astPath.parent.node.type !== 'AssignmentExpression' && - astUtil.isReference(astPath) - ) - } - - resolveModulePath (moduleName) { - try { - const absolutePath = resolve.sync(moduleName, {basedir: path.dirname(this.options.filePath), extensions: ['.js', '.json']}) - const isCoreNodeModule = absolutePath.indexOf(path.sep) === -1 - return isCoreNodeModule ? null : absolutePath - } catch (e) { - return null - } - } -} - -function isReferenceToShadowedVariable (astPath) { - const referenceName = astPath.node.name - let scope = astPath.scope - let foundDeclaration = GLOBALS.has(referenceName) - while (scope) { - if (scope.declares(referenceName)) { - if (foundDeclaration) { - return true - } else { - foundDeclaration = true - } - } - scope = scope.parent - } - return false -} - -function isStaticRequire (astPath) { - const node = astPath.node - return ( - node.callee.name === 'require' && - node.arguments.length === 1 && - node.arguments[0].type === 'Literal' - ) -} - -function isStaticRequireResolve (astPath) { - const node = astPath.node - return ( - node.callee.type === 'MemberExpression' && - node.callee.object.name === 'require' && - node.callee.property.name === 'resolve' && - node.arguments.length === 1 && - node.arguments[0].type === 'Literal' - ) -} - -function isTopLevelASTPath (astPath) { - if (astPath.scope.isGlobal) { - return true - } else if (astPath.scope.depth === 1) { - while (astPath) { - const node = astPath.node - if (node.type === 'FunctionExpression') { - const parentNode = astPath.parent.node - const grandparentNode = astPath.parent.parent.node - const parentIsCallExpression = parentNode.type === 'CallExpression' && parentNode.arguments.indexOf(node) === -1 - const grandparentIsCallExpression = grandparentNode.type === 'CallExpression' - if (parentIsCallExpression || grandparentIsCallExpression) { - return true - } - } - astPath = astPath.parent - } - return false - } else { - return false - } -} diff --git a/lib/generate-snapshot-script.js b/lib/generate-snapshot-script.js deleted file mode 100644 index 09b942e..0000000 --- a/lib/generate-snapshot-script.js +++ /dev/null @@ -1,78 +0,0 @@ -'use strict' - -const fs = require('fs') -const path = require('path') -const FileRequireTransform = require('./file-require-transform') -const indentString = require('indent-string') - -module.exports = function (options) { - // Phase 1: Starting at the main module, traverse all requires, transforming - // all module references to paths relative to the base directory path and - // collecting abstract syntax trees for use in generating the script in - // phase 2. - const moduleASTs = {} - const requiredModulePaths = [options.mainPath] - while (requiredModulePaths.length > 0) { - const filePath = requiredModulePaths.shift() - let relativeFilePath = path.relative(options.baseDirPath, filePath) - if (!relativeFilePath.startsWith('.')) { - relativeFilePath = './' + relativeFilePath - } - if (!moduleASTs[relativeFilePath]) { - const source = fs.readFileSync(filePath, 'utf8') - let foundRequires = [] - const transform = new FileRequireTransform({ - filePath, - source, - baseDirPath: options.baseDirPath, - didFindRequire: (unresolvedPath, resolvedPath) => { - if (options.shouldExcludeModule(resolvedPath)) { - return true - } else { - foundRequires.push({unresolvedPath, resolvedPath}) - return false - } - } - }) - const transformedSource = indentString(transform.apply(), ' ', 2) - moduleASTs[relativeFilePath] = `function (exports, module, __filename, __dirname, require, define) {\n${transformedSource}\n}` - requiredModulePaths.push(...foundRequires.map(r => r.resolvedPath)) - } - } - - // Phase 2: Now use the data we gathered during phase 1 to build a snapshot - // script based on `./blueprint.js`. - let snapshotContent = fs.readFileSync(path.join(__dirname, 'blueprint.js'), 'utf8') - - // Replace `require(main)` with a require of the relativized main module path. - let relativeFilePath = path.relative(options.baseDirPath, options.mainPath) - if (!relativeFilePath.startsWith('.')) { - relativeFilePath = './' + relativeFilePath - } - snapshotContent = snapshotContent.replace('mainModuleRequirePath', `"${relativeFilePath}"`) - - // Replace `require.definitions = {}` with an assignment of the actual definitions - // of all the modules. - let definitions = '' - const moduleFilePaths = Object.keys(moduleASTs) - for (let i = 0; i < moduleFilePaths.length - 1; i++) { - const filePath = moduleFilePaths[i] - const source = moduleASTs[filePath] - definitions += indentString(`"${filePath}": ${source}`, ' ', 4) + ',\n' - } - if (moduleFilePaths.length > 0) { - const filePath = moduleFilePaths[moduleFilePaths.length - 1] - const source = moduleASTs[filePath] - definitions += indentString(`"${filePath}": ${source}`, ' ', 4) - } - - const definitionsAssignment = 'customRequire.definitions = {}' - const definitionsAssignmentStartIndex = snapshotContent.indexOf(definitionsAssignment) - const definitionsAssignmentEndIndex = definitionsAssignmentStartIndex + definitionsAssignment.length - snapshotContent = - snapshotContent.slice(0, definitionsAssignmentStartIndex) + - `customRequire.definitions = {\n${definitions}\n }` + - snapshotContent.slice(definitionsAssignmentEndIndex) - - return snapshotContent -}