Skip to content

Commit

Permalink
fix(react): add missing polyfills for apps using babel.
Browse files Browse the repository at this point in the history
Closes #1668
  • Loading branch information
jaysoo authored and vsavkin committed Jul 30, 2019
1 parent 9beafb1 commit 790f174
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 14 deletions.
2 changes: 2 additions & 0 deletions packages/react/src/plugins/babel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ export function getBabelWebpackConfig(config: Configuration) {
[
require('@babel/preset-env').default,
{
// Allow importing core-js in entrypoint and use browserlist to select polyfills
useBuiltIns: 'entry',
modules: false,
// Exclude transforms that make all code slower
exclude: ['transform-typeof-symbol']
Expand Down
17 changes: 17 additions & 0 deletions packages/react/src/schematics/application/application.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -482,5 +482,22 @@ describe('app', () => {
workspaceJson.projects['my-app'].architect.build.options.webpackConfig
).toEqual('@nrwl/react/plugins/babel');
});

it('should add required polyfills for core-js and regenerator', async () => {
const tree = await runSchematic(
'app',
{ name: 'myApp', babel: true },
appTree
);
const packageJSON = readJsonInTree(tree, 'package.json');
const polyfillsSource = tree
.read('apps/my-app/src/polyfills.ts')
.toString();

expect(packageJSON.devDependencies['core-js']).toBeDefined();
expect(packageJSON.devDependencies['regenerator-runtime']).toBeDefined();
expect(polyfillsSource).toContain('regenerator');
expect(polyfillsSource).toContain('core-js');
});
});
});
69 changes: 55 additions & 14 deletions packages/react/src/schematics/application/application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,13 @@ import {
toFileName,
updateJsonInTree,
generateProjectLint,
addLintFiles
addLintFiles,
toPropertyName,
addGlobal
} from '@nrwl/workspace';
import {
addDepsToPackageJson,
insertImport,
updateWorkspaceInTree
} from '@nrwl/workspace/src/utils/ast-utils';
import ngAdd from '../ng-add/ng-add';
Expand All @@ -41,8 +44,11 @@ import {
babelPresetEnvVersion,
babelPresetReactVersion,
babelPresetTypeScriptVersion,
reactRouterVersion
coreJsVersion,
reactRouterVersion,
regeneratorVersion
} from '../../utils/versions';
import { addImportToModule } from '../../../../angular/src/utils/ast-utils';

interface NormalizedSchema extends Schema {
projectName: string;
Expand Down Expand Up @@ -240,21 +246,56 @@ function addRouting(options: NormalizedSchema): Rule {

function addBabel(options: NormalizedSchema): Rule {
return options.babel
? addDepsToPackageJson(
{},
{
'@babel/core': babelCoreVersion,
'@babel/preset-env': babelPresetEnvVersion,
'@babel/preset-react': babelPresetReactVersion,
'@babel/preset-typescript': babelPresetTypeScriptVersion,
'@babel/plugin-proposal-decorators': babelPluginDecoratorsVersion,
'babel-loader': babelLoaderVersion,
'babel-plugin-macros': babelPluginMacrosVersion
}
)
? chain([
addDepsToPackageJson(
{},
{
'@babel/core': babelCoreVersion,
'@babel/preset-env': babelPresetEnvVersion,
'@babel/preset-react': babelPresetReactVersion,
'@babel/preset-typescript': babelPresetTypeScriptVersion,
'@babel/plugin-proposal-decorators': babelPluginDecoratorsVersion,
'babel-loader': babelLoaderVersion,
'babel-plugin-macros': babelPluginMacrosVersion,
'core-js': coreJsVersion,
'regenerator-runtime': regeneratorVersion
}
),
addPolyfillForBabel(options)
])
: noop();
}

function addPolyfillForBabel(options: NormalizedSchema): Rule {
return (host: Tree) => {
const polyfillsPath = join(options.appProjectRoot, `src/polyfills.ts`);
const polyfillsSource = host.read(polyfillsPath)!.toString('utf-8');
const polyfillsSourceFile = ts.createSourceFile(
polyfillsPath,
polyfillsSource,
ts.ScriptTarget.Latest,
true
);

insert(host, polyfillsPath, [
...addGlobal(
polyfillsSourceFile,
polyfillsPath,
`
/*
* Polyfill stable language features.
* It's recommended to use @babel/preset-env and browserslist
* to only include the polyfills necessary for the target browsers.
*/
import 'core-js/stable';
import 'regenerator-runtime/runtime';
`
)
]);
};
}

function normalizeOptions(host: Tree, options: Schema): NormalizedSchema {
const appDirectory = options.directory
? `${toFileName(options.directory)}/${toFileName(options.name)}`
Expand Down
2 changes: 2 additions & 0 deletions packages/react/src/utils/versions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,5 @@ export const babelPresetTypeScriptVersion = '7.3.3';
export const babelPluginDecoratorsVersion = '7.4.4';
export const babelLoaderVersion = '8.0.6';
export const babelPluginMacrosVersion = '2.6.1';
export const coreJsVersion = '3.1.4';
export const regeneratorVersion = '0.13.3';

0 comments on commit 790f174

Please sign in to comment.