Skip to content

Commit

Permalink
fix(react): add migrations to fix babel setup for workspaces using re…
Browse files Browse the repository at this point in the history
…act, next.js, and gatsby (#5041)
  • Loading branch information
jaysoo authored and FrozenPandaz committed Mar 19, 2021
1 parent 34710a5 commit 27f168e
Show file tree
Hide file tree
Showing 10 changed files with 443 additions and 135 deletions.
18 changes: 18 additions & 0 deletions packages/web/migrations.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,24 @@
"version": "9.2.0-beta.1",
"description": "Set buildLibsFromSource property to true to not break existing projects.",
"factory": "./src/migrations/update-9-2-0/set-build-libs-from-source"
},
"update-root-babel-config-11-5-2": {
"cli": "nx",
"version": "11.5.2-beta.1",
"description": "Remove presets from the root babel.config.json file to prevent conflicts with babel presets used in apps.",
"factory": "./src/migrations/update-11-5-2/update-root-babel-config"
},
"create-babelrc-for-workspace-libs-11-5-2": {
"cli": "nx",
"version": "11.5.2-beta.1",
"description": "Create .babelrc files for workspace libs to fix compatibility with the new babel.config.json setup.",
"factory": "./src/migrations/update-11-5-2/create-babelrc-for-workspace-libs"
},
"update-existing-babelrc-files-11-5-2": {
"cli": "nx",
"version": "11.5.2-beta.1",
"description": "Update existing .babelrc files to add missing '@nrwl/web/babel' preset if necessary.",
"factory": "./src/migrations/update-11-5-2/update-existing-babelrc-files"
}
}
}
117 changes: 0 additions & 117 deletions packages/web/src/migrations/update-11-5-0/update-babel-config.spec.ts

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';
import { readJson, Tree } from '@nrwl/devkit';
import { createBabelrcForWorkspaceLibs } from './create-babelrc-for-workspace-libs';

describe('Create missing .babelrc files', () => {
let tree: Tree;

beforeEach(async () => {
tree = createTreeWithEmptyWorkspace();
});

it(`should create .babelrc files for libs that are used in '@nrwl/web:build'`, async () => {
tree.write(
'workspace.json',
JSON.stringify({
projects: {
webapp: {
root: 'apps/webapp',
projectType: 'application',
targets: {
build: { executor: '@nrwl/web:build' },
},
},
nodeapp: {
root: 'apps/nodeapp',
projectType: 'application',
targets: {
build: { executor: '@nrwl/node:build' },
},
},
weblib: {
root: 'libs/weblib',
projectType: 'library',
},
nodelib: {
root: 'libs/nodelib',
projectType: 'library',
},
},
})
);
tree.write(
'nx.json',
JSON.stringify({
npmScope: 'proj',
projects: {
webapp: {},
nodeapp: {},
weblib: {},
nodelib: {},
},
})
);
tree.write('apps/webapp/index.ts', `import '@proj/weblib';`);

await createBabelrcForWorkspaceLibs(tree);

expect(readJson(tree, 'libs/weblib/.babelrc')).toMatchObject({
presets: ['@nrwl/web/babel'],
});

expect(tree.exists('libs/nodelib/.babelrc')).toBeFalsy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { formatFiles, getProjects, Tree } from '@nrwl/devkit';
import { reverse } from '@nrwl/workspace/src/core/project-graph';
import { createProjectGraphFromTree } from '@nrwl/workspace/src/utilities/create-project-graph-from-tree';
import { hasDependentAppUsingWebBuild } from '@nrwl/web/src/migrations/update-11-5-2/utils';

export async function createBabelrcForWorkspaceLibs(host: Tree) {
const projects = getProjects(host);
const graph = reverse(createProjectGraphFromTree(host));

for (const [name, p] of projects.entries()) {
if (!hasDependentAppUsingWebBuild(name, graph, projects)) {
continue;
}

const babelrcPath = `${p.root}/.babelrc`;
if (p.projectType === 'library' && !host.exists(babelrcPath)) {
// Library is included in applications that require .babelrc to
// exist and contain '@nrwl/web/babel' preset.
host.write(
babelrcPath,
JSON.stringify({ presets: ['@nrwl/web/babel'] }, null, 2)
);
}
}

await formatFiles(host);
}

export default createBabelrcForWorkspaceLibs;
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';
import { readJson, Tree } from '@nrwl/devkit';
import { updateExistingBabelrcFiles } from './update-existing-babelrc-files';

describe('Create missing .babelrc files', () => {
let tree: Tree;

beforeEach(async () => {
tree = createTreeWithEmptyWorkspace();
});

it(`should add web babel preset if it does not exist`, async () => {
tree.write(
'workspace.json',
JSON.stringify({
projects: {
'missing-babel-presets': {
root: 'apps/missing-babel-presets',
projectType: 'application',
},
'web-app': {
root: 'apps/web-app',
projectType: 'application',
},
'react-app': {
root: 'apps/react-app',
projectType: 'application',
},
'gatsby-app': {
root: 'apps/gatsby-app',
projectType: 'application',
},
'not-using-babel': {
root: 'apps/not-using-babel',
projectType: 'application',
},
'next-app': {
root: 'apps/next-app',
projectType: 'application',
},
},
})
);
tree.write(
'nx.json',
JSON.stringify({
projects: {
'missing-babel-presets': {},
'web-app': {},
'react-app': {},
'gatsby-app': {},
'not-using-babel': {},
'next-app': {},
},
})
);
tree.write(
'babel.config.json',
JSON.stringify({
presets: ['@nrwl/web/babel'],
})
);
tree.write('apps/missing-babel-presets/.babelrc', JSON.stringify({}));
tree.write(
'apps/web-app/.babelrc',
JSON.stringify({ presets: ['@nrwl/web/babel'] })
);
tree.write(
'apps/react-app/.babelrc',
JSON.stringify({ presets: ['@nrwl/react/babel'] })
);
tree.write(
'apps/gatsby-app/.babelrc',
JSON.stringify({ presets: ['@nrwl/gatsby/babel'] })
);
tree.write(
'apps/next-app/.babelrc',
JSON.stringify({ presets: ['@nrwl/next/babel'] })
);

await updateExistingBabelrcFiles(tree);

expect(readJson(tree, 'apps/missing-babel-presets/.babelrc')).toMatchObject(
{
presets: ['@nrwl/web/babel'],
}
);

expect(readJson(tree, 'apps/web-app/.babelrc')).toMatchObject({
presets: ['@nrwl/web/babel'],
});

expect(readJson(tree, 'apps/react-app/.babelrc')).toMatchObject({
presets: ['@nrwl/react/babel'],
});

expect(readJson(tree, 'apps/gatsby-app/.babelrc')).toMatchObject({
presets: ['@nrwl/gatsby/babel'],
});

expect(tree.exists('apps/not-using-babel/.babelrc')).not.toBeTruthy();

expect(readJson(tree, 'apps/next-app/.babelrc')).toMatchObject({
presets: ['@nrwl/next/babel'],
});
});
});
Original file line number Diff line number Diff line change
@@ -1,17 +1,8 @@
import { formatFiles, getProjects, Tree, updateJson } from '@nrwl/devkit';

export async function updateBabelConfig(host: Tree) {
export async function updateExistingBabelrcFiles(host: Tree) {
const projects = getProjects(host);

if (host.exists('babel.config.json')) {
updateJson(host, 'babel.config.json', (json) => {
if (Array.isArray(json.presets)) {
json.presets = json.presets.filter((x) => x !== '@nrwl/web/babel');
}
return json;
});
}

projects.forEach((p) => {
const babelrcPath = `${p.root}/.babelrc`;

Expand All @@ -34,17 +25,10 @@ export async function updateBabelConfig(host: Tree) {
}
return json;
});
// Non-buildable libraries might be included in applications that
// require .babelrc to exist and contain '@nrwl/web/babel' preset
} else if (p.projectType === 'library') {
host.write(
babelrcPath,
JSON.stringify({ presets: ['@nrwl/web/babel'] }, null, 2)
);
}
});

await formatFiles(host);
}

export default updateBabelConfig;
export default updateExistingBabelrcFiles;
Loading

0 comments on commit 27f168e

Please sign in to comment.