feat(js): move babel preset to @nrwl/js/babel so @nrwl/web is not… (#14478)

This commit is contained in:
Jack Hsu 2023-01-23 10:32:07 -05:00 committed by GitHub
parent ef3d5de759
commit 5e11adbba4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 266 additions and 132 deletions

View File

@ -38,7 +38,7 @@ describe('js e2e', () => {
const babelRc = readJson(`libs/${lib}/.babelrc`); const babelRc = readJson(`libs/${lib}/.babelrc`);
expect(babelRc.plugins).toBeUndefined(); expect(babelRc.plugins).toBeUndefined();
expect(babelRc.presets).toStrictEqual([ expect(babelRc.presets).toStrictEqual([
['@nrwl/web/babel', { useBuiltIns: 'usage' }], ['@nrwl/js/babel', { useBuiltIns: 'usage' }],
]); ]);
expect(runCLI(`build ${lib}`)).toContain('Done compiling TypeScript files'); expect(runCLI(`build ${lib}`)).toContain('Done compiling TypeScript files');

View File

@ -160,8 +160,8 @@ function updateDependencies(tree: Tree, options: NormalizedSchema) {
if (options.compiler === 'babel' || options.babelJest) { if (options.compiler === 'babel' || options.babelJest) {
devDeps['babel-jest'] = babelJestVersion; devDeps['babel-jest'] = babelJestVersion;
// in some cases @nrwl/web will not already be present i.e. node only projects // in some cases @nrwl/js will not already be present i.e. node only projects
devDeps['@nrwl/web'] = nxVersion; devDeps['@nrwl/js'] = nxVersion;
} else if (options.compiler === 'swc') { } else if (options.compiler === 'swc') {
devDeps['@swc/jest'] = swcJestVersion; devDeps['@swc/jest'] = swcJestVersion;
} }

110
packages/js/babel.ts Normal file
View File

@ -0,0 +1,110 @@
import { dirname } from 'path';
/*
* Babel preset to provide TypeScript support and module/nomodule for Nx.
*/
export interface NxWebBabelPresetOptions {
useBuiltIns?: boolean | string;
decorators?: {
decoratorsBeforeExport?: boolean;
legacy?: boolean;
};
classProperties?: {
loose?: boolean;
};
}
module.exports = function (api: any, options: NxWebBabelPresetOptions = {}) {
api.assertVersion(7);
const isModern = api.caller((caller) => caller?.isModern);
// This is set by `@nrwl/web:rollup` executor
const isNxPackage = api.caller((caller) => caller?.isNxPackage);
const emitDecoratorMetadata = api.caller(
(caller) => caller?.emitDecoratorMetadata ?? true
);
// Determine settings for `@babel/plugin-proposal-class-properties`,
// so that we can sync the `loose` option with `@babel/preset-env`.
const classProperties = options.classProperties ?? { loose: true };
return {
presets: [
// Support module/nomodule pattern.
[
require.resolve('@babel/preset-env'),
// For Jest tests, NODE_ENV is set as 'test' and we only want to set target as Node.
// All other options will fail in Jest since Node does not support some ES features
// such as import syntax.
process.env.NODE_ENV === 'test'
? { targets: { node: 'current' }, loose: true }
: {
// Allow importing core-js in entrypoint and use browserlist to select polyfills.
useBuiltIns: options.useBuiltIns ?? 'entry',
corejs: 3,
// Do not transform modules to CJS
modules: false,
targets: isModern ? { esmodules: 'intersect' } : undefined,
bugfixes: true,
// Exclude transforms that make all code slower
exclude: ['transform-typeof-symbol'],
// This must match the setting for `@babel/plugin-proposal-class-properties`
loose: classProperties.loose,
},
],
[
require.resolve('@babel/preset-typescript'),
{
allowDeclareFields: true,
},
],
],
plugins: [
!isNxPackage
? [
require.resolve('@babel/plugin-transform-runtime'),
{
corejs: false,
helpers: true,
regenerator: true,
useESModules: isModern,
absoluteRuntime: dirname(
require.resolve('@babel/runtime/package.json')
),
},
]
: null,
require.resolve('babel-plugin-macros'),
emitDecoratorMetadata
? require.resolve('babel-plugin-transform-typescript-metadata')
: undefined,
// Must use legacy decorators to remain compatible with TypeScript.
[
require.resolve('@babel/plugin-proposal-decorators'),
options.decorators ?? { legacy: true },
],
[
require.resolve('@babel/plugin-proposal-class-properties'),
classProperties,
],
].filter(Boolean),
overrides: [
// Convert `const enum` to `enum`. The former cannot be supported by babel
// but at least we can get it to not error out.
{
test: /\.tsx?$/,
plugins: [
[
require.resolve('babel-plugin-const-enum'),
{
transform: 'removeConst',
},
],
],
},
],
};
};

View File

@ -32,9 +32,19 @@
"executors": "./executors.json", "executors": "./executors.json",
"builders": "./executors.json", "builders": "./executors.json",
"dependencies": { "dependencies": {
"@babel/core": "^7.15.0",
"@babel/plugin-proposal-class-properties": "^7.14.5",
"@babel/plugin-proposal-decorators": "^7.14.5",
"@babel/plugin-transform-runtime": "^7.15.0",
"@babel/preset-env": "^7.15.0",
"@babel/preset-typescript": "^7.15.0",
"@babel/runtime": "^7.14.8",
"@nrwl/devkit": "file:../devkit", "@nrwl/devkit": "file:../devkit",
"@nrwl/linter": "file:../linter", "@nrwl/linter": "file:../linter",
"@nrwl/workspace": "file:../workspace", "@nrwl/workspace": "file:../workspace",
"babel-plugin-const-enum": "^1.0.1",
"babel-plugin-macros": "^2.8.0",
"babel-plugin-transform-typescript-metadata": "^0.3.1",
"chalk": "^4.1.0", "chalk": "^4.1.0",
"fast-glob": "3.2.7", "fast-glob": "3.2.7",
"fs-extra": "^11.1.0", "fs-extra": "^11.1.0",

View File

@ -917,7 +917,7 @@ describe('lib', () => {
Object { Object {
"presets": Array [ "presets": Array [
Array [ Array [
"@nrwl/web/babel", "@nrwl/js/babel",
Object { Object {
"useBuiltIns": "usage", "useBuiltIns": "usage",
}, },
@ -950,7 +950,7 @@ describe('lib', () => {
Object { Object {
"presets": Array [ "presets": Array [
Array [ Array [
"@nrwl/web/babel", "@nrwl/js/babel",
Object { Object {
"useBuiltIns": "usage", "useBuiltIns": "usage",
}, },

View File

@ -256,7 +256,7 @@ function addBabelRc(tree: Tree, options: NormalizedSchema) {
const filename = '.babelrc'; const filename = '.babelrc';
const babelrc = { const babelrc = {
presets: [['@nrwl/web/babel', { useBuiltIns: 'usage' }]], presets: [['@nrwl/js/babel', { useBuiltIns: 'usage' }]],
}; };
writeJson(tree, join(options.projectRoot, filename), babelrc); writeJson(tree, join(options.projectRoot, filename), babelrc);

View File

@ -1,12 +1,18 @@
import type { NxWebBabelPresetOptions } from '@nrwl/web';
/* /*
* Babel preset to provide React support for Nx. * Babel preset to provide React support for Nx.
*/ */
interface NxReactBabelOptions extends NxWebBabelPresetOptions { interface NxReactBabelOptions {
runtime?: string; runtime?: string;
importSource?: string; importSource?: string;
useBuiltIns?: boolean | string;
decorators?: {
decoratorsBeforeExport?: boolean;
legacy?: boolean;
};
classProperties?: {
loose?: boolean;
};
} }
module.exports = function (api: any, options: NxReactBabelOptions) { module.exports = function (api: any, options: NxReactBabelOptions) {
@ -17,7 +23,7 @@ module.exports = function (api: any, options: NxReactBabelOptions) {
*/ */
const isNextJs = api.caller((caller) => caller?.pagesDir); const isNextJs = api.caller((caller) => caller?.pagesDir);
const presets: any[] = [['@nrwl/web/babel', options]]; const presets: any[] = [['@nrwl/js/babel', options]];
/** /**
* Next.js already includes the preset-react, and including it * Next.js already includes the preset-react, and including it

View File

@ -238,7 +238,7 @@ export function createRollupOptions(
useSwc && swc(), useSwc && swc(),
useBabel && useBabel &&
getBabelInputPlugin({ getBabelInputPlugin({
// Let's `@nrwl/web/babel` preset know that we are packaging. // Lets `@nrwl/js/babel` preset know that we are packaging.
caller: { caller: {
// @ts-ignore // @ts-ignore
// Ignoring type checks for caller since we have custom attributes // Ignoring type checks for caller since we have custom attributes

View File

@ -1,110 +1,9 @@
import { dirname } from 'path'; const nxJsBabelPreset = require('@nrwl/js/babel');
/* /** @deprecated Use `@nrwl/js/babel`. */
* Babel preset to provide TypeScript support and module/nomodule for Nx. module.exports = function (api: any, options: any = {}) {
*/ console.warn(
'`@nrwl/web/babel` has been deprecated. Use `@nrwl/js/babel` instead in your .babelrc files.'
export interface NxWebBabelPresetOptions {
useBuiltIns?: boolean | string;
decorators?: {
decoratorsBeforeExport?: boolean;
legacy?: boolean;
};
classProperties?: {
loose?: boolean;
};
}
module.exports = function (api: any, options: NxWebBabelPresetOptions = {}) {
api.assertVersion(7);
const isModern = api.caller((caller) => caller?.isModern);
// This is set by `@nrwl/web:rollup` executor
const isNxPackage = api.caller((caller) => caller?.isNxPackage);
const emitDecoratorMetadata = api.caller(
(caller) => caller?.emitDecoratorMetadata ?? true
); );
return nxJsBabelPreset(api, options);
// Determine settings for `@babel/plugin-proposal-class-properties`,
// so that we can sync the `loose` option with `@babel/preset-env`.
const classProperties = options.classProperties ?? { loose: true };
return {
presets: [
// Support module/nomodule pattern.
[
require.resolve('@babel/preset-env'),
// For Jest tests, NODE_ENV is set as 'test' and we only want to set target as Node.
// All other options will fail in Jest since Node does not support some ES features
// such as import syntax.
process.env.NODE_ENV === 'test'
? { targets: { node: 'current' }, loose: true }
: {
// Allow importing core-js in entrypoint and use browserlist to select polyfills.
useBuiltIns: options.useBuiltIns ?? 'entry',
corejs: 3,
// Do not transform modules to CJS
modules: false,
targets: isModern ? { esmodules: 'intersect' } : undefined,
bugfixes: true,
// Exclude transforms that make all code slower
exclude: ['transform-typeof-symbol'],
// This must match the setting for `@babel/plugin-proposal-class-properties`
loose: classProperties.loose,
},
],
[
require.resolve('@babel/preset-typescript'),
{
allowDeclareFields: true,
},
],
],
plugins: [
!isNxPackage
? [
require.resolve('@babel/plugin-transform-runtime'),
{
corejs: false,
helpers: true,
regenerator: true,
useESModules: isModern,
absoluteRuntime: dirname(
require.resolve('@babel/runtime/package.json')
),
},
]
: null,
require.resolve('babel-plugin-macros'),
emitDecoratorMetadata
? require.resolve('babel-plugin-transform-typescript-metadata')
: undefined,
// Must use legacy decorators to remain compatible with TypeScript.
[
require.resolve('@babel/plugin-proposal-decorators'),
options.decorators ?? { legacy: true },
],
[
require.resolve('@babel/plugin-proposal-class-properties'),
classProperties,
],
].filter(Boolean),
overrides: [
// Convert `const enum` to `enum`. The former cannot be supported by babel
// but at least we can get it to not error out.
{
test: /\.tsx?$/,
plugins: [
[
require.resolve('babel-plugin-const-enum'),
{
transform: 'removeConst',
},
],
],
},
],
};
}; };

View File

@ -1,3 +1,2 @@
export { webInitGenerator } from './src/generators/init/init'; export { webInitGenerator } from './src/generators/init/init';
export { applicationGenerator } from './src/generators/application/application'; export { applicationGenerator } from './src/generators/application/application';
export type { NxWebBabelPresetOptions } from './babel';

View File

@ -47,6 +47,12 @@
"version": "15.0.0-beta.1", "version": "15.0.0-beta.1",
"description": "Update usages of rollup executors to @nrwl/rollup", "description": "Update usages of rollup executors to @nrwl/rollup",
"factory": "./src/migrations/update-15-0-0/update-rollup-executor" "factory": "./src/migrations/update-15-0-0/update-rollup-executor"
},
"update-babel-preset": {
"cli": "nx",
"version": "15.5.4-beta.0",
"description": "Update `@nrwl/web/babel` preset to `@nrwl/js/babel` for projects that have a .babelrc file.",
"factory": "./src/migrations/update-15-5-4/update-babel-preset"
} }
}, },
"packageJsonUpdates": { "packageJsonUpdates": {

View File

@ -30,13 +30,6 @@
"migrations": "./migrations.json" "migrations": "./migrations.json"
}, },
"dependencies": { "dependencies": {
"@babel/core": "^7.15.0",
"@babel/plugin-proposal-class-properties": "^7.14.5",
"@babel/plugin-proposal-decorators": "^7.14.5",
"@babel/plugin-transform-runtime": "^7.15.0",
"@babel/preset-env": "^7.15.0",
"@babel/preset-typescript": "^7.15.0",
"@babel/runtime": "^7.14.8",
"@nrwl/cypress": "file:../cypress", "@nrwl/cypress": "file:../cypress",
"@nrwl/devkit": "file:../devkit", "@nrwl/devkit": "file:../devkit",
"@nrwl/jest": "file:../jest", "@nrwl/jest": "file:../jest",
@ -44,9 +37,6 @@
"@nrwl/linter": "file:../linter", "@nrwl/linter": "file:../linter",
"@nrwl/rollup": "file:../rollup", "@nrwl/rollup": "file:../rollup",
"@nrwl/workspace": "file:../workspace", "@nrwl/workspace": "file:../workspace",
"babel-plugin-const-enum": "^1.0.1",
"babel-plugin-macros": "^2.8.0",
"babel-plugin-transform-typescript-metadata": "^0.3.1",
"chalk": "^4.1.0", "chalk": "^4.1.0",
"chokidar": "^3.5.1", "chokidar": "^3.5.1",
"http-server": "^14.1.0", "http-server": "^14.1.0",

View File

@ -1,5 +1,5 @@
{ {
"presets": [ "presets": [
"@nrwl/web/babel" "@nrwl/js/babel"
] ]
} }

View File

@ -1,5 +1,5 @@
{ {
"presets": [ "presets": [
"@nrwl/web/babel" "@nrwl/js/babel"
] ]
} }

View File

@ -0,0 +1,67 @@
import {
addProjectConfiguration,
readJson,
Tree,
writeJson,
} from '@nrwl/devkit';
import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';
import update from './update-babel-preset';
describe('update-babel-preset', () => {
let tree: Tree;
beforeEach(() => {
tree = createTreeWithEmptyWorkspace();
});
it('should update preset with options', async () => {
addProjectConfiguration(tree, 'demo', {
root: 'demo',
});
writeJson(tree, 'demo/.babelrc', {
presets: [
'@acme/foo',
[
'@nrwl/web/babel',
{
useBuiltIns: 'usage',
},
],
'@acme/bar',
],
});
await update(tree);
const result = readJson(tree, 'demo/.babelrc');
expect(result).toEqual({
presets: [
'@acme/foo',
[
'@nrwl/js/babel',
{
useBuiltIns: 'usage',
},
],
'@acme/bar',
],
});
});
it('should update preset without options', async () => {
addProjectConfiguration(tree, 'demo', {
root: 'demo',
});
writeJson(tree, 'demo/.babelrc', {
presets: ['@acme/foo', '@nrwl/web/babel', '@acme/bar'],
});
await update(tree);
const result = readJson(tree, 'demo/.babelrc');
expect(result).toEqual({
presets: ['@acme/foo', '@nrwl/js/babel', '@acme/bar'],
});
});
});

View File

@ -0,0 +1,47 @@
import {
readJson,
writeJson,
Tree,
addDependenciesToPackageJson,
getProjects,
joinPathFragments,
} from '@nrwl/devkit';
import { nxVersion } from '../../utils/versions';
/* Updates @nrwl/web/babel to @nrwl/js/babel because web package is no longer necessary to use webpack/rollup + babel. */
export default async function update(tree: Tree) {
// Add `@nrwl/js` in case it was missing before.
addDependenciesToPackageJson(
tree,
{},
{
'@nrwl/js': nxVersion,
}
);
const projects = getProjects(tree);
projects.forEach((config, name) => {
const babelrcPath = joinPathFragments(config.root, '.babelrc');
if (!tree.exists(babelrcPath)) return;
const babelrc = readJson(tree, babelrcPath);
const idx = babelrc?.presets?.findIndex((p) =>
typeof p === 'string'
? p === '@nrwl/web/babel'
: p[0] === '@nrwl/web/babel'
);
if (idx === -1) return;
const preset = babelrc.presets[idx];
if (typeof preset === 'string') {
babelrc.presets.splice(idx, 1, '@nrwl/js/babel');
} else if (Array.isArray(preset)) {
babelrc.presets.splice(idx, 1, ['@nrwl/js/babel', preset[1]]);
}
writeJson(tree, babelrcPath, babelrc);
});
}

View File

@ -1,3 +1,3 @@
{ {
"presets": [["@nrwl/web/babel", { "useBuiltIns": "usage" }]] "presets": [["@nrwl/js/babel", { "useBuiltIns": "usage" }]]
} }