Skip to content

Commit

Permalink
fix(shaker): keep side effects from modules (#1190)
Browse files Browse the repository at this point in the history
  • Loading branch information
layershifter committed Jan 18, 2023
1 parent a6ab7e9 commit cf1d661
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 2 deletions.
5 changes: 5 additions & 0 deletions .changeset/weak-walls-behave.md
@@ -0,0 +1,5 @@
---
'@linaria/shaker': patch
---

fix: keep side effects from modules
Expand Up @@ -15,6 +15,11 @@ exports.defaultValue = Math.random() * _foo;
exports.foo = _foo;"
`;

exports[`shaker should keep side-effects from modules 1`] = `
"import 'regenerator-runtime/runtime.js';
export const a = 1;"
`;

exports[`shaker should process array patterns 1`] = `
"const [,, c] = array;
export { c };"
Expand Down Expand Up @@ -51,6 +56,8 @@ exports.Kind = _Kind;"

exports[`shaker should remove all references of \`a\` 1`] = `"exports.b = 10;"`;

exports[`shaker should remove asset imports 1`] = `"export const a = 1;"`;

exports[`shaker should remove related code 1`] = `
"const a = 1;
export { a };"
Expand Down
22 changes: 22 additions & 0 deletions packages/shaker/src/plugins/__tests__/shaker-plugin.test.ts
Expand Up @@ -309,4 +309,26 @@ describe('shaker', () => {
exports.default = defaultExports;"
`);
});

it('should remove asset imports', () => {
const { code, metadata } = keep(['a'])`
import './asset.css';
export const a = 1;
`;

expect(code).toMatchSnapshot();
expect(metadata.imports.size).toBe(0);
});

it('should keep side-effects from modules', () => {
const { code, metadata } = keep(['a'])`
import 'regenerator-runtime/runtime.js';
export const a = 1;
`;

expect(code).toMatchSnapshot();
expect(metadata.imports.size).toBe(1);
});
});
@@ -0,0 +1,23 @@
import shouldKeepSideEffect from '../../utils/shouldKeepSideEffect';

describe('shouldKeepSideEffect', () => {
it('allows modules', () => {
expect(shouldKeepSideEffect('@babel/runtime')).toBeTruthy();
expect(shouldKeepSideEffect('regenerator-runtime')).toBeTruthy();

expect(shouldKeepSideEffect('./side-effect')).toBeTruthy();
});

it('allows extensions', () => {
expect(shouldKeepSideEffect('./side-effect.js')).toBeTruthy();
expect(shouldKeepSideEffect('./side-effect.cjs')).toBeTruthy();
expect(shouldKeepSideEffect('./side-effect.mjs')).toBeTruthy();

expect(shouldKeepSideEffect('regenerator-runtime/runtime.js')).toBeTruthy();
});

it('skips assets', () => {
expect(shouldKeepSideEffect('./asset.css')).toBeFalsy();
expect(shouldKeepSideEffect('./asset.scss')).toBeFalsy();
});
});
10 changes: 8 additions & 2 deletions packages/shaker/src/plugins/shaker-plugin.ts
Expand Up @@ -22,6 +22,8 @@ import {
mutate,
} from '@linaria/utils';

import shouldKeepSideEffect from './utils/shouldKeepSideEffect';

type Core = typeof core;

export interface IShakerOptions {
Expand Down Expand Up @@ -276,8 +278,12 @@ export default function shakerPlugin(
.map((exp) => exp.local);

if (!keepSideEffects && sideEffectImports.length > 0) {
// Remove all imports that don't import something explicitly
sideEffectImports.forEach((i) => forDeleting.push(i.local));
// Remove all imports that don't import something explicitly and should not be kept
sideEffectImports.forEach((i) => {
if (!shouldKeepSideEffect(i.source)) {
forDeleting.push(i.local);
}
});
}

const deleted = new Set<NodePath>();
Expand Down
8 changes: 8 additions & 0 deletions packages/shaker/src/plugins/utils/shouldKeepSideEffect.ts
@@ -0,0 +1,8 @@
const EXT_REGEX = /\.[0-9a-z]+$/;
const ALLOWED_EXTENSIONS = ['.js', '.cjs', '.mjs'];

export default function shouldKeepSideEffect(importPath: string) {
const [ext] = importPath.match(EXT_REGEX) || [''];

return ext === '' || ALLOWED_EXTENSIONS.includes(ext);
}

0 comments on commit cf1d661

Please sign in to comment.