fix(react): add missing style preprocessors when using Vite (#13600)
This commit is contained in:
parent
3e2b8d987f
commit
67c7822ad3
@ -124,6 +124,12 @@
|
|||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"default": false,
|
"default": false,
|
||||||
"description": "Skip generating a vite config file"
|
"description": "Skip generating a vite config file"
|
||||||
|
},
|
||||||
|
"coverageProvider": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["c8", "istanbul"],
|
||||||
|
"default": "c8",
|
||||||
|
"description": "Coverage provider to use."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": ["project"],
|
"required": ["project"],
|
||||||
|
|||||||
@ -970,7 +970,8 @@ describe('app', () => {
|
|||||||
|
|
||||||
describe('setup React app with --bundler=vite', () => {
|
describe('setup React app with --bundler=vite', () => {
|
||||||
let viteAppTree: Tree;
|
let viteAppTree: Tree;
|
||||||
beforeAll(async () => {
|
|
||||||
|
beforeEach(async () => {
|
||||||
viteAppTree = createTreeWithEmptyV1Workspace();
|
viteAppTree = createTreeWithEmptyV1Workspace();
|
||||||
await applicationGenerator(viteAppTree, { ...schema, bundler: 'vite' });
|
await applicationGenerator(viteAppTree, { ...schema, bundler: 'vite' });
|
||||||
});
|
});
|
||||||
@ -984,6 +985,7 @@ describe('app', () => {
|
|||||||
buildTarget: 'my-app:build',
|
buildTarget: 'my-app:build',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should add dependencies in package.json', () => {
|
it('should add dependencies in package.json', () => {
|
||||||
const packageJson = readJson(viteAppTree, '/package.json');
|
const packageJson = readJson(viteAppTree, '/package.json');
|
||||||
|
|
||||||
@ -1020,6 +1022,30 @@ describe('app', () => {
|
|||||||
viteAppTree.exists('/apps/insourceTests/src/app/app.spec.tsx')
|
viteAppTree.exists('/apps/insourceTests/src/app/app.spec.tsx')
|
||||||
).toBe(false);
|
).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it.each`
|
||||||
|
style | pkg
|
||||||
|
${'less'} | ${'less'}
|
||||||
|
${'scss'} | ${'sass'}
|
||||||
|
${'styl'} | ${'stylus'}
|
||||||
|
`(
|
||||||
|
'should add style preprocessor when vite is used',
|
||||||
|
async ({ style, pkg }) => {
|
||||||
|
await applicationGenerator(viteAppTree, {
|
||||||
|
...schema,
|
||||||
|
style,
|
||||||
|
bundler: 'vite',
|
||||||
|
unitTestRunner: 'vitest',
|
||||||
|
name: style,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(readJson(viteAppTree, 'package.json')).toMatchObject({
|
||||||
|
devDependencies: {
|
||||||
|
[pkg]: expect.any(String),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('setting generator defaults', () => {
|
describe('setting generator defaults', () => {
|
||||||
|
|||||||
@ -31,6 +31,7 @@ import {
|
|||||||
swcCoreVersion,
|
swcCoreVersion,
|
||||||
swcLoaderVersion,
|
swcLoaderVersion,
|
||||||
} from '../../utils/versions';
|
} from '../../utils/versions';
|
||||||
|
import { installCommonDependencies } from './lib/install-common-dependencies';
|
||||||
|
|
||||||
async function addLinting(host: Tree, options: NormalizedSchema) {
|
async function addLinting(host: Tree, options: NormalizedSchema) {
|
||||||
const tasks: GeneratorCallback[] = [];
|
const tasks: GeneratorCallback[] = [];
|
||||||
@ -122,6 +123,7 @@ export async function applicationGenerator(host: Tree, schema: Schema) {
|
|||||||
|
|
||||||
const vitestTask = await vitestGenerator(host, {
|
const vitestTask = await vitestGenerator(host, {
|
||||||
uiFramework: 'react',
|
uiFramework: 'react',
|
||||||
|
coverageProvider: 'c8',
|
||||||
project: options.projectName,
|
project: options.projectName,
|
||||||
inSourceTests: options.inSourceTests,
|
inSourceTests: options.inSourceTests,
|
||||||
});
|
});
|
||||||
@ -153,6 +155,8 @@ export async function applicationGenerator(host: Tree, schema: Schema) {
|
|||||||
|
|
||||||
// Handle tsconfig.spec.json for jest or vitest
|
// Handle tsconfig.spec.json for jest or vitest
|
||||||
updateSpecConfig(host, options);
|
updateSpecConfig(host, options);
|
||||||
|
const stylePreprocessorTask = installCommonDependencies(host, options);
|
||||||
|
tasks.push(stylePreprocessorTask);
|
||||||
const styledTask = addStyledModuleDependencies(host, options.styledModule);
|
const styledTask = addStyledModuleDependencies(host, options.styledModule);
|
||||||
tasks.push(styledTask);
|
tasks.push(styledTask);
|
||||||
const routingTask = addRouting(host, options);
|
const routingTask = addRouting(host, options);
|
||||||
|
|||||||
@ -0,0 +1,35 @@
|
|||||||
|
import { addDependenciesToPackageJson, Tree } from '@nrwl/devkit';
|
||||||
|
import {
|
||||||
|
lessVersion,
|
||||||
|
sassVersion,
|
||||||
|
stylusVersion,
|
||||||
|
} from '../../../utils/versions';
|
||||||
|
import { NormalizedSchema } from '../schema';
|
||||||
|
|
||||||
|
export function installCommonDependencies(
|
||||||
|
host: Tree,
|
||||||
|
options: NormalizedSchema
|
||||||
|
) {
|
||||||
|
let devDependencies = null;
|
||||||
|
|
||||||
|
// Vite requires style preprocessors to be installed manually.
|
||||||
|
// `@nrwl/webpack` installs them automatically for now.
|
||||||
|
// TODO(jack): Once we clean up webpack we can remove this check
|
||||||
|
if (options.bundler === 'vite' || options.unitTestRunner === 'vitest') {
|
||||||
|
switch (options.style) {
|
||||||
|
case 'scss':
|
||||||
|
devDependencies = { sass: sassVersion };
|
||||||
|
break;
|
||||||
|
case 'less':
|
||||||
|
devDependencies = { less: lessVersion };
|
||||||
|
break;
|
||||||
|
case 'styl':
|
||||||
|
devDependencies = { stylus: stylusVersion };
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return devDependencies
|
||||||
|
? addDependenciesToPackageJson(host, {}, devDependencies)
|
||||||
|
: function noop() {};
|
||||||
|
}
|
||||||
@ -312,6 +312,7 @@ describe('component', () => {
|
|||||||
.read('libs/my-lib/src/lib/hello/hello.tsx')
|
.read('libs/my-lib/src/lib/hello/hello.tsx')
|
||||||
.toString();
|
.toString();
|
||||||
expect(content).toContain('<style jsx>');
|
expect(content).toContain('<style jsx>');
|
||||||
|
expect(content).not.toContain("styles['container']");
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should add dependencies to package.json', async () => {
|
it('should add dependencies to package.json', async () => {
|
||||||
|
|||||||
@ -14,7 +14,7 @@ import { Route, Link } from 'react-router-dom';
|
|||||||
import styled from '<%= styledModule %>';
|
import styled from '<%= styledModule %>';
|
||||||
<% } else {
|
<% } else {
|
||||||
var wrapper = 'div';
|
var wrapper = 'div';
|
||||||
var extras = globalCss ? '' : " className={styles['container']}";
|
var extras = globalCss || styledModule === 'styled-jsx' ? '' : " className={styles['container']}";
|
||||||
%>
|
%>
|
||||||
<%- style !== 'styled-jsx' ? globalCss ? `import './${fileName}.${style}';` : `import styles from './${fileName}.module.${style}';`: '' %>
|
<%- style !== 'styled-jsx' ? globalCss ? `import './${fileName}.${style}';` : `import styles from './${fileName}.module.${style}';`: '' %>
|
||||||
<% }
|
<% }
|
||||||
|
|||||||
@ -0,0 +1,44 @@
|
|||||||
|
import { addDependenciesToPackageJson, Tree } from '@nrwl/devkit';
|
||||||
|
import {
|
||||||
|
lessVersion,
|
||||||
|
reactDomVersion,
|
||||||
|
reactVersion,
|
||||||
|
sassVersion,
|
||||||
|
stylusVersion,
|
||||||
|
swcCoreVersion,
|
||||||
|
} from '../../../utils/versions';
|
||||||
|
import { NormalizedSchema } from '../schema';
|
||||||
|
|
||||||
|
export function installCommonDependencies(
|
||||||
|
host: Tree,
|
||||||
|
options: NormalizedSchema
|
||||||
|
) {
|
||||||
|
const devDependencies =
|
||||||
|
options.compiler === 'swc' ? { '@swc/core': swcCoreVersion } : {};
|
||||||
|
|
||||||
|
// Vite requires style preprocessors to be installed manually.
|
||||||
|
// `@nrwl/webpack` installs them automatically for now.
|
||||||
|
// TODO(jack): Once we clean up webpack we can remove this check
|
||||||
|
if (options.bundler === 'vite' || options.unitTestRunner === 'vitest') {
|
||||||
|
switch (options.style) {
|
||||||
|
case 'scss':
|
||||||
|
devDependencies['sass'] = sassVersion;
|
||||||
|
break;
|
||||||
|
case 'less':
|
||||||
|
devDependencies['less'] = lessVersion;
|
||||||
|
break;
|
||||||
|
case 'styl':
|
||||||
|
devDependencies['stylus'] = stylusVersion;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return addDependenciesToPackageJson(
|
||||||
|
host,
|
||||||
|
{
|
||||||
|
react: reactVersion,
|
||||||
|
'react-dom': reactDomVersion,
|
||||||
|
},
|
||||||
|
devDependencies
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -771,4 +771,28 @@ describe('lib', () => {
|
|||||||
}).not.toThrow();
|
}).not.toThrow();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
it.each`
|
||||||
|
style | pkg
|
||||||
|
${'less'} | ${'less'}
|
||||||
|
${'scss'} | ${'sass'}
|
||||||
|
${'styl'} | ${'stylus'}
|
||||||
|
`(
|
||||||
|
'should add style preprocessor when vite is used',
|
||||||
|
async ({ style, pkg }) => {
|
||||||
|
await libraryGenerator(tree, {
|
||||||
|
...defaultSchema,
|
||||||
|
style,
|
||||||
|
bundler: 'vite',
|
||||||
|
unitTestRunner: 'vitest',
|
||||||
|
name: 'myLib',
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(readJson(tree, 'package.json')).toMatchObject({
|
||||||
|
devDependencies: {
|
||||||
|
[pkg]: expect.any(String),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
import {
|
import {
|
||||||
addDependenciesToPackageJson,
|
|
||||||
addProjectConfiguration,
|
addProjectConfiguration,
|
||||||
convertNxGenerator,
|
convertNxGenerator,
|
||||||
ensurePackage,
|
ensurePackage,
|
||||||
@ -11,12 +10,7 @@ import {
|
|||||||
} from '@nrwl/devkit';
|
} from '@nrwl/devkit';
|
||||||
import { runTasksInSerial } from '@nrwl/workspace/src/utilities/run-tasks-in-serial';
|
import { runTasksInSerial } from '@nrwl/workspace/src/utilities/run-tasks-in-serial';
|
||||||
|
|
||||||
import {
|
import { nxVersion } from '../../utils/versions';
|
||||||
nxVersion,
|
|
||||||
reactDomVersion,
|
|
||||||
reactVersion,
|
|
||||||
swcCoreVersion,
|
|
||||||
} from '../../utils/versions';
|
|
||||||
import componentGenerator from '../component/component';
|
import componentGenerator from '../component/component';
|
||||||
import initGenerator from '../init/init';
|
import initGenerator from '../init/init';
|
||||||
import { Schema } from './schema';
|
import { Schema } from './schema';
|
||||||
@ -27,6 +21,7 @@ import { addLinting } from './lib/add-linting';
|
|||||||
import { updateAppRoutes } from './lib/update-app-routes';
|
import { updateAppRoutes } from './lib/update-app-routes';
|
||||||
import { createFiles } from './lib/create-files';
|
import { createFiles } from './lib/create-files';
|
||||||
import { updateBaseTsConfig } from './lib/update-base-tsconfig';
|
import { updateBaseTsConfig } from './lib/update-base-tsconfig';
|
||||||
|
import { installCommonDependencies } from './lib/install-common-dependencies';
|
||||||
|
|
||||||
export async function libraryGenerator(host: Tree, schema: Schema) {
|
export async function libraryGenerator(host: Tree, schema: Schema) {
|
||||||
const tasks: GeneratorCallback[] = [];
|
const tasks: GeneratorCallback[] = [];
|
||||||
@ -123,6 +118,7 @@ export async function libraryGenerator(host: Tree, schema: Schema) {
|
|||||||
const vitestTask = await vitestGenerator(host, {
|
const vitestTask = await vitestGenerator(host, {
|
||||||
uiFramework: 'react',
|
uiFramework: 'react',
|
||||||
project: options.name,
|
project: options.name,
|
||||||
|
coverageProvider: 'c8',
|
||||||
inSourceTests: options.inSourceTests,
|
inSourceTests: options.inSourceTests,
|
||||||
});
|
});
|
||||||
tasks.push(vitestTask);
|
tasks.push(vitestTask);
|
||||||
@ -153,14 +149,7 @@ export async function libraryGenerator(host: Tree, schema: Schema) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!options.skipPackageJson) {
|
if (!options.skipPackageJson) {
|
||||||
const installReactTask = await addDependenciesToPackageJson(
|
const installReactTask = await installCommonDependencies(host, options);
|
||||||
host,
|
|
||||||
{
|
|
||||||
react: reactVersion,
|
|
||||||
'react-dom': reactDomVersion,
|
|
||||||
},
|
|
||||||
options.compiler === 'swc' ? { '@swc/core': swcCoreVersion } : {}
|
|
||||||
);
|
|
||||||
tasks.push(installReactTask);
|
tasks.push(installReactTask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -52,3 +52,8 @@ export const isbotVersion = '^3.6.5';
|
|||||||
export const corsVersion = '~2.8.5';
|
export const corsVersion = '~2.8.5';
|
||||||
export const typesCorsVersion = '~2.8.12';
|
export const typesCorsVersion = '~2.8.12';
|
||||||
export const moduleFederationNodeVersion = '~0.9.6';
|
export const moduleFederationNodeVersion = '~0.9.6';
|
||||||
|
|
||||||
|
// style preprocessors
|
||||||
|
export const lessVersion = '3.12.2';
|
||||||
|
export const sassVersion = '^1.55.0';
|
||||||
|
export const stylusVersion = '^0.55.0';
|
||||||
|
|||||||
@ -59,6 +59,7 @@ export async function viteConfigurationGenerator(tree: Tree, schema: Schema) {
|
|||||||
project: schema.project,
|
project: schema.project,
|
||||||
uiFramework: schema.uiFramework,
|
uiFramework: schema.uiFramework,
|
||||||
inSourceTests: schema.inSourceTests,
|
inSourceTests: schema.inSourceTests,
|
||||||
|
coverageProvider: 'c8',
|
||||||
skipViteConfig: true,
|
skipViteConfig: true,
|
||||||
});
|
});
|
||||||
tasks.push(vitestTask);
|
tasks.push(vitestTask);
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
export interface VitestGeneratorSchema {
|
export interface VitestGeneratorSchema {
|
||||||
project: string;
|
project: string;
|
||||||
uiFramework: 'react' | 'none';
|
uiFramework: 'react' | 'none';
|
||||||
|
coverageProvider: 'c8' | 'istanbul';
|
||||||
inSourceTests?: boolean;
|
inSourceTests?: boolean;
|
||||||
skipViteConfig?: boolean;
|
skipViteConfig?: boolean;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -26,6 +26,12 @@
|
|||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"default": false,
|
"default": false,
|
||||||
"description": "Skip generating a vite config file"
|
"description": "Skip generating a vite config file"
|
||||||
|
},
|
||||||
|
"coverageProvider": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["c8", "istanbul"],
|
||||||
|
"default": "c8",
|
||||||
|
"description": "Coverage provider to use."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": ["project"]
|
"required": ["project"]
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import {
|
import {
|
||||||
|
addDependenciesToPackageJson,
|
||||||
convertNxGenerator,
|
convertNxGenerator,
|
||||||
formatFiles,
|
formatFiles,
|
||||||
generateFiles,
|
generateFiles,
|
||||||
@ -18,6 +19,10 @@ import { VitestGeneratorSchema } from './schema';
|
|||||||
|
|
||||||
import { runTasksInSerial } from '@nrwl/workspace/src/utilities/run-tasks-in-serial';
|
import { runTasksInSerial } from '@nrwl/workspace/src/utilities/run-tasks-in-serial';
|
||||||
import initGenerator from '../init/init';
|
import initGenerator from '../init/init';
|
||||||
|
import {
|
||||||
|
vitestCoverageC8Version,
|
||||||
|
vitestCoverageIstanbulVersion,
|
||||||
|
} from '../../utils/versions';
|
||||||
|
|
||||||
export async function vitestGenerator(
|
export async function vitestGenerator(
|
||||||
tree: Tree,
|
tree: Tree,
|
||||||
@ -45,6 +50,22 @@ export async function vitestGenerator(
|
|||||||
createFiles(tree, schema, root);
|
createFiles(tree, schema, root);
|
||||||
updateTsConfig(tree, schema, root);
|
updateTsConfig(tree, schema, root);
|
||||||
|
|
||||||
|
const installCoverageProviderTask = addDependenciesToPackageJson(
|
||||||
|
tree,
|
||||||
|
{},
|
||||||
|
schema.coverageProvider === 'istanbul'
|
||||||
|
? {
|
||||||
|
'@vitest/coverage-istanbul': vitestCoverageIstanbulVersion,
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
'@vitest/coverage-c8': vitestCoverageC8Version,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
tasks.push(installCoverageProviderTask);
|
||||||
|
|
||||||
|
if (schema.coverageProvider === 'istanbul') {
|
||||||
|
}
|
||||||
|
|
||||||
await formatFiles(tree);
|
await formatFiles(tree);
|
||||||
|
|
||||||
return runTasksInSerial(...tasks);
|
return runTasksInSerial(...tasks);
|
||||||
|
|||||||
@ -10,6 +10,7 @@ describe('vitest generator', () => {
|
|||||||
const options: VitestGeneratorSchema = {
|
const options: VitestGeneratorSchema = {
|
||||||
project: 'my-test-react-app',
|
project: 'my-test-react-app',
|
||||||
uiFramework: 'react',
|
uiFramework: 'react',
|
||||||
|
coverageProvider: 'c8',
|
||||||
};
|
};
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
@ -126,6 +127,9 @@ describe('vitest generator', () => {
|
|||||||
|
|
||||||
test: {
|
test: {
|
||||||
globals: true,
|
globals: true,
|
||||||
|
cache: {
|
||||||
|
dir: '../../node_modules/.vitest'
|
||||||
|
},
|
||||||
environment: 'jsdom',
|
environment: 'jsdom',
|
||||||
include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
|
include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
|
||||||
|
|
||||||
@ -169,6 +173,9 @@ describe('vitest generator', () => {
|
|||||||
},
|
},
|
||||||
test: {
|
test: {
|
||||||
globals: true,
|
globals: true,
|
||||||
|
cache: {
|
||||||
|
dir: '../../node_modules/.vitest'
|
||||||
|
},
|
||||||
environment: 'jsdom',
|
environment: 'jsdom',
|
||||||
include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
|
include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
|
||||||
includeSource: ['src/**/*.{js,mjs,cjs,ts,mts,cts,jsx,tsx}']
|
includeSource: ['src/**/*.{js,mjs,cjs,ts,mts,cts,jsx,tsx}']
|
||||||
|
|||||||
@ -354,6 +354,9 @@ export function writeViteConfig(tree: Tree, options: Schema) {
|
|||||||
const testOption = options.includeVitest
|
const testOption = options.includeVitest
|
||||||
? `test: {
|
? `test: {
|
||||||
globals: true,
|
globals: true,
|
||||||
|
cache: {
|
||||||
|
dir: '${offsetFromRoot(projectConfig.root)}node_modules/.vitest'
|
||||||
|
},
|
||||||
environment: 'jsdom',
|
environment: 'jsdom',
|
||||||
include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
|
include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
|
||||||
${
|
${
|
||||||
|
|||||||
@ -9,3 +9,7 @@ export const vitePluginVueJsxVersion = '^2.1.1';
|
|||||||
export const viteTsConfigPathsVersion = '^3.5.2';
|
export const viteTsConfigPathsVersion = '^3.5.2';
|
||||||
export const jsdomVersion = '~20.0.3';
|
export const jsdomVersion = '~20.0.3';
|
||||||
export const vitePluginDtsVersion = '~1.7.1';
|
export const vitePluginDtsVersion = '~1.7.1';
|
||||||
|
|
||||||
|
// Coverage providers
|
||||||
|
export const vitestCoverageC8Version = '~0.25.3';
|
||||||
|
export const vitestCoverageIstanbulVersion = '~0.25.3';
|
||||||
|
|||||||
@ -220,6 +220,7 @@ export async function applicationGenerator(host: Tree, schema: Schema) {
|
|||||||
const vitestTask = await vitestGenerator(host, {
|
const vitestTask = await vitestGenerator(host, {
|
||||||
uiFramework: 'none',
|
uiFramework: 'none',
|
||||||
project: options.projectName,
|
project: options.projectName,
|
||||||
|
coverageProvider: 'c8',
|
||||||
inSourceTests: options.inSourceTests,
|
inSourceTests: options.inSourceTests,
|
||||||
});
|
});
|
||||||
tasks.push(vitestTask);
|
tasks.push(vitestTask);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user