diff --git a/e2e/next/src/next.test.ts b/e2e/next/src/next.test.ts index 3ae7bc43c6..9e0d4c1d2c 100644 --- a/e2e/next/src/next.test.ts +++ b/e2e/next/src/next.test.ts @@ -91,7 +91,6 @@ describe('Next.js Applications', () => { updateFile( `libs/${libName}/src/lib/${libName}.tsx`, ` - import React from 'react'; import styles from './style.module.css'; export function Test() { return
Hello
; @@ -108,7 +107,7 @@ describe('Next.js Applications', () => { await checkApp(appName, { checkUnitTest: true, checkLint: true, - checkE2E: false, + checkE2E: true, }); }, 120000); @@ -139,7 +138,7 @@ describe('Next.js Applications', () => { }); }, 120000); - it('should compile when using a workspace and react lib written in TypeScript', async () => { + fit('should compile when using a workspace and react lib written in TypeScript', async () => { const appName = uniq('app'); const tsLibName = uniq('tslib'); const tsxLibName = uniq('tsxlib'); @@ -160,7 +159,6 @@ describe('Next.js Applications', () => { updateFile( `libs/${tsxLibName}/src/lib/${tsxLibName}.tsx`, ` - import React from 'react'; interface TestComponentProps { text: string; @@ -324,7 +322,6 @@ describe('Next.js Applications', () => { updateFile( `apps/${appName}/pages/index.tsx`, ` - import React from 'react'; export function Index() { let x = ''; @@ -362,7 +359,6 @@ describe('Next.js Applications', () => { updateFile( `libs/${libName}/src/lib/${libName}.js`, ` - import React from 'react'; import styles from './style.module.css'; export function Test() { return
Hello
; diff --git a/packages/react/babel.ts b/packages/react/babel.ts index 26e1f2397c..bf0e9acf59 100644 --- a/packages/react/babel.ts +++ b/packages/react/babel.ts @@ -5,6 +5,7 @@ interface ReactBabelOptions { runtime?: string; importSource?: string; + useBuiltIns?: boolean | string; } module.exports = function (api: any, options: ReactBabelOptions) { @@ -13,7 +14,7 @@ module.exports = function (api: any, options: ReactBabelOptions) { return { presets: [ - '@nrwl/web/babel', + ['@nrwl/web/babel', { useBuiltIns: options.useBuiltIns }], [ require.resolve('@babel/preset-react'), getReactPresetOptions({ diff --git a/packages/react/src/generators/library/files/lib/.babelrc__tmpl__ b/packages/react/src/generators/library/files/lib/.babelrc__tmpl__ index c2db7bd4a9..d10d05a41f 100644 --- a/packages/react/src/generators/library/files/lib/.babelrc__tmpl__ +++ b/packages/react/src/generators/library/files/lib/.babelrc__tmpl__ @@ -2,7 +2,8 @@ "presets": [ [ "@nrwl/react/babel", { - "runtime": "automatic" + "runtime": "automatic", + "useBuiltIns": "usage" <% if (style === '@emotion/styled') { %>,"importSource": "@emotion/react" }<% } %> } ] diff --git a/packages/web/babel.spec.ts b/packages/web/babel.spec.ts deleted file mode 100644 index f2c01c5e2b..0000000000 --- a/packages/web/babel.spec.ts +++ /dev/null @@ -1,60 +0,0 @@ -const babelPreset = require('./babel'); - -describe('@nrwl/web/babel preset', () => { - it('should provide default plugin options', () => { - const apiMock = { - assertVersion: jest.fn(), - caller: jest.fn(), - }; - - const options = babelPreset(apiMock); - - expect( - findPluginOptions('@babel/plugin-proposal-decorators', options) - ).toEqual({ - legacy: true, - }); - - expect( - findPluginOptions('@babel/plugin-proposal-class-properties', options) - ).toEqual({ - loose: true, - }); - }); - - it('should allow overrides of plugin options', () => { - const apiMock = { - assertVersion: jest.fn(), - caller: jest.fn(), - }; - - const options = babelPreset(apiMock, { - decorators: { - decoratorsBeforeExport: true, - legacy: false, - }, - classProperties: { - loose: false, - }, - }); - - expect( - findPluginOptions('@babel/plugin-proposal-decorators', options) - ).toEqual({ - decoratorsBeforeExport: true, - legacy: false, - }); - - expect( - findPluginOptions('@babel/plugin-proposal-class-properties', options) - ).toEqual({ - loose: false, - }); - }); -}); - -function findPluginOptions(name: string, options: any) { - return options.plugins.find( - (x) => Array.isArray(x) && x[0].indexOf(name) !== -1 - )[1]; -} diff --git a/packages/web/babel.ts b/packages/web/babel.ts index 1e6afa11ad..81a1fdd287 100644 --- a/packages/web/babel.ts +++ b/packages/web/babel.ts @@ -1,8 +1,11 @@ +import { dirname } from 'path'; + /* * Babel preset to provide TypeScript support and module/nomodule for Nx. */ interface NxReactBabelPresetOptions { + useBuiltIns?: boolean | string; decorators?: { decoratorsBeforeExport?: boolean; legacy?: boolean; @@ -16,8 +19,13 @@ module.exports = function (api: any, options: NxReactBabelPresetOptions = {}) { api.assertVersion(7); const isModern = api.caller((caller) => caller?.isModern); + // `isServer` is passed from `next-babel-loader`, when it compiles for the server const isServer = api.caller((caller) => caller?.isServer); + + // This is set by `@nrwl/web:package` executor + const isNxPackage = api.caller((caller) => caller?.isNxPackage); + const emitDecoratorMetadata = api.caller( (caller) => caller?.emitDecoratorMetadata ?? true ); @@ -35,7 +43,7 @@ module.exports = function (api: any, options: NxReactBabelPresetOptions = {}) { : { // Allow importing core-js in entrypoint and use browserlist to select polyfills. // This is needed for differential loading as well. - useBuiltIns: 'entry', + useBuiltIns: options.useBuiltIns ?? 'entry', corejs: 3, // Do not transform modules to CJS modules: false, @@ -48,6 +56,20 @@ module.exports = function (api: any, options: NxReactBabelPresetOptions = {}) { require.resolve('@babel/preset-typescript'), ], 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') diff --git a/packages/web/package.json b/packages/web/package.json index 3b3f2e173d..8c150d3f11 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -38,6 +38,8 @@ "@babel/plugin-proposal-class-properties": "7.12.13", "@babel/plugin-proposal-decorators": "7.12.13", "@babel/plugin-transform-regenerator": "7.12.13", + "@babel/plugin-transform-runtime": "7.12.13", + "@babel/runtime": "7.12.13", "@babel/preset-typescript": "7.12.13", "@rollup/plugin-commonjs": "11.0.2", "@rollup/plugin-babel": "5.0.2", diff --git a/packages/web/src/builders/package/package.impl.ts b/packages/web/src/builders/package/package.impl.ts index 80da13f1fd..da393b9eed 100644 --- a/packages/web/src/builders/package/package.impl.ts +++ b/packages/web/src/builders/package/package.impl.ts @@ -217,6 +217,10 @@ export function createRollupOptions( extensions: fileExtensions, }), getBabelInputPlugin({ + // Let's `@nrwl/web/babel` preset know that we are packaging. + caller: { + isNxPackage: true, + }, cwd: join(context.root, sourceRoot), rootMode: 'upward', babelrc: true, diff --git a/packages/workspace/src/generators/library/files/lib/__dot__babelrc__tmpl__ b/packages/workspace/src/generators/library/files/lib/__dot__babelrc__tmpl__ index 0cae4a9a81..cf7ddd99c6 100644 --- a/packages/workspace/src/generators/library/files/lib/__dot__babelrc__tmpl__ +++ b/packages/workspace/src/generators/library/files/lib/__dot__babelrc__tmpl__ @@ -1,3 +1,3 @@ { - "presets": ["@nrwl/web/babel"] + "presets": [["@nrwl/web/babel", { "useBuiltIns": "usage" }]] }