New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@parcel/scope-hoisting

Package Overview
Dependencies
Maintainers
1
Versions
293
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@parcel/scope-hoisting - npm Package Compare versions

Comparing version 2.0.0-nightly.214 to 2.0.0-nightly.219

10

lib/concat.js

@@ -40,3 +40,3 @@ "use strict";

async function concat(bundle, bundleGraph) {
async function concat(bundle, bundleGraph, wrappedAssets) {
let queue = new _utils.PromiseQueue({

@@ -53,3 +53,3 @@ maxConcurrent: 32

if (resolved) {
resolved.meta.shouldWrap = true;
wrappedAssets.add(resolved.id);
}

@@ -63,3 +63,3 @@

case 'asset':
queue.add(() => processAsset(bundle, node.value));
queue.add(() => processAsset(bundle, node.value, wrappedAssets));
}

@@ -127,3 +127,3 @@ });

async function processAsset(bundle, asset) {
async function processAsset(bundle, asset, wrappedAssets) {
let statements;

@@ -139,3 +139,3 @@

if (asset.meta.shouldWrap) {
if (wrappedAssets.has(asset.id)) {
statements = wrapModule(asset, statements);

@@ -142,0 +142,0 @@ }

@@ -74,3 +74,3 @@ "use strict";

if (entry && (!(0, _utils2.isEntry)(bundle, bundleGraph) || (0, _utils2.isReferenced)(bundle, bundleGraph))) {
if (entry && !referencedAssets.has(entry) && (!(0, _utils2.isEntry)(bundle, bundleGraph) || (0, _utils2.isReferenced)(bundle, bundleGraph))) {
let exportsId = (0, _utils2.assertString)(entry.meta.exportsIdentifier);

@@ -77,0 +77,0 @@ exported.add(exportsId);

@@ -28,7 +28,24 @@ "use strict";

const REGISTER_TEMPLATE = _template.default.statement('parcelRequire.registerBundle(ID, function () { STATEMENTS; })');
const REGISTER_TEMPLATE = _template.default.statement(`(function() {
function $parcel$bundleWrapper() {
if ($parcel$bundleWrapper._executed) return;
STATEMENTS;
$parcel$bundleWrapper._executed = true;
}
parcelRequire.registerBundle(ID, $parcel$bundleWrapper);
var $parcel$referencedAssets = REFERENCED_IDS;
for (var $parcel$i = 0; $parcel$i < $parcel$referencedAssets.length; $parcel$i++) {
parcelRequire.registerBundle($parcel$referencedAssets[$parcel$i], $parcel$bundleWrapper);
}
})()`);
const WRAPPER_TEMPLATE = _template.default.statement('(function () { STATEMENTS; })()');
function generate(bundleGraph, bundle, ast, options) {
function generate({
bundleGraph,
bundle,
ast,
referencedAssets,
options
}) {
let interpreter;

@@ -51,3 +68,4 @@

ID: t.stringLiteral((0, _nullthrows.default)(entry).id),
STATEMENTS: statements
STATEMENTS: statements,
REFERENCED_IDS: t.arrayExpression([...referencedAssets].map(asset => t.stringLiteral(asset.id)))
})] : [WRAPPER_TEMPLATE({

@@ -54,0 +72,0 @@ STATEMENTS: statements

@@ -48,3 +48,4 @@ "use strict";

ast,
options
options,
wrappedAssets
}) {

@@ -397,3 +398,3 @@ let format = _index.default[bundle.env.outputFormat];

if (mod.meta.shouldWrap) {
if (wrappedAssets.has(mod.id)) {
node = t.callExpression((0, _utils.getIdentifier)(mod, 'init'), []);

@@ -609,3 +610,3 @@ } // Replace with nothing if the require call's result is not used.

// not in the current bundle.
let decls = path.pushContainer('body', [...referencedAssets].filter(a => !a.meta.shouldWrap).map(a => {
let decls = path.pushContainer('body', [...referencedAssets].filter(a => !wrappedAssets.has(a.id)).map(a => {
return FAKE_INIT_TEMPLATE({

@@ -631,3 +632,3 @@ INIT: (0, _utils.getIdentifier)(a, 'init'),

let exported = format.generateExports(bundleGraph, bundle, referencedAssets, path, replacements, options);
(0, _shake.default)(path.scope, exported);
(0, _shake.default)(path.scope, exported, exportsMap);
}

@@ -637,3 +638,6 @@

});
return ast;
return {
ast,
referencedAssets
};
}

@@ -22,3 +22,3 @@ "use strict";

*/
function treeShake(scope, exportedIdentifiers) {
function treeShake(scope, exportedIdentifiers, exportsMap) {
// Keep passing over all bindings in the scope until we don't remove any.

@@ -32,3 +32,3 @@ // This handles cases where we remove one binding which had a reference to

Object.keys(scope.bindings).forEach(name => {
let binding = getUnusedBinding(scope.path, name); // If it is not safe to remove the binding don't touch it.
let binding = getUnusedBinding(scope.path, name, exportsMap); // If it is not safe to remove the binding don't touch it.

@@ -41,3 +41,3 @@ if (!binding || exportedIdentifiers.has(name)) {

(0, _utils.pathRemove)(binding.path);
[...binding.referencePaths, ...binding.constantViolations].forEach(p => remove(p, scope));
[...binding.referencePaths, ...binding.constantViolations].forEach(p => remove(p, scope, exportsMap));
scope.removeBinding(name);

@@ -50,3 +50,3 @@ removed = true;

function getUnusedBinding(path, name) {
function getUnusedBinding(path, name, exportsMap) {
let binding = path.scope.getBinding(name);

@@ -58,3 +58,3 @@

if (!isPure(binding.path)) {
if (!isPure(binding)) {
// declaration (~= init) isn't pure

@@ -64,2 +64,11 @@ return null;

if (hasSideEffects(binding)) {
// e.g.
// let foo = {};
// foo = window;
// foo.xyz = 2;
// console.log(window.xyz);
return null;
}
if (!binding.referenced) {

@@ -70,3 +79,3 @@ return binding;

let bailout = binding.referencePaths.some(path => !isExportAssignment(path) && !isWildcardDest(path));
let bailout = binding.referencePaths.some(path => !isExportAssignment(path, exportsMap) && !isWildcardDest(path));

@@ -80,4 +89,7 @@ if (!bailout) {

function isPure(path) {
function isPure(binding) {
let {
path
} = binding;
let {
node

@@ -96,8 +108,22 @@ } = path;

function isExportAssignment(path) {
function hasSideEffects(binding) {
let {
node
} = binding.path;
if ((0, _types.isVariableDeclarator)(node)) {
return !((!binding.referenced || (0, _types.isObjectExpression)(node.init)) && (binding.constant || binding.constantViolations.every(({
node
}) => !(0, _types.isAssignmentExpression)(node) || (0, _types.isObjectExpression)(node.right))));
}
return false;
}
function isExportAssignment(path, exportsMap) {
let {
parent
} = path; // match "path.foo = bar;"
} = path; // match "path.foo = bar;", where path is a known exports identifier.
if ((0, _types.isMemberExpression)(parent) && parent.object === path.node && ((0, _types.isIdentifier)(parent.property) && !parent.computed || (0, _types.isStringLiteral)(parent.property))) {
if ((0, _types.isMemberExpression)(parent) && parent.object === path.node && (0, _types.isIdentifier)(path.node) && exportsMap.has(path.node.name) && ((0, _types.isIdentifier)(parent.property) && !parent.computed || (0, _types.isStringLiteral)(parent.property))) {
let parentParent = path.parentPath.parent;

@@ -118,3 +144,3 @@ return (0, _types.isAssignmentExpression)(parentParent) && parentParent.left === parent;

function remove(path, scope) {
function remove(path, scope, exportsMap) {
let {

@@ -132,3 +158,3 @@ node,

path.parentPath.replaceWith(node);
remove(path.parentPath, scope);
remove(path.parentPath, scope, exportsMap);
} else if ( //e.g. `exports.foo = bar;`, `bar` needs to be pure (an Identifier isn't ?!)

@@ -141,4 +167,4 @@ (0, _types.isExpressionStatement)(parent) && ((right = path.get('right')).isPure() || right.isIdentifier())) {

}
} else if (isExportAssignment(path)) {
remove(path.parentPath.parentPath, scope);
} else if (isExportAssignment(path, exportsMap)) {
remove(path.parentPath.parentPath, scope, exportsMap);
} else if (isWildcardDest(path)) {

@@ -160,3 +186,3 @@ let wildcard = path.parent;

(0, _assert.default)((0, _types.isIdentifier)(src) || (0, _types.isObjectExpression)(src) && src.properties.length === 0);
remove(path.parentPath, scope);
remove(path.parentPath, scope, exportsMap);
}

@@ -168,3 +194,3 @@ } else if (!path.removed) {

path.parentPath.replaceWith(node);
remove(path.parentPath, scope);
remove(path.parentPath, scope, exportsMap);
} else {

@@ -171,0 +197,0 @@ (0, _utils.pathRemove)(path);

@@ -33,6 +33,2 @@ "use strict";

function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
function getName(asset, type, ...rest) {

@@ -184,5 +180,3 @@ return '$' + t.toIdentifier(asset.id) + '$' + type + (rest.length ? '$' + rest.map(name => name === 'default' ? name : t.toIdentifier(name)).join('$') : '');

(0, _assert.default)(newBindings[name], name);
let _oldBindings$name = oldBindings[name],
{
let {
scope: aScope,

@@ -192,8 +186,6 @@ constantViolations: aConstantViolations,

identifier: aId,
path: aPath
} = _oldBindings$name,
a = _objectWithoutProperties(_oldBindings$name, ["scope", "constantViolations", "referencePaths", "identifier", "path"]);
let _newBindings$name = newBindings[name],
{
path: aPath,
...a
} = oldBindings[name];
let {
scope: bScope,

@@ -203,6 +195,5 @@ constantViolations: bConstantViolations,

identifier: bId,
path: bPath
} = _newBindings$name,
b = _objectWithoutProperties(_newBindings$name, ["scope", "constantViolations", "referencePaths", "identifier", "path"]);
path: bPath,
...b
} = newBindings[name];
(0, _assert.default)(aPath === bPath, name);

@@ -209,0 +200,0 @@ (0, _assert.default)(aId === bId, name);

{
"name": "@parcel/scope-hoisting",
"version": "2.0.0-nightly.214+52fd6741",
"version": "2.0.0-nightly.219+f9f7320b",
"description": "Blazing fast, zero configuration web application bundler",

@@ -24,9 +24,9 @@ "license": "MIT",

"@babel/types": "^7.3.3",
"@parcel/babylon-walk": "2.0.0-nightly.1836+52fd6741",
"@parcel/diagnostic": "2.0.0-nightly.214+52fd6741",
"@parcel/babylon-walk": "2.0.0-nightly.1841+f9f7320b",
"@parcel/diagnostic": "2.0.0-nightly.219+f9f7320b",
"@parcel/source-map": "^2.0.0-alpha.4.9",
"@parcel/utils": "2.0.0-nightly.214+52fd6741",
"@parcel/utils": "2.0.0-nightly.219+f9f7320b",
"nullthrows": "^1.1.1"
},
"gitHead": "52fd6741a0ea1f2e043c628cf6b7be0715b1c837"
"gitHead": "f9f7320bed19a9a2a7d75d5c6da657272b4b44ef"
}

@@ -53,3 +53,7 @@ // @flow

export async function concat(bundle: Bundle, bundleGraph: BundleGraph) {
export async function concat(
bundle: Bundle,
bundleGraph: BundleGraph,
wrappedAssets: Set<string>,
) {
let queue = new PromiseQueue({maxConcurrent: 32});

@@ -66,3 +70,3 @@ bundle.traverse((node, shouldWrap) => {

if (resolved) {
resolved.meta.shouldWrap = true;
wrappedAssets.add(resolved.id);
}

@@ -73,3 +77,3 @@ return true;

case 'asset':
queue.add(() => processAsset(bundle, node.value));
queue.add(() => processAsset(bundle, node.value, wrappedAssets));
}

@@ -146,3 +150,7 @@ });

async function processAsset(bundle: Bundle, asset: Asset) {
async function processAsset(
bundle: Bundle,
asset: Asset,
wrappedAssets: Set<string>,
) {
let statements: Array<Statement>;

@@ -157,3 +165,3 @@ if (asset.astGenerator && asset.astGenerator.type === 'babel') {

if (asset.meta.shouldWrap) {
if (wrappedAssets.has(asset.id)) {
statements = wrapModule(asset, statements);

@@ -160,0 +168,0 @@ }

@@ -93,2 +93,3 @@ // @flow

entry &&
!referencedAssets.has(entry) &&
(!isEntry(bundle, bundleGraph) || isReferenced(bundle, bundleGraph))

@@ -95,0 +96,0 @@ ) {

// @flow
import type {Bundle, BundleGraph, PluginOptions} from '@parcel/types';
import type {Asset, Bundle, BundleGraph, PluginOptions} from '@parcel/types';
import type {
ArrayExpression,
ExpressionStatement,

@@ -20,5 +21,20 @@ File,

const REGISTER_TEMPLATE = template.statement<
{|ID: StringLiteral, STATEMENTS: Array<Statement>|},
{|
ID: StringLiteral,
REFERENCED_IDS: ArrayExpression,
STATEMENTS: Array<Statement>,
|},
ExpressionStatement,
>('parcelRequire.registerBundle(ID, function () { STATEMENTS; })');
>(`(function() {
function $parcel$bundleWrapper() {
if ($parcel$bundleWrapper._executed) return;
STATEMENTS;
$parcel$bundleWrapper._executed = true;
}
parcelRequire.registerBundle(ID, $parcel$bundleWrapper);
var $parcel$referencedAssets = REFERENCED_IDS;
for (var $parcel$i = 0; $parcel$i < $parcel$referencedAssets.length; $parcel$i++) {
parcelRequire.registerBundle($parcel$referencedAssets[$parcel$i], $parcel$bundleWrapper);
}
})()`);
const WRAPPER_TEMPLATE = template.statement<

@@ -29,3 +45,9 @@ {|STATEMENTS: Array<Statement>|},

export function generate(
export function generate({
bundleGraph,
bundle,
ast,
referencedAssets,
options,
}: {|
bundleGraph: BundleGraph,

@@ -35,3 +57,4 @@ bundle: Bundle,

options: PluginOptions,
) {
referencedAssets: Set<Asset>,
|}) {
let interpreter;

@@ -56,2 +79,5 @@ if (!bundle.target.env.isBrowser()) {

STATEMENTS: statements,
REFERENCED_IDS: t.arrayExpression(
[...referencedAssets].map(asset => t.stringLiteral(asset.id)),
),
}),

@@ -58,0 +84,0 @@ ]

@@ -71,2 +71,3 @@ // @flow

options,
wrappedAssets,
}: {|

@@ -77,3 +78,4 @@ bundle: Bundle,

options: PluginOptions,
|}) {
wrappedAssets: Set<string>,
|}): {|ast: File, referencedAssets: Set<Asset>|} {
let format = OutputFormats[bundle.env.outputFormat];

@@ -453,3 +455,3 @@ let replacements: Map<Symbol, Symbol> = new Map();

// function, if statement, or conditional expression.
if (mod.meta.shouldWrap) {
if (wrappedAssets.has(mod.id)) {
node = t.callExpression(getIdentifier(mod, 'init'), []);

@@ -666,3 +668,3 @@ }

([...referencedAssets]: Array<Asset>)
.filter(a => !a.meta.shouldWrap)
.filter(a => !wrappedAssets.has(a.id))
.map(a => {

@@ -702,3 +704,3 @@ return FAKE_INIT_TEMPLATE({

treeShake(path.scope, exported);
treeShake(path.scope, exported, exportsMap);
},

@@ -708,3 +710,3 @@ },

return ast;
return {ast, referencedAssets};
}
// @flow
import type {Symbol} from '@parcel/types';
import type {Asset, Symbol} from '@parcel/types';
import type {NodePath, Scope} from '@babel/traverse';

@@ -28,2 +28,3 @@ import type {Expression, Identifier, Node} from '@babel/types';

exportedIdentifiers: Set<Symbol>,
exportsMap: Map<Symbol, Asset>,
) {

@@ -38,3 +39,3 @@ // Keep passing over all bindings in the scope until we don't remove any.

Object.keys(scope.bindings).forEach((name: string) => {
let binding = getUnusedBinding(scope.path, name);
let binding = getUnusedBinding(scope.path, name, exportsMap);

@@ -49,3 +50,3 @@ // If it is not safe to remove the binding don't touch it.

[...binding.referencePaths, ...binding.constantViolations].forEach(p =>
remove(p, scope),
remove(p, scope, exportsMap),
);

@@ -60,3 +61,3 @@

// Check if a binding is safe to remove and returns it if it is.
function getUnusedBinding(path, name) {
function getUnusedBinding(path, name, exportsMap) {
let binding = path.scope.getBinding(name);

@@ -67,3 +68,3 @@ if (!binding) {

if (!isPure(binding.path)) {
if (!isPure(binding)) {
// declaration (~= init) isn't pure

@@ -73,2 +74,11 @@ return null;

if (hasSideEffects(binding)) {
// e.g.
// let foo = {};
// foo = window;
// foo.xyz = 2;
// console.log(window.xyz);
return null;
}
if (!binding.referenced) {

@@ -80,3 +90,3 @@ return binding;

let bailout = binding.referencePaths.some(
path => !isExportAssignment(path) && !isWildcardDest(path),
path => !isExportAssignment(path, exportsMap) && !isWildcardDest(path),
);

@@ -91,3 +101,4 @@

function isPure(path) {
function isPure(binding) {
let {path} = binding;
let {node} = path;

@@ -108,8 +119,26 @@ if (isVariableDeclarator(node) && isIdentifier(node.id)) {

function isExportAssignment(path) {
function hasSideEffects(binding) {
let {node} = binding.path;
if (isVariableDeclarator(node)) {
return !(
(!binding.referenced || isObjectExpression(node.init)) &&
(binding.constant ||
binding.constantViolations.every(
({node}) =>
!isAssignmentExpression(node) || isObjectExpression(node.right),
))
);
}
return false;
}
function isExportAssignment(path, exportsMap: Map<Symbol, Asset>) {
let {parent} = path;
// match "path.foo = bar;"
// match "path.foo = bar;", where path is a known exports identifier.
if (
isMemberExpression(parent) &&
parent.object === path.node &&
isIdentifier(path.node) &&
exportsMap.has(path.node.name) &&
((isIdentifier(parent.property) && !parent.computed) ||

@@ -135,3 +164,7 @@ isStringLiteral(parent.property))

function remove(path: NodePath<Node>, scope: Scope) {
function remove(
path: NodePath<Node>,
scope: Scope,
exportsMap: Map<Symbol, Asset>,
) {
let {node, parent} = path;

@@ -144,3 +177,3 @@ if (isAssignmentExpression(node)) {

path.parentPath.replaceWith(node);
remove(path.parentPath, scope);
remove(path.parentPath, scope, exportsMap);
} else if (

@@ -156,4 +189,4 @@ //e.g. `exports.foo = bar;`, `bar` needs to be pure (an Identifier isn't ?!)

}
} else if (isExportAssignment(path)) {
remove(path.parentPath.parentPath, scope);
} else if (isExportAssignment(path, exportsMap)) {
remove(path.parentPath.parentPath, scope, exportsMap);
} else if (isWildcardDest(path)) {

@@ -178,3 +211,3 @@ let wildcard = path.parent;

);
remove(path.parentPath, scope);
remove(path.parentPath, scope, exportsMap);
}

@@ -186,3 +219,3 @@ } else if (!path.removed) {

path.parentPath.replaceWith(node);
remove(path.parentPath, scope);
remove(path.parentPath, scope, exportsMap);
} else {

@@ -189,0 +222,0 @@ pathRemove(path);

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc