Skip to content

Commit

Permalink
Move adding require statements to inside babel-plugin-strip-runtime (#…
Browse files Browse the repository at this point in the history
…1107)

* Move inserting require statements for atomic css rules to inside babel-plugin-strip-runtime so we can preserve leading comments
  • Loading branch information
hannahkmolloy committed Mar 7, 2022
1 parent 6df960c commit 588cd4f
Show file tree
Hide file tree
Showing 13 changed files with 117 additions and 118 deletions.
6 changes: 6 additions & 0 deletions .changeset/wild-cats-draw.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@compiled/babel-plugin-strip-runtime': patch
'@compiled/webpack-loader': patch
---

Adding require statements for atomic css now occurs inside the babel-plugin-strip-runtime plugin
5 changes: 5 additions & 0 deletions .changeset/wise-crabs-knock.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@compiled/babel-plugin': patch
---

Use preserveLeadingComments util from @compiled/utils
4 changes: 3 additions & 1 deletion packages/babel-plugin-strip-runtime/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@
"dependencies": {
"@babel/core": "^7.17.5",
"@babel/helper-plugin-utils": "^7.16.7",
"@babel/template": "^7.16.7",
"@babel/traverse": "^7.17.3",
"@babel/types": "^7.17.0"
"@babel/types": "^7.17.0",
"@compiled/utils": "^0.6.15"
},
"devDependencies": {
"@compiled/babel-plugin": "*",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,20 @@ import { format } from 'prettier';

import stripRuntimeBabelPlugin from '../index';

const testStyleSheetPath =
'@compiled/webpack-loader/css-loader!@compiled/webpack-loader/css-loader/compiled-css.css';
const regexToFindRequireStatements =
/(require\('@compiled\/webpack-loader\/css-loader!@compiled\/webpack-loader\/css-loader\/compiled-css\.css\?style=.*;)/g;

const transform = (
code: string,
opts: {
onFoundStyleRules?: (style: string[]) => void;
styleSheetPath?: string;
run: 'both' | 'bake' | 'extract';
runtime: 'automatic' | 'classic';
}
): string => {
const { onFoundStyleRules, run, runtime } = opts;
const { styleSheetPath, run, runtime } = opts;
const bake = run === 'both' || run === 'bake';
const extract = run === 'both' || run === 'extract';

Expand All @@ -24,7 +29,7 @@ const transform = (
filename: join(__dirname, 'app.tsx'),
plugins: [
...(bake ? [[compiledBabelPlugin, { importReact: runtime === 'classic' }]] : []),
...(extract ? [[stripRuntimeBabelPlugin, { onFoundStyleRules }]] : []),
...(extract ? [[stripRuntimeBabelPlugin, { styleSheetPath }]] : []),
],
presets: [['@babel/preset-react', { runtime }]],
});
Expand Down Expand Up @@ -74,15 +79,16 @@ describe('babel-plugin-strip-runtime using source code', () => {
`);
});

it('calls onFoundStyleRules for every found style', () => {
const onFoundStyleRules = jest.fn();

transform(code, { onFoundStyleRules, run: 'both', runtime });
it('adds require statement for every found style', () => {
const actual = transform(code, {
styleSheetPath: testStyleSheetPath,
run: 'both',
runtime,
});

expect(onFoundStyleRules).toHaveBeenCalledTimes(1);
expect(onFoundStyleRules).toHaveBeenCalledWith([
'._1wyb1fwx{font-size:12px}',
'._syaz13q2{color:blue}',
expect(actual.match(regexToFindRequireStatements)).toEqual([
`require('${testStyleSheetPath}?style=._syaz13q2%7Bcolor%3Ablue%7D');`,
`require('${testStyleSheetPath}?style=._1wyb1fwx%7Bfont-size%3A12px%7D');`,
]);
});
});
Expand Down Expand Up @@ -111,15 +117,16 @@ describe('babel-plugin-strip-runtime using source code', () => {
`);
});

it('calls onFoundStyleRules for every found style', () => {
const onFoundStyleRules = jest.fn();
it('adds require statement for every found style', () => {
const actual = transform(code, {
styleSheetPath: testStyleSheetPath,
run: 'both',
runtime,
});

transform(code, { onFoundStyleRules, run: 'both', runtime });

expect(onFoundStyleRules).toHaveBeenCalledTimes(1);
expect(onFoundStyleRules).toHaveBeenCalledWith([
'._1wyb1fwx{font-size:12px}',
'._syaz13q2{color:blue}',
expect(actual.match(regexToFindRequireStatements)).toEqual([
`require('${testStyleSheetPath}?style=._syaz13q2%7Bcolor%3Ablue%7D');`,
`require('${testStyleSheetPath}?style=._1wyb1fwx%7Bfont-size%3A12px%7D');`,
]);
});
});
Expand Down Expand Up @@ -149,16 +156,17 @@ describe('babel-plugin-strip-runtime using source code', () => {
`);
});

it('calls onFoundStyleRules for every found style', () => {
const onFoundStyleRules = jest.fn();
it('adds require statement for every found style', () => {
const baked = transform(code, { run: 'bake', runtime });

transform(baked, { onFoundStyleRules, run: 'both', runtime });

expect(onFoundStyleRules).toHaveBeenCalledTimes(1);
expect(onFoundStyleRules).toHaveBeenCalledWith([
'._1wyb1fwx{font-size:12px}',
'._syaz13q2{color:blue}',
const actual = transform(baked, {
styleSheetPath: testStyleSheetPath,
run: 'extract',
runtime,
});

expect(actual.match(regexToFindRequireStatements)).toEqual([
`require('${testStyleSheetPath}?style=._syaz13q2%7Bcolor%3Ablue%7D');`,
`require('${testStyleSheetPath}?style=._1wyb1fwx%7Bfont-size%3A12px%7D');`,
]);
});
});
Expand Down Expand Up @@ -187,16 +195,17 @@ describe('babel-plugin-strip-runtime using source code', () => {
`);
});

it('calls onFoundStyleRules for every found style', () => {
const onFoundStyleRules = jest.fn();
it('adds require statement for every found style', () => {
const baked = transform(code, { run: 'bake', runtime });

transform(baked, { onFoundStyleRules, run: 'both', runtime });

expect(onFoundStyleRules).toHaveBeenCalledTimes(1);
expect(onFoundStyleRules).toHaveBeenCalledWith([
'._1wyb1fwx{font-size:12px}',
'._syaz13q2{color:blue}',
const actual = transform(baked, {
styleSheetPath: testStyleSheetPath,
run: 'extract',
runtime,
});

expect(actual.match(regexToFindRequireStatements)).toEqual([
`require('${testStyleSheetPath}?style=._syaz13q2%7Bcolor%3Ablue%7D');`,
`require('${testStyleSheetPath}?style=._1wyb1fwx%7Bfont-size%3A12px%7D');`,
]);
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,20 @@ import { format } from 'prettier';

import stripRuntimeBabelPlugin from '../index';

const testStyleSheetPath =
'@compiled/webpack-loader/css-loader!@compiled/webpack-loader/css-loader/compiled-css.css';
const regexToFindRequireStatements =
/(require\('@compiled\/webpack-loader\/css-loader!@compiled\/webpack-loader\/css-loader\/compiled-css\.css\?style=.*;)/g;

const transform = (
code: string,
opts: {
modules?: boolean;
onFoundStyleRules?: (style: string[]) => void;
styleSheetPath?: string;
runtime: 'automatic' | 'classic';
}
): string => {
const { modules, onFoundStyleRules, runtime } = opts;
const { modules, styleSheetPath, runtime } = opts;
const filename = join(__dirname, 'app.tsx');

const initialFileResult = transformSync(code, {
Expand All @@ -37,7 +42,7 @@ const transform = (
babelrc: false,
configFile: false,
filename,
plugins: [[stripRuntimeBabelPlugin, { onFoundStyleRules }]],
plugins: [[stripRuntimeBabelPlugin, { styleSheetPath }]],
});

if (!fileResult || !fileResult.code) {
Expand Down Expand Up @@ -65,15 +70,12 @@ describe('babel-plugin-strip-runtime using transpiled code', () => {
describe('with the automatic runtime', () => {
const runtime = 'automatic';

it('calls onFoundStyleRules for every found style', () => {
const onFoundStyleRules = jest.fn();

transform(code, { onFoundStyleRules, runtime });
it('adds require statement for every found style', () => {
const actual = transform(code, { styleSheetPath: testStyleSheetPath, runtime });

expect(onFoundStyleRules).toHaveBeenCalledTimes(1);
expect(onFoundStyleRules).toHaveBeenCalledWith([
'._1wyb1fwx{font-size:12px}',
'._syaz13q2{color:blue}',
expect(actual.match(regexToFindRequireStatements)).toEqual([
`require('${testStyleSheetPath}?style=._syaz13q2%7Bcolor%3Ablue%7D');`,
`require('${testStyleSheetPath}?style=._1wyb1fwx%7Bfont-size%3A12px%7D');`,
]);
});

Expand Down Expand Up @@ -113,15 +115,12 @@ describe('babel-plugin-strip-runtime using transpiled code', () => {
describe('with the classic runtime', () => {
const runtime = 'classic';

it('calls onFoundStyleRules for every found style', () => {
const onFoundStyleRules = jest.fn();

transform(code, { onFoundStyleRules, runtime });
it('adds require statement for every found style', () => {
const actual = transform(code, { styleSheetPath: testStyleSheetPath, runtime });

expect(onFoundStyleRules).toHaveBeenCalledTimes(1);
expect(onFoundStyleRules).toHaveBeenCalledWith([
'._1wyb1fwx{font-size:12px}',
'._syaz13q2{color:blue}',
expect(actual.match(regexToFindRequireStatements)).toEqual([
`require('${testStyleSheetPath}?style=._syaz13q2%7Bcolor%3Ablue%7D');`,
`require('${testStyleSheetPath}?style=._1wyb1fwx%7Bfont-size%3A12px%7D');`,
]);
});

Expand Down
22 changes: 19 additions & 3 deletions packages/babel-plugin-strip-runtime/src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import { declare } from '@babel/helper-plugin-utils';
import template from '@babel/template';
import type { NodePath } from '@babel/traverse';
import * as t from '@babel/types';
import { preserveLeadingComments } from '@compiled/utils';

import type { PluginPass } from './types';
import { isAutomaticRuntime } from './utils/is-automatic-runtime';
import { isCCComponent } from './utils/is-cc-component';
import { isCreateElement } from './utils/is-create-element';
import { removeStyleDeclarations } from './utils/remove-style-declarations';
import { toURIComponent } from './utils/to-uri-component';

export default declare<PluginPass>((api) => {
api.assertVersion(7);
Expand All @@ -18,9 +21,22 @@ export default declare<PluginPass>((api) => {
},
visitor: {
Program: {
exit() {
if (this.opts.onFoundStyleRules) {
this.opts.onFoundStyleRules(this.styleRules);
exit(path) {
if (this.opts.styleSheetPath) {
preserveLeadingComments(path);
this.styleRules.forEach((rule) => {
// Each found atomic rule will create a new import that uses the styleSheetPath provided.
// The benefit is two fold:
// (1) thread safe collection of styles
// (2) caching -- resulting in faster builds (one import per rule!)
const params = toURIComponent(rule);
path.unshiftContainer(
'body',
template.ast(`require("${this.opts.styleSheetPath}?style=${params}");`)
);
// We use require instead of import so it works with both ESM and CJS source.
// If we used ESM it would blow up with CJS source, unfortunately.
});
}
},
},
Expand Down
4 changes: 2 additions & 2 deletions packages/babel-plugin-strip-runtime/src/types.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
export interface PluginPass {
opts: {
/**
* Will callback at the end of the file pass with all found style rules.
* Specifies the styleSheetPath used for requiring atomic styles.
*/
onFoundStyleRules?: (rules: string[]) => void;
styleSheetPath?: string;
};

/**
Expand Down
12 changes: 12 additions & 0 deletions packages/babel-plugin-strip-runtime/src/utils/to-uri-component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/**
* Escapes a CSS rule to be a valid query param.
* Also escapes escalamation marks (!) to not confuse webpack.
*
* @param rule
* @returns
*/
export const toURIComponent = (rule: string): string => {
const component = encodeURIComponent(rule).replace(/!/g, '%21');

return component;
};
2 changes: 1 addition & 1 deletion packages/babel-plugin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"@babel/traverse": "^7.17.3",
"@babel/types": "^7.17.0",
"@compiled/css": "^0.8.1",
"@compiled/utils": "^0.6.14",
"@compiled/utils": "^0.6.15",
"@emotion/is-prop-valid": "^1.1.2",
"resolve": "^1.22.0"
},
Expand Down
3 changes: 1 addition & 2 deletions packages/babel-plugin/src/babel-plugin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { declare } from '@babel/helper-plugin-utils';
import jsxSyntax from '@babel/plugin-syntax-jsx';
import template from '@babel/template';
import * as t from '@babel/types';
import { unique } from '@compiled/utils';
import { unique, preserveLeadingComments } from '@compiled/utils';

import { visitClassNamesPath } from './class-names';
import { visitCssPropPath } from './css-prop';
Expand All @@ -20,7 +20,6 @@ import {
isCompiledStyledCallExpression,
isCompiledStyledTaggedTemplateExpression,
} from './utils/is-compiled';
import { preserveLeadingComments } from './utils/preserve-leading-comments';

// eslint-disable-next-line @typescript-eslint/no-var-requires
const packageJson = require('../package.json');
Expand Down
18 changes: 0 additions & 18 deletions packages/babel-plugin/src/utils/preserve-leading-comments.tsx

This file was deleted.

0 comments on commit 588cd4f

Please sign in to comment.