Open pongells opened 2 years ago
In our case we managed to make the test files compile using the @cypress/webpack-batteries-included-preprocessor and following their example to support typescript as speculated here: https://github.com/cypress-io/cypress/tree/develop/npm/webpack-batteries-included-preprocessor#usage
const webpackPreprocessor = require('@cypress/webpack-batteries-included-preprocessor')
module.exports = (on) => {
on('file:preprocessor', webpackPreprocessor({
typescript: require.resolve('typescript')
}))
}
Not sure why this package can transpile the packages from @angular/cdk
while the default config from cypress cannot, since this is supposed to be the actual default cypress is using to transpile test files if you don't use a custom 'file:preprocessor' at all
Thanks @panagiotis199, it seems to be working and even though it might not be the "proper" solution it's definitely better than nothing! :D
We have the same error with version of Cypress 8.7.0 and latest Angular 13.
I'm seeing the same issue after upgrading to ng 13, except I'm seeing failures loading @angular/core
and @angular/common
. To be clear, I did not require a custom webpack config before upgrading to ng 13, but as of ng 13 an override is required.
I'd already worked through a number of related errors (eg jest also broke after the change to the angular library package format to .mjs files). Here's the fix that worked for me:
yarn add -D ts-loader
// plugins/index.ts
/// <reference types="cypress" />
import webpackPreprocessor from '@cypress/webpack-preprocessor';
import webpackConfig from '../cypress.webpack.config';
...
/**
* @type {Cypress.PluginConfig}
*/
module.exports = async (on: Cypress.PluginEvents, config: Cypress.ResolvedConfigOptions) => {
// ... other prior config
on('file:preprocessor', webpackPreprocessor({
webpackOptions: webpackConfig
}));
return config;
};
// cypress.webpack.config.ts
import path from 'path';
const tsConfigFile = path.resolve(__dirname, './tsconfig.json');
export default {
resolve: {
extensions: ['.ts', '.js', '.mjs']
},
devtool: 'source-map',
module: {
rules: [
{
test: /\.ts$/,
exclude: [ /node_modules/ ],
use: {
loader: 'ts-loader',
options: {
configFile: tsConfigFile
}
}
},
{ // Angular linker needed to link partial-ivy code
// See https://angular.io/guide/creating-libraries#consuming-partial-ivy-code-outside-the-angular-cli
test: /[/\\]@angular[/\\].+\.m?js$/,
use: {
loader: 'babel-loader',
options: {
plugins: ['@angular/compiler-cli/linker/babel'],
compact: false,
cacheDirectory: true
}
}
}
]
}
};
Hopefully the default @cypress/webpack-preprocessor
will be updated soon to handle this scenario, and I can remove this workaround.
I can confirm it happens to me as well, any news here?
I can recreate this issue and confirm it's a bug, although it seems to be a tricky one.
Angular removed the 'main' entries in their package.json files. Generally this is fine because with webpacks mainFiles default, webpack would fall back to the modules
mainFile entry which is defined in the package.json. But for some reason yet to be determined this fails in webpack 4 and webpack only attempts to find the main
entry.
The reason this is corrected by adding the batteries included pre-processor is because cypress currently bundles webpack 4 instead of 5. So when adding the preprocessor and fulfilling the peer dependancies, folks seem to be using webpack 5. With webpack 5 this compilation issue does not occur.
So if you are attempting the work around use webpack 5.
So if you are attempting the workaround use webpack 5. Where should we use webpack 5?
I am not sure what do you mean with this @mjhenkes ,
@johncrim thanks, your workaround helped me a lot 💪
but after putting your code i got this error:
Webpack Compilation Error
Module not found: Error: Can't resolve 'rxjs/operators' in 'C:\projects\[...]\node_modules\@angular\core\fesm2020'
Did you mean 'index.js'?
BREAKING CHANGE: The request 'rxjs/operators' failed to resolve only because it was resolved as fully specified
(probably because the origin is strict EcmaScript Module, e. g. a module with javascript mimetype, a '*.mjs' file, or a '*.js' file where the package.json contains '"type": "module"').
The extension in the request is mandatory for it to be fully specified.
Add the extension to the request.
...
then I had to add resolve->fullySpecified: false to config lines into your webpack config:
{ // Angular linker needed to link partial-ivy code
// See https://angular.io/guide/creating-libraries#consuming-partial-ivy-code-outside-the-angular-cli
test: /[/\\]@angular[/\\].+\.m?js$/,
resolve: {
fullySpecified: false,
},
use: {
loader: 'babel-loader',
options: {
plugins: ['@angular/compiler-cli/linker/babel'],
compact: false,
cacheDirectory: true
}
}
}
Now it's working 🤩
I'm using Nx monorepo and .js files as webpack config & plugins file, so here are my files:
apps\web-e2e\src\plugins\index.js
const webpackPreprocessor = require('@cypress/webpack-preprocessor');
const webpackConfig = require('../../cypress.webpack.config');
module.exports = async (on, config) => {
on('file:preprocessor', webpackPreprocessor({
webpackOptions: webpackConfig
}));
return config;
}
apps\web-e2e\cypress.webpack.config.js
const path = require('path');
const tsConfigFile = path.resolve(__dirname, './tsconfig.e2e.json');
module.exports = {
resolve: {
extensions: ['.ts', '.js', '.mjs']
},
devtool: 'source-map',
module: {
rules: [
{
test: /\.ts$/,
exclude: [ /node_modules/ ],
use: {
loader: 'ts-loader',
options: {
configFile: tsConfigFile
}
}
},
{ // Angular linker needed to link partial-ivy code
// See https://angular.io/guide/creating-libraries#consuming-partial-ivy-code-outside-the-angular-cli
test: /[/\\]@angular[/\\].+\.m?js$/,
resolve: {
fullySpecified: false,
},
use: {
loader: 'babel-loader',
options: {
plugins: ['@angular/compiler-cli/linker/babel'],
compact: false,
cacheDirectory: true
}
}
}
]
}
};
Confirm that @johncrim suggestion works. One thing that you may need to notice is that the version of Webpack should >= 5 in order to support fullySpecified
.
Sadly no solutions there work, adding a custom webpack config breaks all my tsconfig.base.ts
custom paths and I can not use any interface I have defined on the source code.
If I import them directly with ..\..\path\to\source\code
it can also not be resolved.
This is really frustating... All my tests are broken and I can not do anything...
@distante yup, it's one thing that causes the issue. I have to use a relative path instead of the normal path indicated in tsconfig.base.ts
. Not sure why it doesn't work on your end. What is the error after you import them directly?
@distante I run into that issue as well. I assumed the import paths are relative to the e2e project root, but they are relative to the importing file. So for the test file my-project-e2e/src/integration/app.spec.ts
I had to use ../../../../libs/my-lib/src/index
.
Not sure this helps in your case as well.
I've been following this thread for a while but none of the workarounds mentioned here worked for me. I'm wondering whether someone in the cypress team is investigating this, to release a proper fix?
It's been a while since Angular 13 was released, but I can't upgrade the NX project I work on until this is fixed 😢
@aleesaan We are also using NX and the workarounds mentioned here didn't work for us either. However, something that did work was patching the rule that @myflowpl provided into the existing webpack config, rather than writing our own.
(Also check your cypress.json to see where you are meant to be putting the plugin and if you should be using .js or .ts)
Here is our plugin file
module.exports = (on, config) => {
const webpackPreprocessor = require('@cypress/webpack-batteries-included-preprocessor');
const webpackOptions = webpackPreprocessor.defaultOptions.webpackOptions;
webpackOptions.module.rules.unshift({
test: /[/\\]@angular[/\\].+\.m?js$/,
resolve: {
fullySpecified: false,
},
use: {
loader: 'babel-loader',
options: {
plugins: ['@angular/compiler-cli/linker/babel'],
compact: false,
cacheDirectory: true
}
}
});
on('file:preprocessor', webpackPreprocessor({
webpackOptions: webpackOptions,
typescript: require.resolve('typescript')
}));
return config;
};
@noggin182 Thanks for the suggestion, but that didn't work for us either, I'm getting the following error:
Error: Webpack Compilation Error
Module build failed (from ../../node_modules/babel-loader/lib/index.js):
Error: Cannot find module '@angular/compiler-cli/linker/babel' from ...
@noggin182 thanks a lot, it is much simpler and it's working for me 💪 and thanks for suggesting now to change plugins/index.js to .ts files, didn't now that it's in cypress.json
@distante It's working now, with the @noggin182 workaround where you extend, not overwrite webpack config, the ts paths aliases are back working, so for me this workaround is fully what we need 🥳
@noggin182 ! You are the best! It works like a dream,
(Pd: Sorry for my late answer to all the people who tagged me :) )
@aleesaan which version Cypress do you use? Here the fix was also not working on Cypress 8.6.0, but after an upgrade to ^9.4 it works fine. Thanks @noggin182!
@basvandorst I just tried with ^9.4 but still same issue :( aka Error: Cannot find module '@angular/compiler-cli/linker/babel'
Any other ideas?
@aleesaan Does it work if you import '@angular/compiler'
to supports/index.ts
?
@dalenguyen thanks for the suggestion, but unfortunately I still get the same error I mentioned earlier 😢
@aleesaan - is @angular/compiler-cli in your dev dependencies? It should be 13+.
Also, for my workaround above, cypress is 9.3+.
The fullySpecified=false
is also required if you use webpack 5 and ES Modules, and any of your code or dependencies don't use full paths in their imports. Webpack 5 changed the default behavior to make it ESM standards compliant, but it causes a lot of problems b/c many imports aren't fully specified (which worked fine in webpack 4 and commonjs).
The other option is using [--experimental-specifier-resolution=[mode]](https://nodejs.org/api/esm.html#customizing-esm-specifier-resolution-algorithm)
when running node - if you use that, the fullySpecified=false
isn't required.
@johncrim - yes, I have "@angular/compiler-cli": "^13.2.1"
in my dev dependencies.
I also have the fullySpecified=false
, I get this error trying the same setup @noggin182 suggested.
Namely, I installed @cypress/webpack-batteries-included-preprocessor
as a dev dependency, and then added this to my plugins/index.js
file:
const webpackPreprocessor = require('@cypress/webpack-batteries-included-preprocessor');
const webpackOptions = webpackPreprocessor.defaultOptions.webpackOptions;
webpackOptions.module.rules.unshift({
test: /[/\\]@angular[/\\].+\.m?js$/,
resolve: {
fullySpecified: false,
},
use: {
loader: 'babel-loader',
options: {
plugins: ['@angular/compiler-cli/linker/babel'],
compact: false,
cacheDirectory: true,
},
},
});
on(
'file:preprocessor',
webpackPreprocessor({
webpackOptions: webpackOptions,
typescript: require.resolve('typescript'),
}),
);
But I still get the error 😢 Am I missing something else?
Hi,
we are already using the workaround, but it seems that test execution time is longer. Will there be an offical fix soon? Thank you in advance
In case anyone also using ngrx, in my case I had to modify the regex a bit to /[/\\](@angular|@ngrx)[/\\].+\.m?js$/
@ChristianKlima you mention test-execution time is longer. Are you referring to merely cypress tests and/or unit tests? We're also using the workaround and we've also noticed a significant performance hit in unit tests execution time, but we're not sure what is causing that yet.
Hello Dennis, I'm referring to cypress tests. After some investigation I found out that this is the reason for the slower execution time of cypress tests: link.
I'm facing the same error than @aleesaan . Cypress 9.4.1, Nx and Angular 13+. Any suggestion?
Have been struggling with this as well. All efforts to no avail. None of the workarounds in this thread worked, though the error was reduced down to a dependence on the 'v8' module, which stems from @angular-devkit/architect/node which is called by the @cypress/webpack-preprocessor
Error: Webpack Compilation Error
Module not found: Error: Can't resolve 'v8' in 'C:\{path}\node_modules\@angular-devkit\architect\node'
at Watching.handle [as handler] (C:\{path}\node_modules\@cypress\webpack-preprocessor\dist\index.js:180:23)
at C:\{path}\node_modules\webpack\lib\Watching.js:259:9
at Hook.eval [as callAsync] (eval at create (C:\{path}\node_modules\tapable\lib\HookCodeFactory.js:33:10), <anonymous>:6:1)
at Hook.CALL_ASYNC_DELEGATE [as _callAsync] (C:\{path}\node_modules\tapable\lib\Hook.js:18:14)
at Watching._done (C:\{path}\node_modules\webpack\lib\Watching.js:256:28)
at C:\{path}\node_modules\webpack\lib\Watching.js:179:21
at Compiler.emitRecords (C:\{path}\node_modules\webpack\lib\Compiler.js:862:39)
at C:\{path}\node_modules\webpack\lib\Watching.js:157:22
at C:\{path}\node_modules\webpack\lib\Compiler.js:844:14
at Hook.eval [as callAsync] (eval at create (C:\{path}\node_modules\tapable\lib\HookCodeFactory.js:33:10), <anonymous>:6:1)
at Hook.CALL_ASYNC_DELEGATE [as _callAsync] (C:\{path}\node_modules\tapable\lib\Hook.js:18:14)
at C:\{path}\node_modules\webpack\lib\Compiler.js:841:27
at C:\{path}\node_modules\neo-async\async.js:2818:7
at done (C:\{path}\node_modules\neo-async\async.js:3522:9)
at alreadyWritten (C:\{path}\node_modules\webpack\lib\Compiler.js:673:8)
at C:\{path}\node_modules\webpack\lib\Compiler.js:761:19
at C:\{path}\node_modules\graceful-fs\graceful-fs.js:123:16
at C:\{user}\AppData\Local\Cypress\Cache\9.5.1\Cypress\resources\app\node_modules\graceful-fs\graceful-fs.js:123:16
at FSReqCallback.readFileAfterClose [as oncomplete] (node:internal/fs/read_file_context:68:3)
Any help is much appreciated.
Hey, thanks for the suggestions to avoid this issue, but has anyone still struggling with that? @aleesaan and @PuffPastry have you solved your problem?
Hey @adhed yes, I still have it 😠We're completely stuck and can't upgrade Angular because of this, I wonder who we can poke to look into it and fix it?
After upgrading all dependencies (including Cypress, Nx, and Angular) to latest I still get the following:
Error: Webpack Compilation Error
.../node_modules/@angular/platform-browser/fesm2015/platform-browser.mjs
Module not found: Error: Can't resolve '@angular/common' in '.../node_modules/@angular/platform-browser/fesm2015'
We had multiple issues with cypress and webpack 5. Mainly publicPath and the platform-browser errors. Solved using a combination of fixes found in various issues.
Used the below config in plugin.js and pointed all our e2e apps at this shared plugin config. I hope this can help someone else move forward with nx + angular 13 + cypress. Was a complete headache
const webpackPreprocessor = require('@cypress/webpack-preprocessor');
const altWebpackConfig = require('@nrwl/cypress/plugins/preprocessor');
const publicPath = 'http://localhost:4400/';
let outputOptions = {};
module.exports = (on, config) => {
const modifiedBaseConfig = altWebpackConfig.getWebpackConfig(config);
modifiedBaseConfig.module.rules.unshift({
test: /\.m?js$/,
loader: 'babel-loader',
options: {
plugins: ['@angular/compiler-cli/linker/babel'],
compact: false,
cacheDirectory: true,
},
});
Object.defineProperty(modifiedBaseConfig, 'output', {
get: () => {
return { ...outputOptions, publicPath };
},
set: function (x) {
outputOptions = x;
},
});
const options = {
webpackOptions: modifiedBaseConfig,
typescript: require.resolve('typescript'),
};
on('file:preprocessor', webpackPreprocessor(options));
return config;
};
Hi, we were also stuggling with this issue after upgrading to angular 13. The posted workarounds are working, but they require some dependencies that I don't want to deal with when updating my packages. Are there any plans to fix this issue? Thanks
Hey, I just bumped into the same issue as well. Is there any plans to fix the issue? None of the workarounds work for me
Bump
Hi @mjhenkes, could you please remove the existing workaround
label? As you can see the workaround doesn't work for many of us, and this issue is blocking us to upgrade to Angular 13. I'd hope that removing the label will push someone from the core team to look into this issue and fix it as soon as possible. It's a shame that even though Angular 13 was released months ago we can't upgrade because of Cypress 😞
want to say for @aleesaan and others that are stuck by this. my team was also having trouble getting fully upgraded to Angular 13 because of this but we were able to get the workaround @noggin182 provided to work
what was missing was installing the peer dependencies of @cypress/webpack-preprocessor
which are specified here in the second npm install command in the Installation section
so for completeness sake and for people that like to scroll to the bottom (me) the full workaround that worked in my case with Angular 13 and cypress 9.7.0 is:
install the @cypress/webpack-batteries-included-preprocessor and @cypress/webpack-preprocessor packages:
npm install --save-dev @cypress/webpack-preprocessor @cypress/webpack-batteries-included-preprocessor
install the peer dependencies of @cypress/webpack-preprocessor:
npm install --save-dev @babel/core @babel/preset-env babel-loader webpack
update the cypress plugin file to resemble this depending on your existing plugins (credit to @noggin182):
cypress/plugins/index.ts
(could alternatively be cypress/plugins/index.js
)
module.exports = (on, config) => {
const webpackPreprocessor = require('@cypress/webpack-batteries-included-preprocessor');
const webpackOptions = webpackPreprocessor.defaultOptions.webpackOptions;
webpackOptions.module.rules.unshift({
test: /[/\\]@angular[/\\].+\.m?js$/,
resolve: {
fullySpecified: false,
},
use: {
loader: 'babel-loader',
options: {
plugins: ['@angular/compiler-cli/linker/babel'],
compact: false,
cacheDirectory: true
}
}
});
on('file:preprocessor', webpackPreprocessor({
webpackOptions: webpackOptions,
typescript: require.resolve('typescript')
}));
return config;
};
hope that helps people while the devs come up with a long term fix.
Having similar issue too!!
Webpack Compilation Error
/{path}/node_modules/@angular/material/fesm2015/dialog.mjs
Module not found: Error: Can't resolve '@angular/animations' in '/{path}/node_modules/@angular/material/fesm2015'
resolve '@angular/animations' in '{path}/node_modules/@angular/material/fesm2015'
Parsed request is a module
@raisedwizardry's workaround seems to resolve the issue I am having. Strangely enough, only e2e tests from one app seems to be affected, e2e tests from 2 other apps seems to be working fine.
For anyone using the nrwl cypress 10 upgrade generator , i.enx generate @nrwl/cypress:migrate-to-cypress-10
we found that the configuration above stopped working.
// cypress.config.ts
import { defineConfig } from 'cypress';
import { nxE2EPreset } from '@nrwl/cypress/plugins/cypress-preset';
// Our current webpack plugin configuration as per @aleesaan as a .js file
import setupNodeEvents from './src/plugins/index';
...
export default defineConfig({
e2e: {
...nxE2EPreset(__dirname),
...cypressJsonConfig,
setupNodeEvents, // <-- didn't work
},
});
Adding it directly in cypress.config.ts
fixed it for us.
// cypress.config.ts
export default defineConfig({
e2e: {
...nxE2EPreset(__dirname),
...cypressJsonConfig,
// The exact same content as the plugins file
setupNodeEvents: (on, config) => {
// @see https://github.com/cypress-io/cypress/issues/19066#issuecomment-1012055705
const webpackPreprocessor = require("@cypress/webpack-batteries-included-preprocessor");
const webpackOptions = webpackPreprocessor.defaultOptions.webpackOptions;
webpackOptions.module.rules.unshift({
test: /[/\\]@angular[/\\].+\.m?js$/,
resolve: {
fullySpecified: false
},
use: {
loader: "babel-loader",
options: {
plugins: ["@angular/compiler-cli/linker/babel"],
compact: false,
cacheDirectory: true
}
}
});
on("file:preprocessor", webpackPreprocessor({
webpackOptions: webpackOptions,
typescript: require.resolve("typescript")
}));
return config;
}
},
});
Thanks for the workaround. Our e2e tests are running again.
But we still have problems with code coverage. Someone else had problems with this?
I was able to get this working in a Angular 14 app with Cypress 10 putting together some of the great workarounds from @noggin182 and others, thanks! Heres what I did:
Install the webpack preprocessor:
npm install -D @cypress/webpack-preprocessor
Update your cypress.config.ts to import the preprocessor as add a rule to compile anything from the @angular namespace using the JIT Linker from Angular:
import { defineConfig } from 'cypress';
const webpackPreprocessor = require('@cypress/webpack-preprocessor');
const webpackOptions = webpackPreprocessor.defaultOptions.webpackOptions;
webpackOptions.module.rules.unshift({
// Angular linker needed to link partial-ivy code
// See https://angular.io/guide/creating-libraries#consuming-partial-ivy-code-outside-the-angular-cli
test: /[/\\]@angular[/\\].+\.m?js$/,
use: {
loader: 'babel-loader',
options: {
plugins: ['@angular/compiler-cli/linker/babel'],
compact: false,
cacheDirectory: true,
},
},
resolve: {
fullySpecified: false,
},
});
export default defineConfig({
e2e: {
baseUrl: 'http://localhost:4200',
setupNodeEvents: (on, config) => {
on(
'file:preprocessor',
webpackPreprocessor({
webpackOptions,
})
);
return config;
},
},
});
Now any spec that imports something from @angular
should now run. However, there is a considerable delay in loading the spec, presumably waiting for the compiler to finish.
In my case this weird error was caused by a "wrong" import-statement in the e2e.spec-File (Error: Webpack Compilation Error ./node_modules/@angular/cdk/fesm2015/tree.mjs Module not found: Error: Can't resolve '@angular/cdk/bidi'....)
I have an Angular-workspace with a library + a test-application which uses the library and is used for the e2e-Tests.
The problematic import-statement in the e2e.spec-File was this one:
import { DateUtils } from "projects/spike/core/src/public-api";
This DateUtils-class is part of the library.
Changing this import-statement to
import { DateUtils } from "projects/spike/core/src/lib/utilities/date-utils";
fixed the problem.
The workaround by johncrim worked perfectly for us. Additionally, since we used alias imports in the Cypress tests itself, we had to add them to the webpack config using the tsconfig-paths-webpack-plugin .
After upgrading to Angular 16 (from 14) and Cypress 13.6.0 (from 12.17.1), the issue seems to be resolved. I was able to remove the custom webpack preprocessor and alias handling.
Current behavior
When I try to import anything from
@angular/cdk
(Angular 13), Cypress fails to build the test. This used to work in Angular 12, so I am not exactly sure where is the problem.The error I am getting:
Desired behavior
I should be able to import from
@angular/cdk
Test code to reproduce
Cypress Version
9.1.0
Other
No response