nx/packages/cypress/src/plugins/preprocessor.ts
Spencer Elliott 5b6df632cb
fix(core): resolve webpack loaders with require.resolve() (#3436)
* fix(core): resolve webpack loaders with `require.resolve()`

With strict package managers such as pnpm or Yarn PnP, transitive
dependencies are *not* hoisted to the root node_modules folder. This
means that a webpack config defined within a package like
'@nrwl/cypress' cannot resolve loaders like 'ts-loader', unless
'ts-loader' is declared in the workspace's own package.json.

This is a problem because the workspace might define a different version
of 'ts-loader', incompatible with the version declared by
'@nrwl/cypress/package.json'. The workspace should not need to declare
a dependency on 'ts-loader' anyway.

See also:
* https://github.com/pnpm/pnpm/issues/801
* https://github.com/webpack/webpack/issues/5087

* fix(core): resolve absolute 'raw-loader' path

When replacing the 'raw-loader' rule in the `getStylesPartial` function,
check for the absolute path of 'raw-loader' rather than just the name.
2020-08-08 17:53:00 -04:00

60 lines
1.6 KiB
TypeScript

import * as wp from '@cypress/webpack-preprocessor';
import { TsconfigPathsPlugin } from 'tsconfig-paths-webpack-plugin';
import * as nodeExternals from 'webpack-node-externals';
import * as ForkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin';
export function preprocessTypescript(
config: any,
customizeWebpackConfig?: (webpackConfig: any) => any
) {
if (!config.env.tsConfig) {
throw new Error(
'Please provide an absolute path to a tsconfig.json as cypressConfig.env.tsConfig'
);
}
return async (...args) => {
const webpackOptions = customizeWebpackConfig
? customizeWebpackConfig(getWebpackConfig(config))
: getWebpackConfig(config);
return wp({ webpackOptions })(...args);
};
}
export function getWebpackConfig(config: any) {
const extensions = ['.ts', '.tsx', '.mjs', '.js', '.jsx'];
return {
resolve: {
extensions,
plugins: [
new TsconfigPathsPlugin({
configFile: config.env.tsConfig,
extensions,
}),
],
},
module: {
rules: [
{
test: /\.(j|t)sx?$/,
loader: require.resolve('ts-loader'),
exclude: [/node_modules/],
options: {
configFile: config.env.tsConfig,
// https://github.com/TypeStrong/ts-loader/pull/685
experimentalWatchApi: true,
transpileOnly: true,
},
},
],
},
plugins: [
new ForkTsCheckerWebpackPlugin({
tsconfig: config.env.tsConfig,
useTypescriptIncrementalApi: false,
}),
],
externals: [nodeExternals()],
};
}