nx/e2e/next-core/src/next-webpack.test.ts
2023-12-13 12:31:37 -07:00

118 lines
3.4 KiB
TypeScript

import {
checkFilesExist,
cleanupProject,
newProject,
rmDist,
runCLI,
uniq,
updateFile,
updateJson,
} from '@nx/e2e/utils';
import { join } from 'path';
describe('Next.js Webpack', () => {
let proj: string;
let originalEnv: string;
beforeEach(() => {
proj = newProject();
originalEnv = process.env.NODE_ENV;
});
afterEach(() => {
process.env.NODE_ENV = originalEnv;
cleanupProject();
});
it('should support custom webpack and run-commands using withNx', async () => {
const appName = uniq('app');
runCLI(
`generate @nx/next:app ${appName} --no-interactive --style=css --appDir=false`
);
updateFile(
`apps/${appName}/next.config.js`,
`
const { withNx } = require('@nx/next');
const nextConfig = {
nx: {
svgr: false,
},
webpack: (config, context) => {
// Make sure SVGR plugin is disabled if nx.svgr === false (see above)
const found = config.module.rules.find((rule) => {
// Check if the rule is for SVG files
if (!/\.(svg)$/i.test('test.svg')) return false;
// Check if the rule has a 'oneOf' structure
if (!rule.oneOf || !Array.isArray(rule.oneOf)) return false;
// Check each item in 'oneOf' for SVGR loader
return rule.oneOf.some((oneOfRule) => {
if (!oneOfRule.use) return false;
// 'use' might be an object or an array, ensure it's an array for consistency
const uses = Array.isArray(oneOfRule.use)
? oneOfRule.use
: [oneOfRule.use];
return uses.some(use => {
if (typeof use.loader !== 'string') return false;
const svgrRegex = new RegExp('@svgr/webpack');
return svgrRegex.test(use.loader);
});
});
});
if (found) throw new Error('Found SVGR plugin');
console.log('NODE_ENV is', process.env.NODE_ENV);
return config;
}
};
module.exports = withNx(nextConfig);
`
);
// deleting `NODE_ENV` value, so that it's `undefined`, and not `"test"`
// by the time it reaches the build executor.
// this simulates existing behaviour of running a next.js build executor via Nx
delete process.env.NODE_ENV;
const result = runCLI(`build ${appName}`);
checkFilesExist(`dist/apps/${appName}/next.config.js`);
expect(result).toContain('NODE_ENV is production');
updateFile(
`apps/${appName}/next.config.js`,
`
const { withNx } = require('@nx/next');
// Not including "nx" entry should still work.
const nextConfig = {};
module.exports = withNx(nextConfig);
`
);
rmDist();
runCLI(`build ${appName}`);
checkFilesExist(`dist/apps/${appName}/next.config.js`);
// Make sure withNx works with run-commands.
updateJson(join('apps', appName, 'project.json'), (json) => {
json.targets.build = {
command: 'npx next build',
outputs: [`{projectRoot}/.next`],
options: {
cwd: `apps/${appName}`,
},
};
return json;
});
expect(() => {
runCLI(`build ${appName}`);
}).not.toThrow();
checkFilesExist(`dist/apps/${appName}/.next/build-manifest.json`);
}, 300_000);
});