Skip to content
Draft
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .nx/workflows/dynamic-changesets.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ assignment-rules:
- e2e-next
- e2e-web
- e2e-eslint
- e2e-remix
- e2e-cypress
- e2e-docker
targets:
- e2e-ci**react-package**
- e2e-ci**react.test**
Expand All @@ -36,6 +39,13 @@ assignment-rules:
- e2e-ci**web**
- e2e-ci**remix-ts-solution**
- e2e-ci**linter**
- e2e-ci**module-federation/misc-rspack-interoperability**
- e2e-ci**module-federation/dynamic-federation.webpack**
- e2e-ci**docker**
- e2e-ci**module-federation/misc-rspack-interoperability**
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There appears to be a duplicate entry for e2e-ci**module-federation/misc-rspack-interoperability** in the targets list (lines 42 and 45). One of these entries should be removed to prevent the same test from running twice unnecessarily.

Suggested change
- e2e-ci**module-federation/misc-rspack-interoperability**
- e2e-ci**module-federation/dynamic-federation.webpack**
- e2e-ci**docker**
- e2e-ci**module-federation/misc-rspack-interoperability**
- e2e-ci**module-federation/misc-rspack-interoperability**
- e2e-ci**module-federation/dynamic-federation.webpack**
- e2e-ci**docker**

Spotted by Graphite Agent

Fix in Graphite


Is this helpful? React 👍 or 👎 to let us know.

- e2e-ci**cypress-legacy**
- e2e-ci**nx-remix**
- e2e-ci**cypress**
run-on:
- agent: linux-large
parallelism: 1
Expand Down
84 changes: 84 additions & 0 deletions e2e/web/src/web-decorator-babel.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { readFile, runCLI, uniq, updateFile } from '@nx/e2e-utils';
import { setupWebTest } from './web-setup';

describe('Web Components Applications', () => {
setupWebTest();

it('should emit decorator metadata when --compiler=babel and it is enabled in tsconfig', async () => {
const appName = uniq('app');
runCLI(
`generate @nx/web:app apps/${appName} --bundler=webpack --compiler=babel --no-interactive --unitTestRunner=vitest --linter=eslint`
);

updateFile(`apps/${appName}/src/app/app.element.ts`, (content) => {
const newContent = `${content}
function enumerable(value: boolean) {
return function (
target: any,
propertyKey: string,
descriptor: PropertyDescriptor
) {
descriptor.enumerable = value;
};
}
function sealed(target: any) {
return target;
}

@sealed
class Foo {
@enumerable(false) bar() {}
}
`;
return newContent;
});

updateFile(`apps/${appName}/src/app/app.element.ts`, (content) => {
const newContent = `${content}
// bust babel and nx cache
`;
return newContent;
});
setPluginOption(
`apps/${appName}/webpack.config.js`,
'outputHashing',
'none'
);
runCLI(`build ${appName}`);

expect(readFile(`dist/apps/${appName}/main.js`)).toMatch(
/Reflect\.metadata/
);

// Turn off decorator metadata
updateFile(`apps/${appName}/tsconfig.app.json`, (content) => {
const json = JSON.parse(content);
json.compilerOptions.emitDecoratorMetadata = false;
return JSON.stringify(json);
});

setPluginOption(
`apps/${appName}/webpack.config.js`,
'outputHashing',
'none'
);
runCLI(`build ${appName}`);

expect(readFile(`dist/apps/${appName}/main.js`)).not.toMatch(
/Reflect\.metadata/
);
}, 120000);
});

function setPluginOption(
webpackConfigPath: string,
option: string,
value: string | boolean
): void {
updateFile(webpackConfigPath, (content) => {
return content.replace(
new RegExp(`${option}: .+`),
`${option}: ${typeof value === 'string' ? `'${value}'` : value},`
);
});
}
66 changes: 66 additions & 0 deletions e2e/web/src/web-decorator-swc.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { readFile, runCLI, uniq, updateFile } from '@nx/e2e-utils';
import { setupWebTest } from './web-setup';

describe('Web Components Applications', () => {
setupWebTest();

it('should emit decorator metadata when using --compiler=swc', async () => {
const appName = uniq('app');
runCLI(
`generate @nx/web:app apps/${appName} --bundler=webpack --compiler=swc --no-interactive --unitTestRunner=vitest --linter=eslint`
);

updateFile(`apps/${appName}/src/app/app.element.ts`, (content) => {
const newContent = `${content}
function enumerable(value: boolean) {
return function (
target: any,
propertyKey: string,
descriptor: PropertyDescriptor
) {
descriptor.enumerable = value;
};
}
function sealed(target: any) {
return target;
}

@sealed
class Foo {
@enumerable(false) bar() {}
}
`;
return newContent;
});

updateFile(`apps/${appName}/src/app/app.element.ts`, (content) => {
const newContent = `${content}
// bust babel and nx cache
`;
return newContent;
});
setPluginOption(
`apps/${appName}/webpack.config.js`,
'outputHashing',
'none'
);
runCLI(`build ${appName}`);

expect(readFile(`dist/apps/${appName}/main.js`)).toMatch(
/Foo=.*?_decorate/
);
}, 120000);
});

function setPluginOption(
webpackConfigPath: string,
option: string,
value: string | boolean
): void {
updateFile(webpackConfigPath, (content) => {
return content.replace(
new RegExp(`${option}: .+`),
`${option}: ${typeof value === 'string' ? `'${value}'` : value},`
);
});
}
125 changes: 125 additions & 0 deletions e2e/web/src/web-env-variables.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
import {
cleanupProject,
newProject,
readFile,
runCLI,
uniq,
updateFile,
} from '@nx/e2e-utils';

describe('CLI - Environment Variables', () => {
it('should automatically load workspace and per-project environment variables', async () => {
newProject();

const appName = uniq('app');
//test if the Nx CLI loads root .env vars
updateFile(
`.env`,
'NX_PUBLIC_WS_BASE=ws-base\nNX_PUBLIC_SHARED_ENV=shared-in-workspace-base'
);
updateFile(
`.env.local`,
'NX_PUBLIC_WS_ENV_LOCAL=ws-env-local\nNX_PUBLIC_SHARED_ENV=shared-in-workspace-env-local'
);
updateFile(
`.local.env`,
'NX_PUBLIC_WS_LOCAL_ENV=ws-local-env\nNX_PUBLIC_SHARED_ENV=shared-in-workspace-local-env'
);
updateFile(
`apps/${appName}/.env`,
'NX_PUBLIC_APP_BASE=app-base\nNX_PUBLIC_SHARED_ENV=shared-in-app-base'
);
updateFile(
`apps/${appName}/.env.local`,
'NX_PUBLIC_APP_ENV_LOCAL=app-env-local\nNX_PUBLIC_SHARED_ENV=shared-in-app-env-local'
);
updateFile(
`apps/${appName}/.local.env`,
'NX_PUBLIC_APP_LOCAL_ENV=app-local-env\nNX_PUBLIC_SHARED_ENV=shared-in-app-local-env'
);
const main = `apps/${appName}/src/main.ts`;
const newCode = `
const envVars = [process.env.NODE_ENV, process.env.NX_PUBLIC_WS_BASE, process.env.NX_PUBLIC_WS_ENV_LOCAL, process.env.NX_PUBLIC_WS_LOCAL_ENV, process.env.NX_PUBLIC_APP_BASE, process.env.NX_PUBLIC_APP_ENV_LOCAL, process.env.NX_PUBLIC_APP_LOCAL_ENV, process.env.NX_PUBLIC_SHARED_ENV];
const nodeEnv = process.env.NODE_ENV;
const nxWsBase = process.env.NX_PUBLIC_WS_BASE;
const nxWsEnvLocal = process.env.NX_PUBLIC_WS_ENV_LOCAL;
const nxWsLocalEnv = process.env.NX_PUBLIC_WS_LOCAL_ENV;
const nxAppBase = process.env.NX_PUBLIC_APP_BASE;
const nxAppEnvLocal = process.env.NX_PUBLIC_APP_ENV_LOCAL;
const nxAppLocalEnv = process.env.NX_PUBLIC_APP_LOCAL_ENV;
const nxSharedEnv = process.env.NX_PUBLIC_SHARED_ENV;
`;

runCLI(
`generate @nx/web:app apps/${appName} --bundler=webpack --no-interactive --compiler=babel --unitTestRunner=vitest --linter=eslint`
);

const content = readFile(main);

updateFile(main, `${newCode}\n${content}`);

const appName2 = uniq('app');

updateFile(
`apps/${appName2}/.env`,
'NX_PUBLIC_APP_BASE=app2-base\nNX_PUBLIC_SHARED_ENV=shared2-in-app-base'
);
updateFile(
`apps/${appName2}/.env.local`,
'NX_PUBLIC_APP_ENV_LOCAL=app2-env-local\nNX_PUBLIC_SHARED_ENV=shared2-in-app-env-local'
);
updateFile(
`apps/${appName2}/.local.env`,
'NX_PUBLIC_APP_LOCAL_ENV=app2-local-env\nNX_PUBLIC_SHARED_ENV=shared2-in-app-local-env'
);
const main2 = `apps/${appName2}/src/main.ts`;
const newCode2 = `const envVars = [process.env.NODE_ENV, process.env.NX_PUBLIC_WS_BASE, process.env.NX_PUBLIC_WS_ENV_LOCAL, process.env.NX_PUBLIC_WS_LOCAL_ENV, process.env.NX_PUBLIC_APP_BASE, process.env.NX_PUBLIC_APP_ENV_LOCAL, process.env.NX_PUBLIC_APP_LOCAL_ENV, process.env.NX_PUBLIC_SHARED_ENV];`;

runCLI(
`generate @nx/web:app apps/${appName2} --bundler=webpack --no-interactive --compiler=babel --unitTestRunner=vitest --linter=eslint`
);

const content2 = readFile(main2);

updateFile(main2, `${newCode2}\n${content2}`);

setPluginOption(
`apps/${appName}/webpack.config.js`,
'outputHashing',
'none'
);
setPluginOption(`apps/${appName}/webpack.config.js`, 'optimization', false);
setPluginOption(
`apps/${appName2}/webpack.config.js`,
'outputHashing',
'none'
);
setPluginOption(
`apps/${appName2}/webpack.config.js`,
'optimization',
false
);
runCLI(`run-many --target build --node-env=test`);
expect(readFile(`dist/apps/${appName}/main.js`)).toContain(
'const envVars = ["test", "ws-base", "ws-env-local", "ws-local-env", "app-base", "app-env-local", "app-local-env", "shared-in-app-env-local"];'
);
expect(readFile(`dist/apps/${appName2}/main.js`)).toContain(
'const envVars = ["test", "ws-base", "ws-env-local", "ws-local-env", "app2-base", "app2-env-local", "app2-local-env", "shared2-in-app-env-local"];'
);

cleanupProject();
});
});

function setPluginOption(
webpackConfigPath: string,
option: string,
value: string | boolean
): void {
updateFile(webpackConfigPath, (content) => {
return content.replace(
new RegExp(`${option}: .+`),
`${option}: ${typeof value === 'string' ? `'${value}'` : value},`
);
});
}
Loading