diff --git a/e2e/remix/tests/nx-remix.test.ts b/e2e/remix/tests/nx-remix.test.ts
index 37495874ab3d5..7fcc52abae793 100644
--- a/e2e/remix/tests/nx-remix.test.ts
+++ b/e2e/remix/tests/nx-remix.test.ts
@@ -11,164 +11,198 @@ import {
listFiles,
} from '@nx/e2e/utils';
-describe('remix e2e', () => {
- let proj: string;
+describe('Remix E2E Tests', () => {
+ describe('--integrated', () => {
+ let proj: string;
- beforeAll(() => {
- proj = newProject({ packages: ['@nx/remix'] });
- });
-
- afterAll(() => {
- killPorts();
- cleanupProject();
- });
+ beforeAll(() => {
+ proj = newProject({ packages: ['@nx/remix', '@nx/react'] });
+ });
- it('should create a standalone remix app', async () => {
- const appName = uniq('remix');
- runCLI(`generate @nx/remix:preset --name ${appName} --verbose`);
+ afterAll(() => {
+ killPorts();
+ cleanupProject();
+ });
- // Can import using ~ alias like a normal Remix setup.
- updateFile(`app/foo.ts`, `export const foo = 'foo';`);
- updateFile(
- `app/routes/index.tsx`,
- `
- import { foo } from '~/foo';
- export default function Index() {
- return (
-
{foo}
- );
- }
- `
- );
+ it('should create app', async () => {
+ const plugin = uniq('remix');
+ runCLI(`generate @nx/remix:app ${plugin}`);
- const result = runCLI(`build ${appName}`);
- expect(result).toContain('Successfully ran target build');
- }, 120_000);
+ const buildResult = runCLI(`build ${plugin}`);
+ expect(buildResult).toContain('Successfully ran target build');
- it('should create app', async () => {
- const plugin = uniq('remix');
- runCLI(`generate @nx/remix:app ${plugin}`);
+ const testResult = runCLI(`test ${plugin}`);
+ expect(testResult).toContain('Successfully ran target test');
+ }, 120000);
- const buildResult = runCLI(`build ${plugin}`);
- expect(buildResult).toContain('Successfully ran target build');
+ describe('--directory', () => {
+ it('should create src in the specified directory --projectNameAndRootFormat=derived', async () => {
+ const plugin = uniq('remix');
+ const appName = `sub-${plugin}`;
+ runCLI(
+ `generate @nx/remix:app ${plugin} --directory=sub --projectNameAndRootFormat=derived --rootProject=false --no-interactive`
+ );
- const testResult = runCLI(`test ${plugin}`);
- expect(testResult).toContain('Successfully ran target test');
- }, 120000);
+ const result = runCLI(`build ${appName}`);
+ expect(result).toContain('Successfully ran target build');
- describe('--directory', () => {
- it('should create src in the specified directory --projectNameAndRootFormat=derived', async () => {
- const plugin = uniq('remix');
- const appName = `sub-${plugin}`;
- runCLI(
- `generate @nx/remix:app ${plugin} --directory=sub --projectNameAndRootFormat=derived --rootProject=false --no-interactive`
- );
+ // TODO(colum): uncomment line below when fixed
+ checkFilesExist(`dist/apps/sub/${plugin}/build/index.js`);
+ }, 120000);
- const result = runCLI(`build ${appName}`);
- expect(result).toContain('Successfully ran target build');
+ it('should create src in the specified directory --projectNameAndRootFormat=as-provided', async () => {
+ const plugin = uniq('remix');
+ runCLI(
+ `generate @nx/remix:app ${plugin} --directory=subdir --projectNameAndRootFormat=as-provided --rootProject=false --no-interactive`
+ );
- // TODO(colum): uncomment line below when fixed
- // checkFilesExist(`dist/apps/sub/${plugin}/build/index.js`);
- }, 120000);
+ const result = runCLI(`build ${plugin}`);
+ expect(result).toContain('Successfully ran target build');
+ checkFilesExist(`dist/subdir/build/index.js`);
+ }, 120000);
+ });
+
+ describe('--tags', () => {
+ it('should add tags to the project', async () => {
+ const plugin = uniq('remix');
+ runCLI(`generate @nx/remix:app ${plugin} --tags e2etag,e2ePackage`);
+ const project = readJson(`apps/${plugin}/project.json`);
+ expect(project.tags).toEqual(['e2etag', 'e2ePackage']);
+ }, 120000);
+ });
+
+ describe('--js', () => {
+ it('should create js app and build correctly', async () => {
+ const plugin = uniq('remix');
+ runCLI(`generate @nx/remix:app ${plugin} --js=true`);
+
+ const result = runCLI(`build ${plugin}`);
+ expect(result).toContain('Successfully ran target build');
+ }, 120000);
+ });
+
+ describe('--unitTestRunner', () => {
+ it('should generate a library with vitest and test correctly', async () => {
+ const plugin = uniq('remix');
+ runCLI(`generate @nx/remix:library ${plugin} --unitTestRunner=vitest`);
+
+ const result = runCLI(`test ${plugin}`);
+ expect(result).toContain(`Successfully ran target test`);
+ }, 120_000);
+
+ it('should generate a library with jest and test correctly', async () => {
+ const reactapp = uniq('react');
+ runCLI(
+ `generate @nx/react:application ${reactapp} --unitTestRunner=jest`
+ );
+ const plugin = uniq('remix');
+ runCLI(
+ `generate @nx/remix:application ${plugin} --unitTestRunner=jest`
+ );
- it('should create src in the specified directory --projectNameAndRootFormat=as-provided', async () => {
- const plugin = uniq('remix');
- runCLI(
- `generate @nx/remix:app ${plugin} --directory=subdir --projectNameAndRootFormat=as-provided --rootProject=false --no-interactive`
- );
+ const result = runCLI(`test ${plugin}`);
+ expect(result).toContain(`Successfully ran target test`);
- const result = runCLI(`build ${plugin}`);
- expect(result).toContain('Successfully ran target build');
- checkFilesExist(`dist/subdir/build/index.js`);
- }, 120000);
- });
+ const reactResult = runCLI(`test ${reactapp}`);
+ expect(result).toContain(`Successfully ran target test`);
+ }, 120_000);
+ });
- describe('--tags', () => {
- it('should add tags to the project', async () => {
+ describe('error checking', () => {
const plugin = uniq('remix');
- runCLI(`generate @nx/remix:app ${plugin} --tags e2etag,e2ePackage`);
- const project = readJson(`${plugin}/project.json`);
- expect(project.tags).toEqual(['e2etag', 'e2ePackage']);
- }, 120000);
- });
- describe('--js', () => {
- it('should create js app and build correctly', async () => {
- const plugin = uniq('remix');
- runCLI(`generate @nx/remix:app ${plugin} --js=true`);
+ beforeAll(async () => {
+ runCLI(`generate @nx/remix:app ${plugin} --tags e2etag,e2ePackage`);
+ }, 120000);
- const result = runCLI(`build ${plugin}`);
- expect(result).toContain('Successfully ran target build');
- }, 120000);
- });
+ it('should check for un-escaped dollar signs in routes', async () => {
+ await expect(async () =>
+ runCLI(
+ `generate @nx/remix:route --project ${plugin} --path my.route.$withParams.tsx`
+ )
+ ).rejects.toThrow();
- describe('--unitTestRunner', () => {
- it('should generate a library with vitest and test correctly', async () => {
- const plugin = uniq('remix');
- runCLI(`generate @nx/remix:library ${plugin} --unitTestRunner=vitest`);
+ runCLI(
+ `generate @nx/remix:route --project ${plugin} --path my.route.\\$withParams.tsx`
+ );
- const result = runCLI(`test ${plugin}`);
- expect(result).toContain(`Successfully ran target test`);
- }, 120_000);
- });
+ expect(() =>
+ checkFilesExist(`apps/${plugin}/app/routes/my.route.$withParams.tsx`)
+ ).not.toThrow();
+ }, 120000);
- describe('error checking', () => {
- const plugin = uniq('remix');
+ it('should pass un-escaped dollar signs in routes with skipChecks flag', async () => {
+ await runCommandAsync(
+ `someWeirdUseCase=route-segment && yarn nx generate @nx/remix:route --project ${plugin} --path my.route.$someWeirdUseCase.tsx --force`
+ );
- beforeAll(async () => {
- runCLI(`generate @nx/remix:app ${plugin} --tags e2etag,e2ePackage`);
- }, 120000);
+ expect(() =>
+ checkFilesExist(
+ `apps/${plugin}/app/routes/my.route.route-segment.tsx`
+ )
+ ).not.toThrow();
+ }, 120000);
+
+ it('should check for un-escaped dollar signs in resource routes', async () => {
+ await expect(async () =>
+ runCLI(
+ `generate @nx/remix:resource-route --project ${plugin} --path my.route.$withParams.ts`
+ )
+ ).rejects.toThrow();
- it('should check for un-escaped dollar signs in routes', async () => {
- await expect(async () =>
runCLI(
- `generate @nx/remix:route --project ${plugin} --path my.route.$withParams.tsx`
- )
- ).rejects.toThrow();
+ `generate @nx/remix:resource-route --project ${plugin} --path my.route.\\$withParams.ts`
+ );
- runCLI(
- `generate @nx/remix:route --project ${plugin} --path my.route.\\$withParams.tsx`
- );
+ expect(() =>
+ checkFilesExist(`apps/${plugin}/app/routes/my.route.$withParams.ts`)
+ ).not.toThrow();
+ }, 120000);
- expect(() =>
- checkFilesExist(`${plugin}/app/routes/my.route.$withParams.tsx`)
- ).not.toThrow();
- }, 120000);
+ it('should pass un-escaped dollar signs in resource routes with skipChecks flag', async () => {
+ await runCommandAsync(
+ `someWeirdUseCase=route-segment && yarn nx generate @nx/remix:resource-route --project ${plugin} --path my.route.$someWeirdUseCase.ts --force`
+ );
- it('should pass un-escaped dollar signs in routes with skipChecks flag', async () => {
- await runCommandAsync(
- `someWeirdUseCase=route-segment && yarn nx generate @nx/remix:route --project ${plugin} --path my.route.$someWeirdUseCase.tsx --force`
- );
+ expect(() =>
+ checkFilesExist(`apps/${plugin}/app/routes/my.route.route-segment.ts`)
+ ).not.toThrow();
+ }, 120000);
+ });
+ });
- expect(() =>
- checkFilesExist(`${plugin}/app/routes/my.route.route-segment.tsx`)
- ).not.toThrow();
- }, 120000);
+ describe('--standalone', () => {
+ let proj: string;
- it('should check for un-escaped dollar signs in resource routes', async () => {
- await expect(async () =>
- runCLI(
- `generate @nx/remix:resource-route --project ${plugin} --path my.route.$withParams.ts`
- )
- ).rejects.toThrow();
+ beforeAll(() => {
+ proj = newProject({ packages: ['@nx/remix'] });
+ });
- runCLI(
- `generate @nx/remix:resource-route --project ${plugin} --path my.route.\\$withParams.ts`
- );
+ afterAll(() => {
+ killPorts();
+ cleanupProject();
+ });
- expect(() =>
- checkFilesExist(`${plugin}/app/routes/my.route.$withParams.ts`)
- ).not.toThrow();
- }, 120000);
+ it('should create a standalone remix app', async () => {
+ const appName = uniq('remix');
+ runCLI(`generate @nx/remix:preset --name ${appName} --verbose`);
- it('should pass un-escaped dollar signs in resource routes with skipChecks flag', async () => {
- await runCommandAsync(
- `someWeirdUseCase=route-segment && yarn nx generate @nx/remix:resource-route --project ${plugin} --path my.route.$someWeirdUseCase.ts --force`
+ // Can import using ~ alias like a normal Remix setup.
+ updateFile(`app/foo.ts`, `export const foo = 'foo';`);
+ updateFile(
+ `app/routes/index.tsx`,
+ `
+ import { foo } from '~/foo';
+ export default function Index() {
+ return (
+ {foo}
+ );
+ }
+ `
);
- expect(() =>
- checkFilesExist(`${plugin}/app/routes/my.route.route-segment.ts`)
- ).not.toThrow();
- }, 120000);
+ const result = runCLI(`build ${appName}`);
+ expect(result).toContain('Successfully ran target build');
+ }, 120_000);
});
});
diff --git a/packages/remix/src/generators/application/__snapshots__/application.impl.spec.ts.snap b/packages/remix/src/generators/application/__snapshots__/application.impl.spec.ts.snap
index f73d0613e55af..03ac40a59833a 100644
--- a/packages/remix/src/generators/application/__snapshots__/application.impl.spec.ts.snap
+++ b/packages/remix/src/generators/application/__snapshots__/application.impl.spec.ts.snap
@@ -323,9 +323,8 @@ export default {
exports[`Remix Application Integrated Repo --projectNameAndRootFormat=as-provided --unitTestRunner should generate the correct files for testing using jest 2`] = `
"/* eslint-disable */
export default {
- setupFilesAfterEnv: ['/test-setup.ts'],
displayName: 'test',
- preset: '../jest.preset.cjs',
+ preset: '../jest.preset.js',
transform: {
'^.+\\\\.[tj]sx?$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }],
},
@@ -801,9 +800,8 @@ export default {
exports[`Remix Application Integrated Repo --projectNameAndRootFormat=derived --unitTestRunner should generate the correct files for testing using jest 2`] = `
"/* eslint-disable */
export default {
- setupFilesAfterEnv: ['/test-setup.ts'],
displayName: 'test',
- preset: '../../jest.preset.cjs',
+ preset: '../../jest.preset.js',
transform: {
'^.+\\\\.[tj]sx?$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }],
},
diff --git a/packages/remix/src/generators/application/application.impl.ts b/packages/remix/src/generators/application/application.impl.ts
index b2563364e8fc5..c0450ea4a9fb0 100644
--- a/packages/remix/src/generators/application/application.impl.ts
+++ b/packages/remix/src/generators/application/application.impl.ts
@@ -198,7 +198,8 @@ export async function remixApplicationGeneratorInternal(
const pkgInstallTask = updateUnitTestConfig(
tree,
options.projectRoot,
- options.unitTestRunner
+ options.unitTestRunner,
+ options.rootProject
);
tasks.push(pkgInstallTask);
} else {
diff --git a/packages/remix/src/generators/application/lib/update-unit-test-config.ts b/packages/remix/src/generators/application/lib/update-unit-test-config.ts
index 9ec9de48ecd1b..3af2a85a418d1 100644
--- a/packages/remix/src/generators/application/lib/update-unit-test-config.ts
+++ b/packages/remix/src/generators/application/lib/update-unit-test-config.ts
@@ -21,7 +21,8 @@ import {
export function updateUnitTestConfig(
tree: Tree,
pathToRoot: string,
- unitTestRunner: 'vitest' | 'jest'
+ unitTestRunner: 'vitest' | 'jest',
+ rootProject: boolean
) {
const pathToTestSetup = joinPathFragments(pathToRoot, `test-setup.ts`);
tree.write(
@@ -45,9 +46,9 @@ export function updateUnitTestConfig(
'./tests/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'
);
updateVitestTestSetup(tree, pathToViteConfig, 'test-setup.ts');
- } else if (unitTestRunner === 'jest') {
+ } else if (unitTestRunner === 'jest' && rootProject) {
const pathToJestConfig = joinPathFragments(pathToRoot, 'jest.config.ts');
- tree.rename('jest.preset.js', 'jest.preset.cjs');
+ tree.write('jest.preset.cjs', tree.read('jest.preset.js', 'utf-8'));
updateJestTestSetup(tree, pathToJestConfig, `/test-setup.ts`);
tree.write(
pathToJestConfig,