@linaria/utils
Version:
Blazing fast zero-runtime CSS in JS library
179 lines (164 loc) • 5.96 kB
JavaScript
"use strict";
var _path = require("path");
var babel = _interopRequireWildcard(require("@babel/core"));
var _generator = _interopRequireDefault(require("@babel/generator"));
var _dedent = _interopRequireDefault(require("dedent"));
var _scopeHelpers = require("../scopeHelpers");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
/* eslint-env jest */
const {
File
} = babel;
const run = rawCode => {
const code = (0, _dedent.default)(rawCode);
const filename = (0, _path.join)(__dirname, 'source.ts');
const ast = babel.parse(code, {
babelrc: false,
configFile: false,
filename,
presets: ['@babel/preset-typescript']
});
const file = new File({
filename
}, {
code,
ast
});
const visitor = path => {
var _path$node$leadingCom;
if (!((_path$node$leadingCom = path.node.leadingComments) !== null && _path$node$leadingCom !== void 0 && _path$node$leadingCom.length) || path.node.leadingComments[0].value.trim() !== 'remove') {
return;
}
const comment = path.node.leadingComments[0];
if (path.listKey && typeof path.key === 'number' && path.key > 0) {
var _prevNode$node$traili;
const prevNode = path.getSibling(path.key - 1);
if ((_prevNode$node$traili = prevNode.node.trailingComments) !== null && _prevNode$node$traili !== void 0 && _prevNode$node$traili.includes(comment)) {
var _prevNode$node$traili2;
// eslint-disable-next-line no-param-reassign
prevNode.node.trailingComments = (_prevNode$node$traili2 = prevNode.node.trailingComments) === null || _prevNode$node$traili2 === void 0 ? void 0 : _prevNode$node$traili2.filter(c => c !== comment);
}
}
// eslint-disable-next-line no-param-reassign
path.node.leadingComments = null;
(0, _scopeHelpers.removeWithRelated)([path]);
};
file.path.traverse({
Expression: visitor,
Statement: visitor
});
return (0, _generator.default)(file.path.node).code;
};
describe('removeWithRelated', () => {
it('should keep alive used import specifier', () => {
const code = run`
import { a, b } from './source';
/* remove */a;
`;
expect(code).toMatchSnapshot();
});
it('should remove the whole import', () => {
const code = run`
import { a } from './source';
/* remove */a;
`;
expect(code).toMatchSnapshot();
});
it('should remove try/catch block', () => {
const code = run`
const a = 1;
try {
/* remove */42;
} catch (e) {
}
`;
expect(code).toMatchSnapshot();
});
it('should optimize logical expression', () => {
const code = run`
const a = 1;
/* remove */const b = 2;
const c = 3;
const res = a && b && c;
`;
expect(code).toMatchSnapshot();
});
it('should shake try/catch', () => {
const code = run`
{
const a = 1;
/* remove */const b = 2;
function c() {
try {
return a;
} catch(e) {
return b;
}
}
}
`;
expect(code).toMatchSnapshot();
});
it('should remove node if it becomes invalid after removing its children', () => {
const code = run`
/* remove */const mode = "DEV";
if (mode !== "DEV") {
}
`;
expect(code).toMatchSnapshot();
});
it('should not delete params of functions', () => {
const code = run`
function test(arg) {
/* remove */console.log(arg);
return null;
}
`;
expect(code).toMatchSnapshot();
});
it('should remove functions with empty bodies', () => {
const code = run`
function container() {
function testFn(arg) {
/* remove */console.log(arg);
}
const testArrow = (arg) => {
/* remove */console.log(arg);
}
}
`;
expect(code).toBe('function container() {}');
});
it('should not remove top-level functions with empty bodies', () => {
const code = run`
function testFn(arg) {
/* remove */console.log(arg);
}
export const testArrow1 = (arg) => {
/* remove */console.log(arg);
}
const testArrow2 = (arg) => (
/* remove */testFn = arg
)
export default function testDefaultFn(arg) {
/* remove */console.log(arg);
}
`;
expect(code).toMatchSnapshot();
});
it('should not remove functions that are assigned to prototype', () => {
const code = run`
(function() {
function SomeClass() {}
SomeClass.prototype.foo = function foo() {}
SomeClass.prototype.bar = function bar() {
/* remove */console.log(arg);
};
})();
`;
expect(code).toMatchSnapshot();
});
});
//# sourceMappingURL=removeWithRelated.test.js.map