Socket
Socket
Sign inDemoInstall

@linaria/shaker

Package Overview
Dependencies
192
Maintainers
4
Versions
49
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 4.5.3 to 5.0.0

47

esm/index.js

@@ -1,31 +0,38 @@

import { hasEvaluatorMetadata } from '@linaria/utils';
import { getPluginKey, hasEvaluatorMetadata } from '@linaria/utils';
export { default as shakerPlugin } from './plugins/shaker-plugin';
const getKey = plugin => {
if (typeof plugin === 'string') {
return plugin;
}
if (Array.isArray(plugin)) {
return getKey(plugin[0]);
}
if (typeof plugin === 'object' && plugin !== null && 'key' in plugin) {
return plugin.key ?? null;
}
return null;
};
const hasKeyInList = (plugin, list) => {
const pluginKey = getKey(plugin);
const pluginKey = getPluginKey(plugin);
return pluginKey ? list.some(i => pluginKey.includes(i)) : false;
};
const shaker = (babelOptions, ast, code, {
const safeResolve = (id, paths) => {
try {
return require.resolve(id, {
paths: paths.filter(i => i !== null)
});
} catch {
return null;
}
};
const shaker = (evalConfig, ast, code, {
highPriorityPlugins,
...config
}, babel) => {
const preShakePlugins = babelOptions.plugins?.filter(i => hasKeyInList(i, highPriorityPlugins)) ?? [];
const plugins = [...preShakePlugins, [require.resolve('./plugins/shaker-plugin'), config], ...(babelOptions.plugins ?? []).filter(i => !hasKeyInList(i, highPriorityPlugins))];
const hasCommonjsPlugin = babelOptions.plugins?.some(i => getKey(i) === 'transform-modules-commonjs');
const preShakePlugins = evalConfig.plugins?.filter(i => hasKeyInList(i, highPriorityPlugins)) ?? [];
const plugins = [...preShakePlugins, [require.resolve('./plugins/shaker-plugin'), config], ...(evalConfig.plugins ?? []).filter(i => !hasKeyInList(i, highPriorityPlugins))];
const hasCommonjsPlugin = evalConfig.plugins?.some(i => getPluginKey(i) === 'transform-modules-commonjs');
if (!hasCommonjsPlugin) {
plugins.push(require.resolve('@babel/plugin-transform-modules-commonjs'));
}
if (evalConfig.filename?.endsWith('.ts') || evalConfig.filename?.endsWith('.tsx')) {
const hasTypescriptPlugin = evalConfig.plugins?.some(i => getPluginKey(i) === 'transform-typescript');
if (!hasTypescriptPlugin) {
const preset = safeResolve('@babel/preset-typescript', [evalConfig.filename]);
const plugin = safeResolve('@babel/plugin-transform-typescript', [evalConfig.filename, preset]);
if (plugin) {
plugins.push(plugin);
}
}
}
const transformOptions = {
...babelOptions,
...evalConfig,
caller: {

@@ -38,3 +45,3 @@ name: 'linaria'

if (!transformed || !hasEvaluatorMetadata(transformed.metadata)) {
throw new Error(`${babelOptions.filename} has no shaker metadata`);
throw new Error(`${evalConfig.filename} has no shaker metadata`);
}

@@ -41,0 +48,0 @@ return [transformed.ast, transformed.code ?? '', transformed.metadata.linariaEvaluator.imports];

@@ -25,2 +25,3 @@ import { join } from 'path';

presets,
sourceType: /(?:^|\*\/|;)\s*(?:export|import)\s/m.test(formattedCode) ? 'module' : 'script',
plugins: [[shakerPlugin, {

@@ -219,3 +220,3 @@ onlyExports: only

expect(code).toMatchInlineSnapshot(`
"import foo from \\"foo\\";
"import foo from "foo";
export const {

@@ -275,3 +276,3 @@ Alive,

};
Object.defineProperty(exports, \\"createContext\\", {
Object.defineProperty(exports, "createContext", {
enumerable: !0,

@@ -286,10 +287,2 @@ get: function () {

it('deletes non-default exports when importing default export of a module with an __esModule: true property', () => {
/* without workaround, this will be transformed by shaker to:
const n = require('n');
const defaultExports = {
createContext: n.createContext
};
exports.default = defaultExports;
i.e, exports.createContext is deleted
*/
const {

@@ -316,6 +309,6 @@ code

};
Object.defineProperty(exports, \\"__esModule\\", {
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, \\"createContext\\", {
Object.defineProperty(exports, "createContext", {
enumerable: !0,

@@ -322,0 +315,0 @@ get: function () {}

import { createCustomDebug } from '@linaria/logger';
import { applyAction, collectExportsAndImports, dereference, findActionForNode, getFileIdx, isRemoved, reference, removeWithRelated, sideEffectImport } from '@linaria/utils';
import { applyAction, collectExportsAndImports, dereference, findActionForNode, getFileIdx, invalidateTraversalCache, isRemoved, reference, removeWithRelated, sideEffectImport } from '@linaria/utils';
import shouldKeepSideEffect from './utils/shouldKeepSideEffect';

@@ -29,3 +29,5 @@ function getBindingForExport(exportPath) {

}, root, exportRefs, exports) {
let rearranged = [...exports];
const rearranged = {
...exports
};
const rootScope = root.scope;

@@ -55,6 +57,3 @@ exportRefs.forEach((refs, name) => {

reference(local);
rearranged = rearranged.map(exp => exp.exported === name ? {
...exp,
local
} : exp);
rearranged[name] = local;
});

@@ -77,3 +76,3 @@ return rearranged;

const sideEffectImports = collected.imports.filter(sideEffectImport);
log('import-and-exports', [`imports: ${collected.imports.length} (side-effects: ${sideEffectImports.length})`, `exports: ${collected.exports.length}`, `reexports: ${collected.reexports.length}`].join(', '));
log('import-and-exports', [`imports: ${collected.imports.length} (side-effects: ${sideEffectImports.length})`, `exports: ${Object.values(collected.exports).length}`, `reexports: ${collected.reexports.length}`].join(', '));

@@ -83,6 +82,3 @@ // We cannot just throw out exports if they are referred in the code

const exports = rearrangeExports(babel, file.path, collected.exportRefs, collected.exports);
const findExport = name => exports.find(i => i.exported === name);
collected.exports.forEach(({
local
}) => {
Object.values(collected.exports).forEach(local => {
if (local.isAssignmentExpression()) {

@@ -97,4 +93,4 @@ const left = local.get('left');

});
const hasLinariaPreval = findExport('__linariaPreval') !== undefined;
const hasDefault = findExport('default') !== undefined;
const hasLinariaPreval = exports.__linariaPreval !== undefined;
const hasDefault = exports.default !== undefined;

@@ -108,4 +104,5 @@ // If __linariaPreval is not exported, we can remove it from onlyExports

this.imports = [];
this.exports = [];
this.exports = {};
this.reexports = [];
this.deadExports = Object.keys(exports);
file.path.get('body').forEach(p => {

@@ -127,2 +124,3 @@ p.remove();

this.reexports = collected.reexports;
this.deadExports = [];
return;

@@ -135,8 +133,8 @@ }

}) => imported);
exports.forEach(exp => {
if (onlyExportsSet.has(exp.exported)) {
aliveExports.add(exp);
} else if (importNames.includes(exp.local.node.name || '')) {
aliveExports.add(exp);
} else if ([...aliveExports].some(liveExp => liveExp.local === exp.local)) {
Object.entries(exports).forEach(([exported, local]) => {
if (onlyExportsSet.has(exported)) {
aliveExports.add(local);
} else if (importNames.includes(local.node.name || '')) {
aliveExports.add(local);
} else if ([...aliveExports].some(alive => alive === local)) {
// It's possible to export multiple values from a single variable initializer, e.g

@@ -146,3 +144,3 @@ // export const { foo, bar } = baz();

// we'll attempt to delete the baz() call
aliveExports.add(exp);
aliveExports.add(local);
}

@@ -152,3 +150,3 @@ });

if (onlyExportsSet.has(exp.exported)) {
aliveExports.add(exp);
aliveExports.add(exp.local);
}

@@ -163,10 +161,8 @@ });

// If there are unknown exports, we have keep alive all re-exports.
exports.forEach(exp => {
if (exp.exported === '*') {
aliveExports.add(exp);
}
});
if (exports['*'] !== undefined) {
aliveExports.add(exports['*']);
}
collected.reexports.forEach(exp => {
if (exp.exported === '*') {
aliveExports.add(exp);
aliveExports.add(exp.local);
}

@@ -179,6 +175,7 @@ });

this.reexports = collected.reexports;
this.deadExports = [];
return;
}
}
const forDeleting = [...exports, ...collected.reexports].filter(exp => !aliveExports.has(exp)).map(exp => exp.local);
const forDeleting = [...Object.values(exports), ...collected.reexports.map(i => i.local)].filter(exp => !aliveExports.has(exp));
if (!keepSideEffects && !importedAsSideEffect) {

@@ -227,3 +224,11 @@ // Remove all imports that don't import something explicitly and should not be kept

this.imports = withoutRemoved(collected.imports);
this.exports = withoutRemoved(exports);
this.exports = {};
this.deadExports = [];
Object.entries(exports).forEach(([exported, local]) => {
if (isRemoved(local)) {
this.deadExports.push(exported);
} else {
this.exports[exported] = local;
}
});
this.reexports = withoutRemoved(collected.reexports);

@@ -259,2 +264,3 @@ },

};
invalidateTraversalCache(file.path);
}

@@ -261,0 +267,0 @@ };

@@ -16,32 +16,39 @@ "use strict";

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const getKey = plugin => {
if (typeof plugin === 'string') {
return plugin;
}
if (Array.isArray(plugin)) {
return getKey(plugin[0]);
}
if (typeof plugin === 'object' && plugin !== null && 'key' in plugin) {
var _key;
return (_key = plugin.key) !== null && _key !== void 0 ? _key : null;
}
return null;
};
const hasKeyInList = (plugin, list) => {
const pluginKey = getKey(plugin);
const pluginKey = (0, _utils.getPluginKey)(plugin);
return pluginKey ? list.some(i => pluginKey.includes(i)) : false;
};
const shaker = (babelOptions, ast, code, {
const safeResolve = (id, paths) => {
try {
return require.resolve(id, {
paths: paths.filter(i => i !== null)
});
} catch {
return null;
}
};
const shaker = (evalConfig, ast, code, {
highPriorityPlugins,
...config
}, babel) => {
var _babelOptions$plugins, _babelOptions$plugins2, _babelOptions$plugins3, _babelOptions$plugins4, _transformed$code;
const preShakePlugins = (_babelOptions$plugins = (_babelOptions$plugins2 = babelOptions.plugins) === null || _babelOptions$plugins2 === void 0 ? void 0 : _babelOptions$plugins2.filter(i => hasKeyInList(i, highPriorityPlugins))) !== null && _babelOptions$plugins !== void 0 ? _babelOptions$plugins : [];
const plugins = [...preShakePlugins, [require.resolve('./plugins/shaker-plugin'), config], ...((_babelOptions$plugins3 = babelOptions.plugins) !== null && _babelOptions$plugins3 !== void 0 ? _babelOptions$plugins3 : []).filter(i => !hasKeyInList(i, highPriorityPlugins))];
const hasCommonjsPlugin = (_babelOptions$plugins4 = babelOptions.plugins) === null || _babelOptions$plugins4 === void 0 ? void 0 : _babelOptions$plugins4.some(i => getKey(i) === 'transform-modules-commonjs');
var _evalConfig$plugins$f, _evalConfig$plugins, _evalConfig$plugins2, _evalConfig$plugins3, _evalConfig$filename, _evalConfig$filename2, _transformed$code;
const preShakePlugins = (_evalConfig$plugins$f = (_evalConfig$plugins = evalConfig.plugins) === null || _evalConfig$plugins === void 0 ? void 0 : _evalConfig$plugins.filter(i => hasKeyInList(i, highPriorityPlugins))) !== null && _evalConfig$plugins$f !== void 0 ? _evalConfig$plugins$f : [];
const plugins = [...preShakePlugins, [require.resolve('./plugins/shaker-plugin'), config], ...((_evalConfig$plugins2 = evalConfig.plugins) !== null && _evalConfig$plugins2 !== void 0 ? _evalConfig$plugins2 : []).filter(i => !hasKeyInList(i, highPriorityPlugins))];
const hasCommonjsPlugin = (_evalConfig$plugins3 = evalConfig.plugins) === null || _evalConfig$plugins3 === void 0 ? void 0 : _evalConfig$plugins3.some(i => (0, _utils.getPluginKey)(i) === 'transform-modules-commonjs');
if (!hasCommonjsPlugin) {
plugins.push(require.resolve('@babel/plugin-transform-modules-commonjs'));
}
if ((_evalConfig$filename = evalConfig.filename) !== null && _evalConfig$filename !== void 0 && _evalConfig$filename.endsWith('.ts') || (_evalConfig$filename2 = evalConfig.filename) !== null && _evalConfig$filename2 !== void 0 && _evalConfig$filename2.endsWith('.tsx')) {
var _evalConfig$plugins4;
const hasTypescriptPlugin = (_evalConfig$plugins4 = evalConfig.plugins) === null || _evalConfig$plugins4 === void 0 ? void 0 : _evalConfig$plugins4.some(i => (0, _utils.getPluginKey)(i) === 'transform-typescript');
if (!hasTypescriptPlugin) {
const preset = safeResolve('@babel/preset-typescript', [evalConfig.filename]);
const plugin = safeResolve('@babel/plugin-transform-typescript', [evalConfig.filename, preset]);
if (plugin) {
plugins.push(plugin);
}
}
}
const transformOptions = {
...babelOptions,
...evalConfig,
caller: {

@@ -54,3 +61,3 @@ name: 'linaria'

if (!transformed || !(0, _utils.hasEvaluatorMetadata)(transformed.metadata)) {
throw new Error(`${babelOptions.filename} has no shaker metadata`);
throw new Error(`${evalConfig.filename} has no shaker metadata`);
}

@@ -57,0 +64,0 @@ return [transformed.ast, (_transformed$code = transformed.code) !== null && _transformed$code !== void 0 ? _transformed$code : '', transformed.metadata.linariaEvaluator.imports];

@@ -28,2 +28,3 @@ "use strict";

presets,
sourceType: /(?:^|\*\/|;)\s*(?:export|import)\s/m.test(formattedCode) ? 'module' : 'script',
plugins: [[_shakerPlugin.default, {

@@ -222,3 +223,3 @@ onlyExports: only

expect(code).toMatchInlineSnapshot(`
"import foo from \\"foo\\";
"import foo from "foo";
export const {

@@ -278,3 +279,3 @@ Alive,

};
Object.defineProperty(exports, \\"createContext\\", {
Object.defineProperty(exports, "createContext", {
enumerable: !0,

@@ -289,10 +290,2 @@ get: function () {

it('deletes non-default exports when importing default export of a module with an __esModule: true property', () => {
/* without workaround, this will be transformed by shaker to:
const n = require('n');
const defaultExports = {
createContext: n.createContext
};
exports.default = defaultExports;
i.e, exports.createContext is deleted
*/
const {

@@ -319,6 +312,6 @@ code

};
Object.defineProperty(exports, \\"__esModule\\", {
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, \\"createContext\\", {
Object.defineProperty(exports, "createContext", {
enumerable: !0,

@@ -325,0 +318,0 @@ get: function () {}

@@ -36,3 +36,5 @@ "use strict";

}, root, exportRefs, exports) {
let rearranged = [...exports];
const rearranged = {
...exports
};
const rootScope = root.scope;

@@ -62,6 +64,3 @@ exportRefs.forEach((refs, name) => {

(0, _utils.reference)(local);
rearranged = rearranged.map(exp => exp.exported === name ? {
...exp,
local
} : exp);
rearranged[name] = local;
});

@@ -84,3 +83,3 @@ return rearranged;

const sideEffectImports = collected.imports.filter(_utils.sideEffectImport);
log('import-and-exports', [`imports: ${collected.imports.length} (side-effects: ${sideEffectImports.length})`, `exports: ${collected.exports.length}`, `reexports: ${collected.reexports.length}`].join(', '));
log('import-and-exports', [`imports: ${collected.imports.length} (side-effects: ${sideEffectImports.length})`, `exports: ${Object.values(collected.exports).length}`, `reexports: ${collected.reexports.length}`].join(', '));

@@ -90,6 +89,3 @@ // We cannot just throw out exports if they are referred in the code

const exports = rearrangeExports(babel, file.path, collected.exportRefs, collected.exports);
const findExport = name => exports.find(i => i.exported === name);
collected.exports.forEach(({
local
}) => {
Object.values(collected.exports).forEach(local => {
if (local.isAssignmentExpression()) {

@@ -104,4 +100,4 @@ const left = local.get('left');

});
const hasLinariaPreval = findExport('__linariaPreval') !== undefined;
const hasDefault = findExport('default') !== undefined;
const hasLinariaPreval = exports.__linariaPreval !== undefined;
const hasDefault = exports.default !== undefined;

@@ -115,4 +111,5 @@ // If __linariaPreval is not exported, we can remove it from onlyExports

this.imports = [];
this.exports = [];
this.exports = {};
this.reexports = [];
this.deadExports = Object.keys(exports);
file.path.get('body').forEach(p => {

@@ -134,2 +131,3 @@ p.remove();

this.reexports = collected.reexports;
this.deadExports = [];
return;

@@ -142,8 +140,8 @@ }

}) => imported);
exports.forEach(exp => {
if (onlyExportsSet.has(exp.exported)) {
aliveExports.add(exp);
} else if (importNames.includes(exp.local.node.name || '')) {
aliveExports.add(exp);
} else if ([...aliveExports].some(liveExp => liveExp.local === exp.local)) {
Object.entries(exports).forEach(([exported, local]) => {
if (onlyExportsSet.has(exported)) {
aliveExports.add(local);
} else if (importNames.includes(local.node.name || '')) {
aliveExports.add(local);
} else if ([...aliveExports].some(alive => alive === local)) {
// It's possible to export multiple values from a single variable initializer, e.g

@@ -153,3 +151,3 @@ // export const { foo, bar } = baz();

// we'll attempt to delete the baz() call
aliveExports.add(exp);
aliveExports.add(local);
}

@@ -159,3 +157,3 @@ });

if (onlyExportsSet.has(exp.exported)) {
aliveExports.add(exp);
aliveExports.add(exp.local);
}

@@ -170,10 +168,8 @@ });

// If there are unknown exports, we have keep alive all re-exports.
exports.forEach(exp => {
if (exp.exported === '*') {
aliveExports.add(exp);
}
});
if (exports['*'] !== undefined) {
aliveExports.add(exports['*']);
}
collected.reexports.forEach(exp => {
if (exp.exported === '*') {
aliveExports.add(exp);
aliveExports.add(exp.local);
}

@@ -186,6 +182,7 @@ });

this.reexports = collected.reexports;
this.deadExports = [];
return;
}
}
const forDeleting = [...exports, ...collected.reexports].filter(exp => !aliveExports.has(exp)).map(exp => exp.local);
const forDeleting = [...Object.values(exports), ...collected.reexports.map(i => i.local)].filter(exp => !aliveExports.has(exp));
if (!keepSideEffects && !importedAsSideEffect) {

@@ -234,3 +231,11 @@ // Remove all imports that don't import something explicitly and should not be kept

this.imports = withoutRemoved(collected.imports);
this.exports = withoutRemoved(exports);
this.exports = {};
this.deadExports = [];
Object.entries(exports).forEach(([exported, local]) => {
if ((0, _utils.isRemoved)(local)) {
this.deadExports.push(exported);
} else {
this.exports[exported] = local;
}
});
this.reexports = withoutRemoved(collected.reexports);

@@ -266,2 +271,3 @@ },

};
(0, _utils.invalidateTraversalCache)(file.path);
}

@@ -268,0 +274,0 @@ };

{
"name": "@linaria/shaker",
"version": "4.5.3",
"version": "5.0.0",
"description": "Blazing fast zero-runtime CSS in JS library",

@@ -27,28 +27,27 @@ "keywords": [

"dependencies": {
"@babel/core": "^7.22.9",
"@babel/generator": "^7.22.9",
"@babel/plugin-transform-modules-commonjs": "^7.22.5",
"@babel/plugin-transform-runtime": "^7.22.9",
"@babel/core": "^7.22.15",
"@babel/generator": "^7.22.15",
"@babel/plugin-transform-modules-commonjs": "^7.22.15",
"@babel/plugin-transform-runtime": "^7.22.15",
"@babel/plugin-transform-template-literals": "^7.22.5",
"@babel/preset-env": "^7.22.9",
"@babel/preset-env": "^7.22.15",
"babel-plugin-transform-react-remove-prop-types": "^0.4.24",
"ts-invariant": "^0.10.3",
"@linaria/logger": "^4.5.0",
"@linaria/utils": "^4.5.3"
"@linaria/logger": "^5.0.0",
"@linaria/utils": "^5.0.0"
},
"devDependencies": {
"@babel/types": "^7.22.5",
"@types/babel__core": "^7.1.19",
"@babel/types": "^7.22.15",
"@types/babel__core": "^7.20.1",
"@types/babel__generator": "^7.6.4",
"@types/babel__traverse": "^7.17.1",
"@types/dedent": "^0.7.0",
"@types/babel__traverse": "^7.20.1",
"@types/jest": "^28.1.0",
"@types/node": "^17.0.39",
"dedent": "^0.7.0",
"jest": "^28.1.0",
"ts-jest": "^28.0.4",
"typescript": "^4.7.4"
"dedent": "^1.5.1",
"jest": "^29.6.2",
"ts-jest": "^29.1.1",
"typescript": "^5.2.2"
},
"engines": {
"node": "^12.16.0 || >=13.7.0"
"node": ">=16.0.0"
},

@@ -55,0 +54,0 @@ "publishConfig": {

import type core from '@babel/core';
import type { PluginObj } from '@babel/core';
import type { IState } from '@linaria/utils';
declare type Core = typeof core;
type Core = typeof core;
export interface IShakerOptions {
ifUnknownExport?: 'error' | 'ignore' | 'reexport-all' | 'skip-shaking';
keepSideEffects?: boolean;
ifUnknownExport?: 'error' | 'ignore' | 'reexport-all' | 'skip-shaking';
onlyExports: string[];

@@ -9,0 +9,0 @@ }

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

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

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc