chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
/* eslint-disable */
|
||||
module.exports = {
|
||||
transform: {
|
||||
'^.+\\.[tj]sx?$': ['ts-jest', { tsconfig: '<rootDir>/tsconfig.spec.json' }],
|
||||
},
|
||||
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'],
|
||||
maxWorkers: 1,
|
||||
globals: {},
|
||||
globalSetup: '../utils/global-setup.ts',
|
||||
globalTeardown: '../utils/global-teardown.ts',
|
||||
displayName: 'e2e-webpack',
|
||||
preset: '../jest.preset.e2e.js',
|
||||
};
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"name": "@nx/e2e-webpack",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@nx/e2e-utils": "workspace:*"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"name": "e2e-webpack",
|
||||
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
||||
"sourceRoot": "e2e/webpack",
|
||||
"projectType": "application",
|
||||
"implicitDependencies": ["webpack"],
|
||||
"// targets": "to see all targets run: nx show project e2e-webpack --web",
|
||||
"targets": {}
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
||||
|
||||
exports[`Webpack Plugin (legacy) ConvertConfigToWebpackPlugin, should convert withNx webpack config to a standard config using NxWebpackPlugin 1`] = `
|
||||
"const { NxAppWebpackPlugin } = require('@nx/webpack/app-plugin');
|
||||
const { NxReactWebpackPlugin } = require('@nx/react/webpack-plugin');
|
||||
const { useLegacyNxPlugin } = require('@nx/webpack');
|
||||
|
||||
// This file was migrated using @nx/webpack:convert-config-to-webpack-plugin from your './webpack.config.old.js'
|
||||
// Please check that the options here are correct as they were moved from the old webpack.config.js to this file.
|
||||
const options = {};
|
||||
|
||||
/**
|
||||
* @type{import('webpack').WebpackOptionsNormalized}
|
||||
*/
|
||||
module.exports = async () => ({
|
||||
plugins: [
|
||||
new NxAppWebpackPlugin(),
|
||||
new NxReactWebpackPlugin({
|
||||
// Uncomment this line if you don't want to use SVGR
|
||||
// See: https://react-svgr.com/
|
||||
// svgr: false
|
||||
}),
|
||||
// NOTE: useLegacyNxPlugin ensures that the non-standard Webpack configuration file previously used still works.
|
||||
// To remove its usage, move options such as "plugins" into this file as standard Webpack configuration options.
|
||||
// To enhance configurations after Nx plugins have applied, you can add a new plugin with the \\\`apply\\\` method.
|
||||
// e.g. \\\`{ apply: (compiler) => { /* modify compiler.options */ }\\\`
|
||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
await useLegacyNxPlugin(require('./webpack.config.old.js'), options),
|
||||
],
|
||||
});
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`Webpack Plugin (legacy) ConvertConfigToWebpackPlugin, should convert withNx webpack config to a standard config using NxWebpackPlugin 2`] = `
|
||||
"{
|
||||
"name": "app3224373",
|
||||
"$schema": "../node_modules/nx/schemas/project-schema.json",
|
||||
"projectType": "application",
|
||||
"sourceRoot": "app3224373/src",
|
||||
"tags": [],
|
||||
"targets": {
|
||||
"build": {
|
||||
"executor": "@nx/webpack:webpack",
|
||||
"outputs": ["{options.outputPath}"],
|
||||
"defaultConfiguration": "production",
|
||||
"options": {
|
||||
"target": "web",
|
||||
"outputPath": "dist/app3224373",
|
||||
"compiler": "swc",
|
||||
"main": "app3224373/src/main.ts",
|
||||
"tsConfig": "app3224373/tsconfig.app.json",
|
||||
"webpackConfig": "app3224373/webpack.config.js",
|
||||
"assets": ["app3224373/src/favicon.ico", "app3224373/src/assets"],
|
||||
"index": "app3224373/src/index.html",
|
||||
"baseHref": "/",
|
||||
"styles": ["app3224373/src/styles.css"],
|
||||
"scripts": [],
|
||||
"standardWebpackConfigFunction": true
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"optimization": true,
|
||||
"outputHashing": "all",
|
||||
"sourceMap": false,
|
||||
"namedChunks": false,
|
||||
"extractLicenses": true,
|
||||
"vendorChunk": false,
|
||||
"fileReplacements": [
|
||||
{
|
||||
"replace": "app3224373/src/environments/environment.ts",
|
||||
"with": "app3224373/src/environments/environment.prod.ts"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"serve": {
|
||||
"executor": "@nx/webpack:dev-server",
|
||||
"options": {
|
||||
"buildTarget": "app3224373:build"
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"buildTarget": "app3224373:build:production"
|
||||
}
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"executor": "@nx/eslint:lint"
|
||||
},
|
||||
"test": {
|
||||
"executor": "@nx/vitest:test",
|
||||
"outputs": ["{options.reportsDirectory}"],
|
||||
"options": {
|
||||
"reportsDirectory": "coverage/app3224373"
|
||||
}
|
||||
},
|
||||
"serve-static": {
|
||||
"executor": "@nx/web:file-server",
|
||||
"dependsOn": ["build"],
|
||||
"options": {
|
||||
"buildTarget": "app3224373:build",
|
||||
"spa": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`Webpack Plugin (legacy) ConvertConfigToWebpackPlugin, should convert withNx webpack config to a standard config using NxWebpackPlugin 3`] = `
|
||||
"const { composePlugins } = require('@nx/webpack');
|
||||
// Nx plugins for webpack.
|
||||
module.exports = composePlugins((config) => {
|
||||
// Update the webpack config as needed here.
|
||||
// e.g. \`config.plugins.push(new MyPlugin())\`
|
||||
config.output.clean = true;
|
||||
return config;
|
||||
});
|
||||
"
|
||||
`;
|
||||
@@ -0,0 +1,205 @@
|
||||
import {
|
||||
checkFilesExist,
|
||||
cleanupProject,
|
||||
killProcessAndPorts,
|
||||
newProject,
|
||||
readFile,
|
||||
reservePort,
|
||||
runCLI,
|
||||
runCommandUntil,
|
||||
runE2ETests,
|
||||
uniq,
|
||||
updateFile,
|
||||
} from '@nx/e2e-utils';
|
||||
import { ChildProcess } from 'child_process';
|
||||
|
||||
describe('Webpack Plugin (legacy)', () => {
|
||||
let originalAddPluginsEnv: string | undefined;
|
||||
const appName = uniq('app');
|
||||
const libName = uniq('lib');
|
||||
|
||||
beforeAll(() => {
|
||||
originalAddPluginsEnv = process.env.NX_ADD_PLUGINS;
|
||||
process.env.NX_ADD_PLUGINS = 'false';
|
||||
newProject({
|
||||
packages: [
|
||||
'@nx/react',
|
||||
'@nx/webpack',
|
||||
'@nx/cypress',
|
||||
'@nx/playwright',
|
||||
'@nx/jest',
|
||||
'@nx/vite',
|
||||
'@nx/vitest',
|
||||
'@nx/eslint',
|
||||
],
|
||||
});
|
||||
runCLI(
|
||||
`generate @nx/react:app ${appName} --bundler webpack --e2eTestRunner=cypress --rootProject --no-interactive --unitTestRunner=jest --linter=eslint`
|
||||
);
|
||||
runCLI(
|
||||
`generate @nx/react:lib ${libName} --unitTestRunner jest --no-interactive --linter=eslint`
|
||||
);
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
process.env.NX_ADD_PLUGINS = originalAddPluginsEnv;
|
||||
cleanupProject();
|
||||
});
|
||||
|
||||
it('should generate, build, and serve React applications and libraries', () => {
|
||||
expect(() => runCLI(`test ${appName}`)).not.toThrow();
|
||||
expect(() => runCLI(`test ${libName}`)).not.toThrow();
|
||||
|
||||
// TODO: figure out why this test hangs in CI (maybe down to sudo prompt?)
|
||||
// expect(() => runCLI(`build ${appName}`)).not.toThrow();
|
||||
|
||||
// if (runE2ETests()) {
|
||||
// runCLI(`e2e ${appName}-e2e --watch=false --verbose`);
|
||||
// }
|
||||
}, 500_000);
|
||||
|
||||
it('should run serve-static', async () => {
|
||||
let process: ChildProcess;
|
||||
const port = await reservePort();
|
||||
|
||||
try {
|
||||
process = await runCommandUntil(
|
||||
`serve-static ${appName} --port=${port}`,
|
||||
(output) => {
|
||||
return output.includes(`http://localhost:${port}`);
|
||||
}
|
||||
);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
|
||||
// port and process cleanup
|
||||
if (process && process.pid) {
|
||||
await killProcessAndPorts(process.pid, port);
|
||||
}
|
||||
});
|
||||
|
||||
// Issue: https://github.com/nrwl/nx/issues/20179
|
||||
it('should allow main/styles entries to be spread within composePlugins() function (#20179)', () => {
|
||||
const appName = uniq('app');
|
||||
runCLI(
|
||||
`generate @nx/web:app ${appName} --bundler webpack --unitTestRunner=jest --linter=eslint`
|
||||
);
|
||||
|
||||
checkFilesExist(`${appName}/src/main.ts`);
|
||||
updateFile(`${appName}/src/main.ts`, `console.log('Hello');\n`);
|
||||
|
||||
updateFile(
|
||||
`${appName}/webpack.config.js`,
|
||||
`
|
||||
const { composePlugins, withNx, withWeb } = require('@nx/webpack');
|
||||
module.exports = composePlugins(withNx(), withWeb(), (config) => {
|
||||
config.output.clean = true;
|
||||
return {
|
||||
...config,
|
||||
entry: {
|
||||
main: [...config.entry.main],
|
||||
styles: [...config.entry.styles],
|
||||
}
|
||||
};
|
||||
});
|
||||
`
|
||||
);
|
||||
|
||||
expect(() => {
|
||||
runCLI(`build ${appName} --outputHashing none`);
|
||||
}).not.toThrow();
|
||||
checkFilesExist(`dist/${appName}/styles.css`);
|
||||
|
||||
expect(() => {
|
||||
runCLI(`build ${appName} --outputHashing none --extractCss false`);
|
||||
}).not.toThrow();
|
||||
expect(() => {
|
||||
checkFilesExist(`dist/${appName}/styles.css`);
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
it('should support standard webpack config with executors', () => {
|
||||
const appName = uniq('app');
|
||||
runCLI(
|
||||
`generate @nx/web:app ${appName} --bundler webpack --e2eTestRunner=playwright --unitTestRunner=jest --linter=eslint`
|
||||
);
|
||||
updateFile(
|
||||
`${appName}/src/main.ts`,
|
||||
`
|
||||
document.querySelector('proj-root')!.innerHTML = '<h1>Welcome</h1>';
|
||||
`
|
||||
);
|
||||
updateFile(
|
||||
`${appName}/webpack.config.js`,
|
||||
`
|
||||
const { join } = require('path');
|
||||
const {NxAppWebpackPlugin} = require('@nx/webpack/app-plugin');
|
||||
module.exports = {
|
||||
output: {
|
||||
path: join(__dirname, '../dist/${appName}'),
|
||||
},
|
||||
plugins: [
|
||||
new NxAppWebpackPlugin({
|
||||
main: './src/main.ts',
|
||||
compiler: 'tsc',
|
||||
index: './src/index.html',
|
||||
tsConfig: './tsconfig.app.json',
|
||||
})
|
||||
]
|
||||
};
|
||||
`
|
||||
);
|
||||
|
||||
expect(() => {
|
||||
runCLI(`build ${appName} --outputHashing none`);
|
||||
}).not.toThrow();
|
||||
|
||||
if (runE2ETests()) {
|
||||
expect(() => {
|
||||
runCLI(`e2e ${appName}-e2e`);
|
||||
}).not.toThrow();
|
||||
}
|
||||
});
|
||||
|
||||
describe('ConvertConfigToWebpackPlugin,', () => {
|
||||
it('should convert withNx webpack config to a standard config using NxWebpackPlugin', () => {
|
||||
const appName = 'app3224373'; // Needs to be reserved so that the snapshot projectName matches
|
||||
runCLI(
|
||||
`generate @nx/web:app ${appName} --bundler webpack --e2eTestRunner=playwright --unitTestRunner=vitest --linter=eslint`
|
||||
);
|
||||
updateFile(
|
||||
`${appName}/src/main.ts`,
|
||||
`
|
||||
const root = document.querySelector('proj-root');
|
||||
if(root) {
|
||||
root.innerHTML = '<h1>Welcome</h1>'
|
||||
}
|
||||
`
|
||||
);
|
||||
|
||||
runCLI(
|
||||
`generate @nx/webpack:convert-config-to-webpack-plugin --project ${appName}`
|
||||
);
|
||||
|
||||
const webpackConfig = readFile(`${appName}/webpack.config.js`);
|
||||
const oldWebpackConfig = readFile(`${appName}/webpack.config.old.js`);
|
||||
const projectJSON = readFile(`${appName}/project.json`);
|
||||
|
||||
expect(webpackConfig).toMatchSnapshot();
|
||||
expect(projectJSON).toMatchSnapshot(); // This file should be updated adding standardWebpackConfigFunction: true
|
||||
|
||||
expect(oldWebpackConfig).toMatchSnapshot(); // This file should be renamed and updated to not include `withNx`, `withReact`, and `withWeb`.
|
||||
|
||||
expect(() => {
|
||||
runCLI(`build ${appName}`);
|
||||
}).not.toThrow();
|
||||
|
||||
if (runE2ETests()) {
|
||||
expect(() => {
|
||||
runCLI(`e2e ${appName}-e2e`);
|
||||
}).not.toThrow();
|
||||
}
|
||||
}, 600_000);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,673 @@
|
||||
import {
|
||||
checkFilesExist,
|
||||
cleanupProject,
|
||||
createFile,
|
||||
fileExists,
|
||||
listFiles,
|
||||
newProject,
|
||||
packageInstall,
|
||||
readFile,
|
||||
rmDist,
|
||||
runCLI,
|
||||
runCommand,
|
||||
uniq,
|
||||
updateFile,
|
||||
updateJson,
|
||||
} from '@nx/e2e-utils';
|
||||
import { join } from 'path';
|
||||
|
||||
describe('Webpack Plugin', () => {
|
||||
beforeAll(() =>
|
||||
newProject({ packages: ['@nx/webpack', '@nx/js', '@nx/react', '@nx/web'] })
|
||||
);
|
||||
afterAll(() => cleanupProject());
|
||||
|
||||
it('should be able to setup project to build node programs with webpack and different compilers', async () => {
|
||||
const myPkg = uniq('my-pkg');
|
||||
runCLI(
|
||||
`generate @nx/js:lib ${myPkg} --directory=libs/${myPkg} --bundler=none`
|
||||
);
|
||||
updateFile(`libs/${myPkg}/src/index.ts`, `console.log('Hello');\n`);
|
||||
|
||||
runCLI(
|
||||
`generate @nx/webpack:configuration ${myPkg} --target=node --tsConfig=libs/${myPkg}/tsconfig.lib.json --main=libs/${myPkg}/src/index.ts`
|
||||
);
|
||||
|
||||
// Test `scriptType` later during during.
|
||||
updateFile(
|
||||
`libs/${myPkg}/webpack.config.js`,
|
||||
`
|
||||
const path = require('path');
|
||||
const { NxAppWebpackPlugin } = require('@nx/webpack/app-plugin');
|
||||
|
||||
class DebugPlugin {
|
||||
apply(compiler) {
|
||||
console.log('scriptType is ' + compiler.options.output.scriptType);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
target: 'node',
|
||||
output: {
|
||||
path: path.join(__dirname, '../../dist/libs/${myPkg}')
|
||||
},
|
||||
plugins: [
|
||||
new NxAppWebpackPlugin({
|
||||
compiler: 'tsc',
|
||||
main: './src/index.ts',
|
||||
tsConfig: './tsconfig.lib.json',
|
||||
outputHashing: 'none',
|
||||
optimization: false,
|
||||
}),
|
||||
new DebugPlugin()
|
||||
]
|
||||
};`
|
||||
);
|
||||
|
||||
rmDist();
|
||||
|
||||
const buildOutput = runCLI(`build ${myPkg}`);
|
||||
// Ensure scriptType is not set if we're in Node (it only applies to Web).
|
||||
expect(buildOutput).toContain('scriptType is undefined');
|
||||
let output = runCommand(`node dist/libs/${myPkg}/main.js`);
|
||||
expect(output).toMatch(/Hello/);
|
||||
expect(output).not.toMatch(/Conflicting/);
|
||||
expect(output).not.toMatch(/process.env.NODE_ENV/);
|
||||
|
||||
updateJson(join('libs', myPkg, 'project.json'), (config) => {
|
||||
delete config.targets.build;
|
||||
return config;
|
||||
});
|
||||
|
||||
// swc
|
||||
runCLI(
|
||||
`generate @nx/webpack:configuration ${myPkg} --target=node --tsConfig=libs/${myPkg}/tsconfig.lib.json --main=libs/${myPkg}/src/index.ts --compiler=swc`
|
||||
);
|
||||
rmDist();
|
||||
runCLI(`build ${myPkg}`);
|
||||
output = runCommand(`node dist/libs/${myPkg}/main.js`);
|
||||
expect(output).toMatch(/Hello/);
|
||||
|
||||
updateJson(join('libs', myPkg, 'project.json'), (config) => {
|
||||
delete config.targets.build;
|
||||
return config;
|
||||
});
|
||||
|
||||
// tsc
|
||||
runCLI(
|
||||
`generate @nx/webpack:configuration ${myPkg} --target=node --tsConfig=libs/${myPkg}/tsconfig.lib.json --main=libs/${myPkg}/src/index.ts --compiler=tsc`
|
||||
);
|
||||
rmDist();
|
||||
runCLI(`build ${myPkg}`);
|
||||
output = runCommand(`node dist/libs/${myPkg}/main.js`);
|
||||
expect(output).toMatch(/Hello/);
|
||||
}, 500000);
|
||||
|
||||
it('should use either BABEL_ENV or NODE_ENV value for Babel environment configuration', async () => {
|
||||
const myPkg = uniq('my-pkg');
|
||||
runCLI(
|
||||
`generate @nx/js:lib ${myPkg} --directory=libs/${myPkg} --bundler=none`
|
||||
);
|
||||
updateFile(`libs/${myPkg}/src/index.ts`, `console.log('Hello');\n`);
|
||||
|
||||
runCLI(
|
||||
`generate @nx/webpack:configuration ${myPkg} --target=node --compiler=babel --tsConfig=libs/${myPkg}/tsconfig.lib.json --main=libs/${myPkg}/src/index.ts`
|
||||
);
|
||||
|
||||
updateFile(
|
||||
`libs/${myPkg}/.babelrc`,
|
||||
`{ 'presets': ['@nx/js/babel', './custom-preset'] } `
|
||||
);
|
||||
updateFile(
|
||||
`libs/${myPkg}/custom-preset.js`,
|
||||
`
|
||||
module.exports = function(api, opts) {
|
||||
console.log('Babel env is ' + api.env());
|
||||
return opts;
|
||||
}
|
||||
`
|
||||
);
|
||||
|
||||
let output = runCLI(`build ${myPkg}`, {
|
||||
env: {
|
||||
NODE_ENV: 'nodeEnv',
|
||||
BABEL_ENV: 'babelEnv',
|
||||
},
|
||||
});
|
||||
expect(output).toContain('Babel env is babelEnv');
|
||||
}, 500_000);
|
||||
|
||||
it('should be able to build with NxWebpackPlugin and a standard webpack config file', () => {
|
||||
const appName = uniq('app');
|
||||
runCLI(
|
||||
`generate @nx/web:app ${appName} --bundler webpack --directory=apps/${appName}`
|
||||
);
|
||||
updateFile(`apps/${appName}/src/main.ts`, `console.log('Hello');\n`);
|
||||
updateFile(`apps/${appName}/src/foo.ts`, `console.log('Foo');\n`);
|
||||
updateFile(`apps/${appName}/src/bar.ts`, `console.log('Bar');\n`);
|
||||
|
||||
updateFile(
|
||||
`apps/${appName}/webpack.config.js`,
|
||||
`
|
||||
const path = require('path');
|
||||
const { NxAppWebpackPlugin } = require('@nx/webpack/app-plugin');
|
||||
|
||||
module.exports = {
|
||||
target: 'node',
|
||||
output: {
|
||||
path: path.join(__dirname, '../../dist/apps/${appName}'),
|
||||
// do not remove dist, so files between builds will remain
|
||||
clean: false,
|
||||
},
|
||||
plugins: [
|
||||
new NxAppWebpackPlugin({
|
||||
compiler: 'tsc',
|
||||
main: './src/main.ts',
|
||||
additionalEntryPoints: [
|
||||
'./src/foo.ts',
|
||||
{
|
||||
entryName: 'bar',
|
||||
entryPath: './src/bar.ts',
|
||||
}
|
||||
],
|
||||
tsConfig: './tsconfig.app.json',
|
||||
outputHashing: 'none',
|
||||
optimization: false,
|
||||
})
|
||||
]
|
||||
};`
|
||||
);
|
||||
|
||||
runCLI(`build ${appName}`);
|
||||
|
||||
expect(runCommand(`node dist/apps/${appName}/main.js`)).toMatch(/Hello/);
|
||||
expect(runCommand(`node dist/apps/${appName}/foo.js`)).toMatch(/Foo/);
|
||||
expect(runCommand(`node dist/apps/${appName}/bar.js`)).toMatch(/Bar/);
|
||||
|
||||
// Ensure dist is not removed between builds since output.clean === false
|
||||
createFile(`dist/apps/${appName}/extra.js`);
|
||||
runCLI(`build ${appName} --skip-nx-cache`);
|
||||
checkFilesExist(`dist/apps/${appName}/extra.js`);
|
||||
}, 500_000);
|
||||
|
||||
it('should bundle in NX_PUBLIC_ environment variables', () => {
|
||||
const appName = uniq('app');
|
||||
runCLI(
|
||||
`generate @nx/web:app ${appName} --directory=apps/${appName} --bundler webpack`
|
||||
);
|
||||
|
||||
checkFilesExist(`apps/${appName}/src/main.ts`);
|
||||
updateFile(
|
||||
`apps/${appName}/src/main.ts`,
|
||||
`
|
||||
console.log(process.env['NX_PUBLIC_TEST']);
|
||||
`
|
||||
);
|
||||
|
||||
runCLI(`build ${appName}`, {
|
||||
env: {
|
||||
NX_PUBLIC_TEST: 'foobar',
|
||||
},
|
||||
});
|
||||
|
||||
const mainFile = listFiles(`dist/apps/${appName}`).filter((f) =>
|
||||
f.startsWith('main.')
|
||||
);
|
||||
const content = readFile(`dist/apps/${appName}/${mainFile}`);
|
||||
expect(content).toMatch(/foobar/);
|
||||
});
|
||||
|
||||
it('should support babel + core-js to polyfill JS features', async () => {
|
||||
const appName = uniq('app');
|
||||
runCLI(
|
||||
`generate @nx/web:app ${appName} --directory=apps/${appName} --bundler webpack --compiler=babel`
|
||||
);
|
||||
packageInstall('core-js', undefined, '3.26.1', 'prod');
|
||||
|
||||
checkFilesExist(`apps/${appName}/src/main.ts`);
|
||||
updateFile(
|
||||
`apps/${appName}/src/main.ts`,
|
||||
`
|
||||
import 'core-js/stable';
|
||||
async function main() {
|
||||
const result = await Promise.resolve('foobar')
|
||||
console.log(result);
|
||||
}
|
||||
main();
|
||||
`
|
||||
);
|
||||
|
||||
// Modern browser
|
||||
updateFile(`apps/${appName}/.browserslistrc`, `last 1 Chrome version\n`);
|
||||
runCLI(`build ${appName}`);
|
||||
expect(readMainFile(`dist/apps/${appName}`)).toMatch(`await Promise`);
|
||||
|
||||
// Legacy browser
|
||||
updateFile(`apps/${appName}/.browserslistrc`, `IE 11\n`);
|
||||
runCLI(`build ${appName}`);
|
||||
expect(readMainFile(`dist/apps/${appName}`)).not.toMatch(`await Promise`);
|
||||
});
|
||||
|
||||
it('should allow options to be passed from the executor', async () => {
|
||||
const appName = uniq('app');
|
||||
runCLI(
|
||||
`generate @nx/web:app ${appName} --directory=apps/${appName} --bundler webpack`
|
||||
);
|
||||
|
||||
checkFilesExist(`apps/${appName}/project.json`);
|
||||
updateJson(`apps/${appName}/project.json`, (json) => {
|
||||
json.targets.build = {
|
||||
executor: '@nx/webpack:webpack',
|
||||
outputs: ['{options.outputPath}'],
|
||||
options: {
|
||||
generatePackageJson: true, // This should be passed to the plugin.
|
||||
outputPath: `dist/apps/${appName}`,
|
||||
webpackConfig: `apps/${appName}/webpack.config.js`,
|
||||
},
|
||||
};
|
||||
return json;
|
||||
});
|
||||
|
||||
checkFilesExist(`apps/${appName}/webpack.config.js`);
|
||||
updateFile(
|
||||
`apps/${appName}/webpack.config.js`,
|
||||
`
|
||||
const { NxAppWebpackPlugin } = require('@nx/webpack/app-plugin');
|
||||
const { join } = require('path');
|
||||
module.exports = {
|
||||
output: {
|
||||
path: join(__dirname, '../../dist/apps/demo'),
|
||||
},
|
||||
plugins: [
|
||||
new NxAppWebpackPlugin({
|
||||
// NOTE: generatePackageJson is missing here, but executor passes it.
|
||||
target: 'web',
|
||||
compiler: 'swc',
|
||||
main: './src/main.ts',
|
||||
tsConfig: './tsconfig.app.json',
|
||||
optimization: false,
|
||||
outputHashing: 'none',
|
||||
}),
|
||||
],
|
||||
};`
|
||||
);
|
||||
|
||||
runCLI(`build ${appName}`);
|
||||
|
||||
fileExists(`dist/apps/${appName}/package.json`);
|
||||
});
|
||||
|
||||
it('should resolve assets from executors as relative to workspace root', () => {
|
||||
const appName = uniq('app');
|
||||
runCLI(
|
||||
`generate @nx/web:app ${appName} --directory=apps/${appName} --bundler webpack`
|
||||
);
|
||||
updateFile('shared/docs/TEST.md', 'TEST');
|
||||
updateJson(`apps/${appName}/project.json`, (json) => {
|
||||
json.targets.build = {
|
||||
executor: '@nx/webpack:webpack',
|
||||
outputs: ['{options.outputPath}'],
|
||||
options: {
|
||||
assets: [
|
||||
{
|
||||
input: 'shared/docs',
|
||||
glob: 'TEST.md',
|
||||
output: '.',
|
||||
},
|
||||
],
|
||||
outputPath: `dist/apps/${appName}`,
|
||||
webpackConfig: `apps/${appName}/webpack.config.js`,
|
||||
},
|
||||
};
|
||||
return json;
|
||||
});
|
||||
|
||||
runCLI(`build ${appName}`);
|
||||
|
||||
checkFilesExist(`dist/apps/${appName}/TEST.md`);
|
||||
});
|
||||
|
||||
it('it should support building libraries and apps when buildLibsFromSource is false', () => {
|
||||
const appName = uniq('app');
|
||||
const myPkg = uniq('my-pkg');
|
||||
|
||||
runCLI(
|
||||
`generate @nx/web:application ${appName} --directory=apps/${appName} --bundler=webpack`
|
||||
);
|
||||
|
||||
runCLI(
|
||||
`generate @nx/js:lib ${myPkg} --directory=libs/${myPkg} --importPath=@${appName}/${myPkg}`
|
||||
);
|
||||
|
||||
updateFile(`libs/${myPkg}/src/index.ts`, `export const foo = 'bar';\n`);
|
||||
|
||||
updateFile(
|
||||
`apps/${appName}/src/main.ts`,
|
||||
`import { foo } from '@${appName}/${myPkg}';\nconsole.log(foo);\n`
|
||||
);
|
||||
|
||||
updateFile(
|
||||
`apps/${appName}/webpack.config.js`,
|
||||
`
|
||||
const path = require('path');
|
||||
const { NxAppWebpackPlugin } = require('@nx/webpack/app-plugin');
|
||||
|
||||
module.exports = {
|
||||
target: 'node',
|
||||
output: {
|
||||
path: path.join(__dirname, '../../dist/${appName}')
|
||||
},
|
||||
plugins: [
|
||||
new NxAppWebpackPlugin({
|
||||
compiler: 'tsc',
|
||||
main: 'apps/${appName}/src/main.ts',
|
||||
tsConfig: 'apps/${appName}/tsconfig.app.json',
|
||||
outputHashing: 'none',
|
||||
optimization: false,
|
||||
buildLibsFromSource: false,
|
||||
})
|
||||
]
|
||||
};`
|
||||
);
|
||||
|
||||
const result = runCLI(`build ${appName}`);
|
||||
|
||||
expect(result).toContain(
|
||||
`Running target build for project ${appName} and 1 task it depends on`
|
||||
);
|
||||
expect(result).toContain(`nx run ${myPkg}:build`);
|
||||
expect(result).toContain(
|
||||
`Successfully ran target build for project ${appName} and 1 task it depends on`
|
||||
);
|
||||
});
|
||||
|
||||
it('should build a tsc app that imports a workspace lib from source', () => {
|
||||
// Regression for #35017: ts-loader 9.5.7+ forwards the tsconfig rootDir to
|
||||
// transpileModule, so lib sources bundled from source (outside the app
|
||||
// rootDir) failed with TS6059.
|
||||
const appName = uniq('app');
|
||||
const myPkg = uniq('my-pkg');
|
||||
|
||||
runCLI(
|
||||
`generate @nx/web:application ${appName} --directory=apps/${appName} --bundler=webpack`
|
||||
);
|
||||
|
||||
runCLI(
|
||||
`generate @nx/js:lib ${myPkg} --directory=libs/${myPkg} --importPath=@${appName}/${myPkg}`
|
||||
);
|
||||
|
||||
updateFile(`libs/${myPkg}/src/index.ts`, `export const foo = 'bar';\n`);
|
||||
|
||||
updateFile(
|
||||
`apps/${appName}/src/main.ts`,
|
||||
`import { foo } from '@${appName}/${myPkg}';\nconsole.log(foo);\n`
|
||||
);
|
||||
|
||||
updateFile(
|
||||
`apps/${appName}/webpack.config.js`,
|
||||
`
|
||||
const path = require('path');
|
||||
const { NxAppWebpackPlugin } = require('@nx/webpack/app-plugin');
|
||||
|
||||
module.exports = {
|
||||
target: 'node',
|
||||
output: {
|
||||
path: path.join(__dirname, '../../dist/${appName}')
|
||||
},
|
||||
plugins: [
|
||||
new NxAppWebpackPlugin({
|
||||
compiler: 'tsc',
|
||||
main: 'apps/${appName}/src/main.ts',
|
||||
tsConfig: 'apps/${appName}/tsconfig.app.json',
|
||||
outputHashing: 'none',
|
||||
optimization: false,
|
||||
})
|
||||
]
|
||||
};`
|
||||
);
|
||||
|
||||
const result = runCLI(`build ${appName}`);
|
||||
|
||||
expect(result).not.toContain('TS6059');
|
||||
expect(result).toContain(
|
||||
`Successfully ran target build for project ${appName}`
|
||||
);
|
||||
});
|
||||
|
||||
it('should be able to support webpack config with nx enhanced and babel', () => {
|
||||
const appName = uniq('app');
|
||||
|
||||
runCLI(
|
||||
`generate @nx/web:app ${appName} --directory=apps/${appName} --bundler=webpack --compiler=babel`
|
||||
);
|
||||
|
||||
updateFile(
|
||||
`apps/${appName}/webpack.config.js`,
|
||||
`
|
||||
const { composePlugins, withNx } = require('@nx/webpack');
|
||||
const { withReact } = require('@nx/react');
|
||||
const { join } = require('path');
|
||||
|
||||
const pluginOption = {
|
||||
index: 'apps/${appName}/src/index.html',
|
||||
main: 'apps/${appName}/src/main.ts',
|
||||
tsConfig: 'apps/${appName}/tsconfig.app.json',
|
||||
outputPath: 'dist/apps/${appName}',
|
||||
}
|
||||
|
||||
// Nx composable plugins for webpack.
|
||||
module.exports = composePlugins(
|
||||
withNx(pluginOption),
|
||||
withReact(pluginOption),
|
||||
);`
|
||||
);
|
||||
|
||||
const result = runCLI(`build ${appName}`);
|
||||
|
||||
expect(result).toContain(`nx run ${appName}:build`);
|
||||
expect(result).toContain(
|
||||
`Successfully ran target build for project ${appName}`
|
||||
);
|
||||
});
|
||||
|
||||
describe('config types', () => {
|
||||
it('should support a standard config object', () => {
|
||||
const appName = uniq('app');
|
||||
|
||||
runCLI(
|
||||
`generate @nx/react:application --directory=apps/${appName} --bundler=webpack --e2eTestRunner=none`
|
||||
);
|
||||
|
||||
updateFile(
|
||||
`apps/${appName}/webpack.config.js`,
|
||||
`
|
||||
const path = require('path');
|
||||
const { NxAppWebpackPlugin } = require('@nx/webpack/app-plugin');
|
||||
|
||||
module.exports = {
|
||||
target: 'node',
|
||||
output: {
|
||||
path: path.join(__dirname, '../../dist/${appName}')
|
||||
},
|
||||
plugins: [
|
||||
new NxAppWebpackPlugin({
|
||||
compiler: 'babel',
|
||||
main: './src/main.tsx',
|
||||
tsConfig: './tsconfig.app.json',
|
||||
outputHashing: 'none',
|
||||
optimization: false,
|
||||
})
|
||||
]
|
||||
};`
|
||||
);
|
||||
|
||||
const result = runCLI(`build ${appName}`);
|
||||
|
||||
expect(result).toContain(
|
||||
`Successfully ran target build for project ${appName}`
|
||||
);
|
||||
});
|
||||
|
||||
it('should support a standard function that returns a config object', () => {
|
||||
const appName = uniq('app');
|
||||
|
||||
runCLI(
|
||||
`generate @nx/react:application --directory=apps/${appName} --bundler=webpack --e2eTestRunner=none`
|
||||
);
|
||||
|
||||
updateFile(
|
||||
`apps/${appName}/webpack.config.js`,
|
||||
`
|
||||
const path = require('path');
|
||||
const { NxAppWebpackPlugin } = require('@nx/webpack/app-plugin');
|
||||
|
||||
module.exports = () => {
|
||||
return {
|
||||
target: 'node',
|
||||
output: {
|
||||
path: path.join(__dirname, '../../dist/${appName}')
|
||||
},
|
||||
plugins: [
|
||||
new NxAppWebpackPlugin({
|
||||
compiler: 'tsc',
|
||||
main: './src/main.tsx',
|
||||
tsConfig: './tsconfig.app.json',
|
||||
outputHashing: 'none',
|
||||
optimization: false,
|
||||
})
|
||||
]
|
||||
};
|
||||
};`
|
||||
);
|
||||
|
||||
const result = runCLI(`build ${appName}`);
|
||||
expect(result).toContain(
|
||||
`Successfully ran target build for project ${appName}`
|
||||
);
|
||||
});
|
||||
|
||||
it('should support an array of standard config objects', () => {
|
||||
const appName = uniq('app');
|
||||
const serverName = uniq('server');
|
||||
|
||||
runCLI(
|
||||
`generate @nx/react:application --directory=apps/${appName} --bundler=webpack --e2eTestRunner=none`
|
||||
);
|
||||
|
||||
// Create server index file
|
||||
createFile(
|
||||
`apps/${serverName}/index.js`,
|
||||
`console.log('Hello from ${serverName}');\n`
|
||||
);
|
||||
|
||||
updateFile(
|
||||
`apps/${appName}/webpack.config.js`,
|
||||
`
|
||||
const path = require('path');
|
||||
const { NxAppWebpackPlugin } = require('@nx/webpack/app-plugin');
|
||||
|
||||
module.exports = [
|
||||
{
|
||||
name: 'client',
|
||||
target: 'node',
|
||||
output: {
|
||||
path: path.join(__dirname, '../../dist/${appName}')
|
||||
},
|
||||
plugins: [
|
||||
new NxAppWebpackPlugin({
|
||||
compiler: 'tsc',
|
||||
main: './src/main.tsx',
|
||||
tsConfig: './tsconfig.app.json',
|
||||
outputHashing: 'none',
|
||||
optimization: false,
|
||||
})
|
||||
]
|
||||
}, {
|
||||
name: 'server',
|
||||
target: 'node',
|
||||
entry: '../${serverName}/index.js',
|
||||
output: {
|
||||
path: path.join(__dirname, '../../dist/${serverName}'),
|
||||
filename: 'index.js',
|
||||
},
|
||||
}
|
||||
];
|
||||
`
|
||||
);
|
||||
|
||||
const result = runCLI(`build ${appName}`);
|
||||
|
||||
checkFilesExist(`dist/${appName}/main.js`);
|
||||
checkFilesExist(`dist/${serverName}/index.js`);
|
||||
|
||||
expect(result).toContain(
|
||||
`Successfully ran target build for project ${appName}`
|
||||
);
|
||||
});
|
||||
|
||||
it('should support a function that returns an array of standard config objects', () => {
|
||||
const appName = uniq('app');
|
||||
const serverName = uniq('server');
|
||||
|
||||
runCLI(
|
||||
`generate @nx/react:application --directory=apps/${appName} --bundler=webpack --e2eTestRunner=none`
|
||||
);
|
||||
|
||||
// Create server index file
|
||||
createFile(
|
||||
`apps/${serverName}/index.js`,
|
||||
`console.log('Hello from ${serverName}');\n`
|
||||
);
|
||||
|
||||
updateFile(
|
||||
`apps/${appName}/webpack.config.js`,
|
||||
`
|
||||
const path = require('path');
|
||||
const { NxAppWebpackPlugin } = require('@nx/webpack/app-plugin');
|
||||
|
||||
module.exports = () => {
|
||||
return [
|
||||
{
|
||||
name: 'client',
|
||||
target: 'node',
|
||||
output: {
|
||||
path: path.join(__dirname, '../../dist/${appName}')
|
||||
},
|
||||
plugins: [
|
||||
new NxAppWebpackPlugin({
|
||||
compiler: 'tsc',
|
||||
main: './src/main.tsx',
|
||||
tsConfig: './tsconfig.app.json',
|
||||
outputHashing: 'none',
|
||||
optimization: false,
|
||||
})
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'server',
|
||||
target: 'node',
|
||||
entry: '../${serverName}/index.js',
|
||||
output: {
|
||||
path: path.join(__dirname, '../../dist/${serverName}'),
|
||||
filename: 'index.js',
|
||||
}
|
||||
}
|
||||
];
|
||||
};`
|
||||
);
|
||||
const result = runCLI(`build ${appName}`);
|
||||
|
||||
checkFilesExist(`dist/${serverName}/index.js`);
|
||||
checkFilesExist(`dist/${appName}/main.js`);
|
||||
|
||||
expect(result).toContain(
|
||||
`Successfully ran target build for project ${appName}`
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function readMainFile(dir: string): string {
|
||||
const main = listFiles(dir).find((f) => f.startsWith('main.'));
|
||||
return readFile(`${dir}/${main}`);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"types": ["node", "jest"]
|
||||
},
|
||||
"include": [],
|
||||
"files": [],
|
||||
"references": [
|
||||
{
|
||||
"path": "../utils"
|
||||
},
|
||||
{
|
||||
"path": "./tsconfig.spec.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "out-tsc/spec",
|
||||
"types": ["jest", "node"]
|
||||
},
|
||||
"exclude": ["out-tsc"],
|
||||
"include": [
|
||||
"**/*.test.ts",
|
||||
"**/*.spec.ts",
|
||||
"**/*.spec.tsx",
|
||||
"**/*.test.tsx",
|
||||
"**/*.spec.js",
|
||||
"**/*.test.js",
|
||||
"**/*.spec.jsx",
|
||||
"**/*.test.jsx",
|
||||
"**/*.d.ts",
|
||||
"jest.config.ts"
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user