Skip to content

Commit

Permalink
feat(react): add Vite bundler option for buildable libraries
Browse files Browse the repository at this point in the history
  • Loading branch information
jaysoo authored and Jack Hsu committed Nov 24, 2022
1 parent 61f6e2d commit 197cc63
Show file tree
Hide file tree
Showing 34 changed files with 298 additions and 71 deletions.
15 changes: 13 additions & 2 deletions docs/generated/packages/react.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@
"type": "boolean",
"default": false
},
"skipBabelConfig": {
"description": "Do not generate a root babel.config.json (if babel is not needed).",
"type": "boolean",
"default": false
},
"js": {
"type": "boolean",
"default": false,
Expand Down Expand Up @@ -243,7 +248,7 @@
"bundler": {
"description": "The bundler to use.",
"enum": ["vite", "webpack"],
"x-prompt": "Which bundler do you want to use?",
"x-prompt": "Which bundler do you want to use to build the application?",
"default": "webpack"
}
},
Expand Down Expand Up @@ -418,11 +423,17 @@
"description": "Split the project configuration into `<projectRoot>/project.json` rather than including it inside `workspace.json`.",
"type": "boolean"
},
"bundler": {
"type": "string",
"description": "The bundler to use.",
"enum": ["vite", "rollup"],
"default": "rollup"
},
"compiler": {
"type": "string",
"enum": ["babel", "swc"],
"default": "babel",
"description": "Which compiler to use."
"description": "Which compiler to use. Does not apply if bundler is set to Vite."
},
"skipPackageJson": {
"description": "Do not add dependencies to `package.json`.",
Expand Down
6 changes: 6 additions & 0 deletions docs/generated/packages/vite.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@
"x-dropdown": "project",
"x-prompt": "What is the name of the project to set up a webpack for?"
},
"includeLib": {
"type": "boolean",
"description": "Add a library build option.",
"default": false,
"x-prompt": "Does this project contain a buildable library?"
},
"uiFramework": {
"type": "string",
"description": "UI Framework to use for Vite.",
Expand Down
5 changes: 5 additions & 0 deletions docs/generated/packages/web.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@
"description": "Do not add dependencies to `package.json`.",
"type": "boolean",
"default": false
},
"skipBabelConfig": {
"description": "Do not generate a root babel.config.json (if babel is not needed).",
"type": "boolean",
"default": false
}
},
"required": [],
Expand Down
16 changes: 16 additions & 0 deletions e2e/react/src/react-package.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -252,4 +252,20 @@ export async function h() { return 'c'; }
}).toThrow();
}, 250000);
});

it('should support bundling with Vite', async () => {
const libName = uniq('lib');

runCLI(
`generate @nrwl/react:lib ${libName} --buildable --bundler=vite --no-interactive`
);

const result = await runCLIAsync(`build ${libName}`);

expect(result).toMatch(/Vite builder finished/);
checkFilesExist(
`dist/libs/${libName}/index.js`,
`dist/libs/${libName}/index.mjs`
);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ describe('app', () => {
compiler: 'babel',
e2eTestRunner: 'cypress',
skipFormat: false,
unitTestRunner: 'jest',
name: 'myApp',
linter: Linter.EsLint,
style: 'css',
Expand Down
9 changes: 6 additions & 3 deletions packages/react/src/generators/application/application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ export async function applicationGenerator(host: Tree, schema: Schema) {
const initTask = await reactInitGenerator(host, {
...options,
skipFormat: true,
skipBabelConfig: options.bundler === 'vite',
});

tasks.push(initTask);
Expand Down Expand Up @@ -108,9 +109,11 @@ export async function applicationGenerator(host: Tree, schema: Schema) {

const cypressTask = await addCypress(host, options);
tasks.push(cypressTask);
const jestTask = await addJest(host, options);
tasks.push(jestTask);
updateSpecConfig(host, options);
if (options.unitTestRunner === 'jest') {
const jestTask = await addJest(host, options);
tasks.push(jestTask);
updateSpecConfig(host, options);
}
const styledTask = addStyledModuleDependencies(host, options.styledModule);
tasks.push(styledTask);
const routingTask = addRouting(host, options);
Expand Down
30 changes: 15 additions & 15 deletions packages/react/src/generators/application/lib/normalize-options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,20 +40,7 @@ export function normalizeOptions(

assertValidStyle(options.style);

if (options.bundler === 'vite') {
options.unitTestRunner = 'vitest';
}

options.routing = options.routing ?? false;
options.strict = options.strict ?? true;
options.classComponent = options.classComponent ?? false;
options.unitTestRunner = options.unitTestRunner ?? 'jest';
options.e2eTestRunner = options.e2eTestRunner ?? 'cypress';
options.compiler = options.compiler ?? 'babel';
options.bundler = options.bundler ?? 'webpack';
options.devServerPort ??= findFreePort(host);

return {
const normalized = {
...options,
name: names(options.name).fileName,
projectName: appProjectName,
Expand All @@ -63,5 +50,18 @@ export function normalizeOptions(
fileName,
styledModule,
hasStyles: options.style !== 'none',
};
} as NormalizedSchema;

normalized.routing = normalized.routing ?? false;
normalized.strict = normalized.strict ?? true;
normalized.classComponent = normalized.classComponent ?? false;
normalized.compiler = normalized.compiler ?? 'babel';
normalized.bundler = normalized.bundler ?? 'webpack';
normalized.unitTestRunner =
normalized.unitTestRunner ??
(normalized.bundler === 'vite' ? 'vitest' : 'jest');
normalized.e2eTestRunner = normalized.e2eTestRunner ?? 'cypress';
normalized.devServerPort ??= findFreePort(host);

return normalized;
}
2 changes: 2 additions & 0 deletions packages/react/src/generators/application/lib/set-defaults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export function setDefaults(host: Tree, options: NormalizedSchema) {
style: options.style,
unitTestRunner: options.unitTestRunner,
linter: options.linter,
bundler: options.bundler,
...prev.application,
},
component: {
Expand All @@ -40,6 +41,7 @@ export function setDefaults(host: Tree, options: NormalizedSchema) {
style: options.style,
unitTestRunner: options.unitTestRunner,
linter: options.linter,
bundler: options.bundler,
...prev.library,
},
},
Expand Down
3 changes: 2 additions & 1 deletion packages/react/src/generators/application/schema.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export interface Schema {
skipFormat: boolean;
directory?: string;
tags?: string;
unitTestRunner: 'jest' | 'vitest' | 'none';
unitTestRunner?: 'jest' | 'vitest' | 'none';
inSourceTests?: boolean;
/**
* @deprecated
Expand Down Expand Up @@ -41,4 +41,5 @@ export interface NormalizedSchema extends Schema {
fileName: string;
styledModule: null | SupportedStyles;
hasStyles: boolean;
unitTestRunner: 'jest' | 'vitest' | 'none';
}
2 changes: 1 addition & 1 deletion packages/react/src/generators/application/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@
"bundler": {
"description": "The bundler to use.",
"enum": ["vite", "webpack"],
"x-prompt": "Which bundler do you want to use?",
"x-prompt": "Which bundler do you want to use to build the application?",
"default": "webpack"
}
},
Expand Down
1 change: 1 addition & 0 deletions packages/react/src/generators/init/schema.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export interface InitSchema {
unitTestRunner?: 'jest' | 'vitest' | 'none';
e2eTestRunner?: 'cypress' | 'none';
skipBabelConfig?: boolean;
skipFormat?: boolean;
skipPackageJson?: boolean;
js?: boolean;
Expand Down
5 changes: 5 additions & 0 deletions packages/react/src/generators/init/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@
"type": "boolean",
"default": false
},
"skipBabelConfig": {
"description": "Do not generate a root babel.config.json (if babel is not needed).",
"type": "boolean",
"default": false
},
"js": {
"type": "boolean",
"default": false,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "<%= name %>",
"version": "0.0.1",
"main": "./index.js",
"module": "./index.mjs",
"exports": {
".": {
"import": "./index.mjs",
"require": "./index.js"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title><%= className %> Demo</title>
<base href="/" />

<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" type="image/x-icon" href="favicon.ico" />
</head>
<body>
<div id="root"></div>
<script type="module" src="./src/demo.tsx"></script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* This a a demo file that can be helpful when developing components by serving and interacting with them in the browser.
*/
<% if (component) { %>
import * as ReactDOM from 'react-dom/client';
import { <%= className %> } from './index';

const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement);
root.render(
<<%= className %> />
);
<% } else { %>
import * as ReactDOM from 'react-dom/client';

const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement);
root.render(
<h1><%= className %> Demo</h1>
);
<% } %>
9 changes: 8 additions & 1 deletion packages/react/src/generators/library/library.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,11 @@ describe('lib', () => {
`);
});
it('should update jest.config.ts for babel', async () => {
await libraryGenerator(appTree, { ...defaultSchema, compiler: 'babel' });
await libraryGenerator(appTree, {
...defaultSchema,
buildable: true,
compiler: 'babel',
});
expect(appTree.read('libs/my-lib/jest.config.ts', 'utf-8')).toContain(
"['babel-jest', { presets: ['@nrwl/react/babel'] }]"
);
Expand Down Expand Up @@ -280,6 +284,7 @@ describe('lib', () => {
await libraryGenerator(appTree, {
...defaultSchema,
directory: 'myDir',
buildable: true,
compiler: 'babel',
});
expect(
Expand Down Expand Up @@ -725,6 +730,7 @@ describe('lib', () => {
it('should install swc dependencies if needed', async () => {
await libraryGenerator(appTree, {
...defaultSchema,
buildable: true,
compiler: 'swc',
});
const packageJson = readJson(appTree, 'package.json');
Expand Down Expand Up @@ -764,6 +770,7 @@ describe('lib', () => {
await libraryGenerator(appTree, {
...defaultSchema,
style,
compiler: 'babel',
name: 'myLib',
});

Expand Down
Loading

0 comments on commit 197cc63

Please sign in to comment.