Skip to content

Commit

Permalink
fix(react): fix external option for @emotion/react
Browse files Browse the repository at this point in the history
  • Loading branch information
puku0x committed Dec 5, 2021
1 parent 4935049 commit 10b63f0
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 3 deletions.
5 changes: 5 additions & 0 deletions packages/react/migrations.json
Expand Up @@ -104,6 +104,11 @@
"version": "13.0.0-beta.0",
"description": "Migrate Storybook to use webpack 5",
"factory": "./src/migrations/update-13-0-0/migrate-storybook-to-webpack-5"
},
"update-external-emotion-jsx-runtime-13.3.0": {
"version": "13.3.0-beta.0",
"description": "Update external option in projects for Emotion",
"factory": "./src/migrations/update-13-3-0/update-external-emotion-jsx-runtime"
}
},
"packageJsonUpdates": {
Expand Down
2 changes: 1 addition & 1 deletion packages/react/src/generators/library/library.spec.ts
Expand Up @@ -507,7 +507,7 @@ describe('lib', () => {

expect(workspaceJson.projects['my-lib'].architect.build).toMatchObject({
options: {
external: ['react/jsx-runtime', '@emotion/styled/base'],
external: ['@emotion/react/jsx-runtime'],
},
});
expect(babelrc.plugins).toEqual(['@emotion/babel-plugin']);
Expand Down
6 changes: 4 additions & 2 deletions packages/react/src/generators/library/library.ts
Expand Up @@ -173,10 +173,12 @@ function addProject(host: Tree, options: NormalizedSchema) {

if (options.publishable || options.buildable) {
const { libsDir } = getWorkspaceLayout(host);
const external = ['react/jsx-runtime'];
const external: string[] = [];

if (options.style === '@emotion/styled') {
external.push('@emotion/styled/base');
external.push('@emotion/react/jsx-runtime');
} else {
external.push('react/jsx-runtime');
}

targets.build = {
Expand Down
@@ -0,0 +1,64 @@
import {
addProjectConfiguration,
readProjectConfiguration,
} from '@nrwl/devkit';
import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';

import { updateExternalEmotionJsxRuntime } from './update-external-emotion-jsx-runtime';

describe('updateExternalEmotionJsxRuntime', () => {
it('should update external for Emotion', async () => {
// ARRANGE
const tree = createTreeWithEmptyWorkspace(2);
addProjectConfiguration(tree, 'components', {
root: 'libs/components',
targets: {
build: {
executor: '@nrwl/web:rollup',
options: {
external: ['@emotion/styled/base', 'react/jsx-runtime'],
},
},
},
});
tree.write(
'libs/components/.babelrc',
JSON.stringify({
presets: [
[
'@nrwl/react/babel',
{
runtime: 'automatic',
importSource: '@emotion/react',
},
],
],
plugins: ['@emotion/babel-plugin'],
})
);

// ACT
await updateExternalEmotionJsxRuntime(tree);

// ASSERT
const { targets } = readProjectConfiguration(tree, 'components');
expect(targets.build.options.external).toEqual([
'@emotion/react/jsx-runtime',
]);
});

it('should not fail for projects with no targets', async () => {
// ARRANGE
const tree = createTreeWithEmptyWorkspace(2);
addProjectConfiguration(tree, 'components', {
root: 'apps/components',
});

// ACT
await updateExternalEmotionJsxRuntime(tree);

// ASSERT
const { targets } = readProjectConfiguration(tree, 'components');
expect(targets).toBeUndefined();
});
});
@@ -0,0 +1,58 @@
import {
Tree,
readJson,
readProjectConfiguration,
updateProjectConfiguration,
} from '@nrwl/devkit';
import { WebPackageOptions } from '@nrwl/web/src/executors/package/schema';
import { forEachExecutorOptions } from '@nrwl/workspace/src/utilities/executor-options-utils';

export async function updateExternalEmotionJsxRuntime(tree: Tree) {
forEachExecutorOptions<WebPackageOptions>(
tree,
'@nrwl/web:rollup',
(options: any, projectName, targetName, configurationName) => {
const projectConfiguration = readProjectConfiguration(tree, projectName);

let hasEmotion = false;
const babelrcPath = `${projectConfiguration.root}/.babelrc`;
if (tree.exists(babelrcPath)) {
const babelrc = readJson(tree, 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) {
const config = configurationName
? projectConfiguration.targets[targetName].configurations[
configurationName
]
: projectConfiguration.targets[targetName].options;

if (config.external && config.external.length > 0) {
config.external.forEach((value, index) => {
if (value === 'react/jsx-runtime') {
config.external.splice(index, 1, '@emotion/react/jsx-runtime');
}
});
config.external.forEach((value, index) => {
if (value === '@emotion/styled/base') {
config.external.splice(index, 1);
}
});
}
updateProjectConfiguration(tree, projectName, projectConfiguration);
}
}
);
}

export default updateExternalEmotionJsxRuntime;

0 comments on commit 10b63f0

Please sign in to comment.