feat(react): support css prop for emotion (#7395)
* feat(react): support css prop for emotion * feat(react): add migration for css prop
This commit is contained in:
parent
7a3c485759
commit
d4f8ba2b2d
@ -92,6 +92,12 @@
|
||||
"version": "12.0.0-beta.0",
|
||||
"description": "Remove @types/react-redux from package.json since react-redux installs the package automatically now",
|
||||
"factory": "./src/migrations/update-12-0-0/remove-react-redux-types-package"
|
||||
},
|
||||
"update-emotion-setup-13.0.0": {
|
||||
"cli": "nx",
|
||||
"version": "13.0.0-beta.0",
|
||||
"description": "Update tsconfig.json to use `jsxImportSource` to support css prop",
|
||||
"factory": "./src/migrations/update-13-0-0/update-emotion-setup"
|
||||
}
|
||||
},
|
||||
"packageJsonUpdates": {
|
||||
|
||||
@ -537,6 +537,18 @@ Object {
|
||||
expect(content).toContain('<StyledApp>');
|
||||
});
|
||||
|
||||
it('should add jsxImportSource to tsconfig.json', async () => {
|
||||
await applicationGenerator(appTree, {
|
||||
...schema,
|
||||
style: '@emotion/styled',
|
||||
});
|
||||
|
||||
const tsconfigJson = readJson(appTree, 'apps/my-app/tsconfig.json');
|
||||
expect(tsconfigJson.compilerOptions['jsxImportSource']).toEqual(
|
||||
'@emotion/react'
|
||||
);
|
||||
});
|
||||
|
||||
it('should exclude styles from workspace.json', async () => {
|
||||
await applicationGenerator(appTree, {
|
||||
...schema,
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
"extends": "<%= offsetFromRoot %>tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"jsx": "react-jsx",
|
||||
<% if (style === '@emotion/styled') { %>"jsxImportSource": "@emotion/react",<% } %>
|
||||
"allowJs": true,
|
||||
"esModuleInterop": true,
|
||||
"allowSyntheticDefaultImports": true
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
"extends": "<%= offsetFromRoot %>tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"jsx": "react-jsx",
|
||||
<% if (style === '@emotion/styled') { %>"jsxImportSource": "@emotion/react",<% } %>
|
||||
"allowJs": true,
|
||||
"esModuleInterop": true,
|
||||
"allowSyntheticDefaultImports": true
|
||||
|
||||
@ -488,6 +488,7 @@ describe('lib', () => {
|
||||
|
||||
const workspaceJson = readJson(appTree, '/workspace.json');
|
||||
const babelrc = readJson(appTree, 'libs/my-lib/.babelrc');
|
||||
const tsconfigJson = readJson(appTree, 'libs/my-lib/tsconfig.json');
|
||||
|
||||
expect(workspaceJson.projects['my-lib'].architect.build).toMatchObject({
|
||||
options: {
|
||||
@ -495,6 +496,9 @@ describe('lib', () => {
|
||||
},
|
||||
});
|
||||
expect(babelrc.plugins).toEqual(['@emotion/babel-plugin']);
|
||||
expect(tsconfigJson.compilerOptions['jsxImportSource']).toEqual(
|
||||
'@emotion/react'
|
||||
);
|
||||
});
|
||||
|
||||
it('should support styled-jsx', async () => {
|
||||
|
||||
@ -0,0 +1,90 @@
|
||||
import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';
|
||||
import { readJson, Tree } from '@nrwl/devkit';
|
||||
import { updateEmotionSetup } from './update-emotion-setup';
|
||||
|
||||
describe('Update tsconfig config for Emotion', () => {
|
||||
let tree: Tree;
|
||||
|
||||
beforeEach(() => {
|
||||
tree = createTreeWithEmptyWorkspace();
|
||||
});
|
||||
|
||||
it(`should add jsxImportSource if it uses @emotion/react`, async () => {
|
||||
tree.write(
|
||||
'workspace.json',
|
||||
JSON.stringify({
|
||||
projects: {
|
||||
'no-emotion-app': {
|
||||
root: 'apps/no-emotion-app',
|
||||
projectType: 'application',
|
||||
},
|
||||
'plain-react-app': {
|
||||
root: 'apps/plain-react-app',
|
||||
projectType: 'application',
|
||||
},
|
||||
'emotion-app': {
|
||||
root: 'apps/emotion-app',
|
||||
projectType: 'application',
|
||||
},
|
||||
},
|
||||
})
|
||||
);
|
||||
tree.write(
|
||||
'nx.json',
|
||||
JSON.stringify({
|
||||
projects: {
|
||||
'no-emotion-app': {},
|
||||
'plain-react-app': {},
|
||||
'emotion-app': {},
|
||||
},
|
||||
})
|
||||
);
|
||||
tree.write('apps/no-emotion-app/.babelrc', JSON.stringify({}));
|
||||
tree.write(
|
||||
'apps/no-emotion-app/tsconfig.json',
|
||||
JSON.stringify({ compilerOptions: {} })
|
||||
);
|
||||
tree.write(
|
||||
'apps/plain-react-app/.babelrc',
|
||||
JSON.stringify({
|
||||
presets: ['@nrwl/react/babel'],
|
||||
plugins: [],
|
||||
})
|
||||
);
|
||||
tree.write(
|
||||
'apps/plain-react-app/tsconfig.json',
|
||||
JSON.stringify({ compilerOptions: { jsx: 'react-jsx' } })
|
||||
);
|
||||
tree.write(
|
||||
'apps/emotion-app/.babelrc',
|
||||
JSON.stringify({
|
||||
presets: [
|
||||
[
|
||||
'@nrwl/react/babel',
|
||||
{
|
||||
runtime: 'automatic',
|
||||
importSource: '@emotion/react',
|
||||
},
|
||||
],
|
||||
],
|
||||
plugins: ['@emotion/babel-plugin'],
|
||||
})
|
||||
);
|
||||
tree.write(
|
||||
'apps/emotion-app/tsconfig.json',
|
||||
JSON.stringify({ compilerOptions: { jsx: 'react-jsx' } })
|
||||
);
|
||||
|
||||
await updateEmotionSetup(tree);
|
||||
|
||||
expect(readJson(tree, 'apps/no-emotion-app/tsconfig.json')).toEqual({
|
||||
compilerOptions: {},
|
||||
});
|
||||
expect(readJson(tree, 'apps/plain-react-app/tsconfig.json')).toEqual({
|
||||
compilerOptions: { jsx: 'react-jsx' },
|
||||
});
|
||||
expect(readJson(tree, 'apps/emotion-app/tsconfig.json')).toEqual({
|
||||
compilerOptions: { jsx: 'react-jsx', jsxImportSource: '@emotion/react' },
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,42 @@
|
||||
import {
|
||||
formatFiles,
|
||||
getProjects,
|
||||
Tree,
|
||||
readJson,
|
||||
updateJson,
|
||||
} from '@nrwl/devkit';
|
||||
|
||||
export async function updateEmotionSetup(host: Tree) {
|
||||
const projects = getProjects(host);
|
||||
|
||||
projects.forEach((p) => {
|
||||
let hasEmotion = false;
|
||||
const babelrcPath = `${p.root}/.babelrc`;
|
||||
const tsConfigPath = `${p.root}/tsconfig.json`;
|
||||
|
||||
if (host.exists(babelrcPath)) {
|
||||
const babelrc = readJson(host, babelrcPath);
|
||||
if (babelrc.presets) {
|
||||
for (const [idx, preset] of babelrc.presets.entries()) {
|
||||
if (Array.isArray(preset)) {
|
||||
if (!preset[0].includes('@nrwl/react/babel')) continue;
|
||||
const emotionOptions = preset[1];
|
||||
hasEmotion = emotionOptions.importSource === '@emotion/react';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hasEmotion && host.exists(tsConfigPath)) {
|
||||
updateJson(host, tsConfigPath, (json) => {
|
||||
json.compilerOptions.jsxImportSource = '@emotion/react';
|
||||
return json;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
await formatFiles(host);
|
||||
}
|
||||
|
||||
export default updateEmotionSetup;
|
||||
Loading…
x
Reference in New Issue
Block a user