Skip to content

Fix/issue 22747 #28134

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions .yarnrc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
nodeLinker: node-modules
42 changes: 40 additions & 2 deletions npm/webpack-dev-server/src/helpers/angularHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ export async function getAngularCliModules (projectRoot: string) {

try {
angularVersion = await getInstalledPackageVersion('@angular-devkit/core', projectRoot)
} catch {
} catch (err) {
throw new Error(`Could not resolve "@angular-devkit/core". Do you have it installed?`)
}

Expand All @@ -189,17 +189,53 @@ export async function getAngularCliModules (projectRoot: string) {
'@angular-devkit/core/src/index.js',
] as const

debug('SOMETHING!!!')
const [
{ generateBrowserWebpackConfigFromContext },
{ getCommonConfig },
{ getStylesConfig },
{ logging },
] = await Promise.all(angularCLiModules.map((dep) => {
try {
if (process.versions.pnp) {
// For some weird reason pnp will not resolve this with the full path, even though it should exist in the
// package
if (dep === '@angular-devkit/core/src/index.js') {
dep = '@angular-devkit/core'
}

// do something with the PnP API ...
debug('PNP angular handler?', process.versions.pnp)
debug('dep', dep)
const { createRequire, findPnpApi } = require(`module`)
const targetPnp = findPnpApi(projectRoot)
const targetRequire = createRequire(projectRoot)

const resolved = targetPnp.resolveRequest(dep, projectRoot)
const instance = targetRequire(resolved)

debug('returning instance')

return instance
}

// fallback
debug('PNP angular handler?', process.versions.pnp)
debug('dep', dep)
const depPath = require.resolve(dep, { paths: [projectRoot] })

return dynamicAbsoluteImport(depPath)
debug('Deppath:', depPath)

const tmp = dynamicAbsoluteImport(depPath)

debug('tmp:', tmp)

return tmp
} catch (e) {
debug('catch:', e)
// const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms))

// sleep(1000000)
throw new Error(`Could not resolve "${dep}". Do you have "@angular-devkit/build-angular" and "@angular-devkit/core" installed?`)
}
}))
Expand Down Expand Up @@ -273,6 +309,8 @@ async function getAngularCliWebpackConfig (devServerConfig: AngularWebpackDevSer
logging,
} = await getAngularCliModules(projectRoot)

debug('generateBrowserWebpackConfigFromContext', generateBrowserWebpackConfigFromContext)

// normalize
const projectConfig = devServerConfig.options?.projectConfig || await getProjectConfig(projectRoot)

Expand Down
6 changes: 6 additions & 0 deletions packages/data-context/src/data/ProjectConfigIpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,8 @@ export class ProjectConfigIpc extends EventEmitter {
} else {
childOptions.env.NODE_OPTIONS = tsNodeEsmLoader
}

childOptions.env['NODE_OPTIONS'] = `--require ${this.projectRoot}/.pnp.loader.mjs ${ childOptions.env['NODE_OPTIONS']}`
} else {
// Not using ES Modules (via "type": "module"),
// so we just register the standard ts-node module
Expand All @@ -324,6 +326,8 @@ export class ProjectConfigIpc extends EventEmitter {
} else {
childOptions.env.NODE_OPTIONS = tsNodeLoader
}

childOptions.env['NODE_OPTIONS'] = `--require ${this.projectRoot}/.pnp.cjs ${ childOptions.env['NODE_OPTIONS']}`
Copy link
Author

@wiegell wiegell Oct 24, 2023

Choose a reason for hiding this comment

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

This line alone fixes #22747, but only if webpack-dev-server is not used (e.g. global mode yarn cypress:open --project xxx and testing an external angular project run via ng serve)

}
} else {
// Just use Node's built-in ESM support.
Expand All @@ -347,6 +351,8 @@ export class ProjectConfigIpc extends EventEmitter {
})
}

debug('fork child process %o', { CHILD_PROCESS_FILE_PATH, configProcessArgs, childOptions })

return fork(CHILD_PROCESS_FILE_PATH, configProcessArgs, childOptions)
}

Expand Down
4 changes: 2 additions & 2 deletions packages/launchpad/cypress/e2e/project-setup.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -556,7 +556,7 @@ describe('Launchpad: Setup Project', () => {
})
})

describe('Command for package managers', () => {
describe.only('Command for package managers', () => {
it('makes the right command for yarn', () => {
scaffoldAndOpenProject('pristine-yarn')

Expand Down Expand Up @@ -584,7 +584,7 @@ describe('Launchpad: Setup Project', () => {
// TODO: Had to revert due to regression: https://github.com/cypress-io/cypress/pull/26452
// Would be great to fully support Plug n Play eventually, but right now it causes issues relating
// to not correctly detecting dependencies when installing the binary.
it.skip('works with Yarn 3 Plug n Play', () => {
it.only('works with Yarn 3 Plug n Play', () => {
Copy link
Author

Choose a reason for hiding this comment

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

I have tried reworking this test to feature an angular repo that should be spun up via cypress. I have run into some other pnp-related issues, that could be mitigated, but i'm stuck at an esm import error deep in the angular_devkit/build package

 cypress:lifecycle:ProjectConfigIpc plugins process error: Error [ERR_MODULE_NOT_FOUND]: Cannot find package '@angular/compiler-cli' imported from /private/var/folders/hg/3s1q3w8j4xlgbp55q9cbsnkm0000gn/T/cy-projects/yarn-v3.1.1-pnp/.yarn/__virtual__/@angular-devkit-build-angular-virtual-4aa3a8673f/0/cache/@angular-devkit-build-angular-npm-16.2.7-ff0a3596ac-cfd587b125.zip/node_modules/@angular-devkit/build-angular/src/utils/load-esm.js
[cy:open:dev:30509]: Did you mean to import @angular-compiler-cli-virtual-8bb163dda9/0/cache/@angular-compiler-cli-npm-16.2.10-071c53740f-07c89fc8a0.zip/node_modules/@angular/compiler-cli/bundles/index.js?
[cy:open:dev:30509]:     at new NodeError (node:internal/errors:399:5)
[cy:open:dev:30509]:     at packageResolve (node:internal/modules/esm/resolve:895:9)
[cy:open:dev:30509]:     at moduleResolve (node:internal/modules/esm/resolve:944:20)
[cy:open:dev:30509]:     at defaultResolve (node:internal/modules/esm/resolve:1159:11)
[cy:open:dev:30509]:     at nextResolve (node:internal/modules/esm/loader:163:28)
[cy:open:dev:30509]:     at ESMLoader.resolve (node:internal/modules/esm/loader:838:30)
[cy:open:dev:30509]:     at ESMLoader.getModuleJob (node:internal/modules/esm/loader:424:18)
[cy:open:dev:30509]:     at ESMLoader.import (node:internal/modules/esm/loader:525:22)
[cy:open:dev:30509]:     at importModuleDynamically (node:internal/modules/cjs/loader:1193:29)
[cy:open:dev:30509]:     at importModuleDynamicallyWrapper (node:internal/vm/module:429:21)
[cy:open:dev:30509]:     at importModuleDynamically (node:internal/vm:106:46)
[cy:open:dev:30509]:     at importModuleDynamicallyCallback (node:internal/process/esm_loader:35:14)
[cy:open:dev:30509]:     at eval (eval at loadEsmModule (/private/var/folders/hg/3s1q3w8j4xlgbp55q9cbsnkm0000gn/T/cy-projects/yarn-v3.1.1-pnp/.yarn/__virtual__/@angular-devkit-build-angular-virtual-4aa3a8673f/packages/angular_devkit/build_angular/src/utils/load-esm.ts:24:10), <anonymous>:3:1)
[cy:open:dev:30509]:     at loadEsmModule (/private/var/folders/hg/3s1q3w8j4xlgbp55q9cbsnkm0000gn/T/cy-projects/yarn-v3.1.1-pnp/.yarn/__virtual__/@angular-devkit-build-angular-virtual-4aa3a8673f/packages/angular_devkit/build_angular/src/utils/load-esm.ts:24:66)
[cy:open:dev:30509]:     at readTsconfig (/private/var/folders/hg/3s1q3w8j4xlgbp55q9cbsnkm0000gn/T/cy-projects/yarn-v3.1.1-pnp/.yarn/__virtual__/@angular-devkit-build-angular-virtual-4aa3a8673f/packages/angular_devkit/build_angular/src/utils/read-tsconfig.ts:29:71)
[cy:open:dev:30509]:     at generateWebpackConfig (/private/var/folders/hg/3s1q3w8j4xlgbp55q9cbsnkm0000gn/T/cy-projects/yarn-v3.1.1-pnp/.yarn/__virtual__/@angular-devkit-build-angular-virtual-4aa3a8673f/packages/angular_devkit/build_angular/src/utils/webpack-browser-config.ts:46:38)
[cy:open:dev:30509]:     at generateBrowserWebpackConfigFromContext (/private/var/folders/hg/3s1q3w8j4xlgbp55q9cbsnkm0000gn/T/cy-projects/yarn-v3.1.1-pnp/.yarn/__virtual__/@angular-devkit-build-angular-virtual-4aa3a8673f/packages/angular_devkit/build_angular/src/utils/webpack-browser-config.ts:158:24)
[cy:open:dev:30509]:     at async getAngularCliWebpackConfig (/Users/<USER>/cypress/npm/webpack-dev-server/dist/helpers/angularHandler.js:193:24)
[cy:open:dev:30509]:     at async angularHandler (/Users/<USER>/cypress/npm/webpack-dev-server/dist/helpers/angularHandler.js:233:27)
[cy:open:dev:30509]:     at async getPreset (/Users/<USER>/cypress/npm/webpack-dev-server/dist/devServer.js:94:20)
[cy:open:dev:30509]:     at async Function.devServer.create (/Users/<USER>/cypress/npm/webpack-dev-server/dist/devServer.js:111:61)
[cy:open:dev:30509]:     at async /Users/<USER>/cypress/npm/webpack-dev-server/dist/devServer.js:26:24

scaffoldAndOpenProject('yarn-v3.1.1-pnp')

cy.visitLaunchpad()
Expand Down
3 changes: 3 additions & 0 deletions packages/server/lib/plugins/child/run_require_async_child.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,14 @@ function run (ipc, file, projectRoot) {
// Config file loading of modules is tested within
// system-tests/projects/config-cjs-and-esm/*
const loadFile = async (file) => {
debug('PNP? ', process.versions.pnp)

try {
debug('Loading file %s', file)

return require(file)
} catch (err) {
debug('Somethin went wrong', err)
if (!err.stack.includes('[ERR_REQUIRE_ESM]') && !err.stack.includes('SyntaxError: Cannot use import statement outside a module')) {
throw err
}
Expand Down
2 changes: 1 addition & 1 deletion packages/server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@
"@cypress/sinon-chai": "2.9.1",
"@cypress/webpack-dev-server": "0.0.0-development",
"@electron/rebuild": "3.2.10",
"@ffprobe-installer/ffprobe": "1.1.0",
"@ffprobe-installer/ffprobe": "1.4.2",
"@packages/config": "0.0.0-development",
"@packages/data-context": "0.0.0-development",
"@packages/electron": "0.0.0-development",
Expand Down
2 changes: 1 addition & 1 deletion system-tests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"@cypress/request-promise": "^5.0.0",
"@cypress/sinon-chai": "2.9.1",
"@cypress/webpack-preprocessor": "0.0.0-development",
"@ffprobe-installer/ffprobe": "1.1.0",
"@ffprobe-installer/ffprobe": "1.4.2",
"@packages/https-proxy": "0.0.0-development",
"@packages/launcher": "0.0.0-development",
"@packages/network": "0.0.0-development",
Expand Down
4 changes: 3 additions & 1 deletion system-tests/projects/yarn-v3.1.1-pnp/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
.yarn
.pnp.js
.pnp.js
.pnp.cjs
.pnp.loader.mjs
5 changes: 5 additions & 0 deletions system-tests/projects/yarn-v3.1.1-pnp/.yarnrc.yml
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
yarnPath: "./yarn-3.1.1.cjs"

# TODO: This should be removed at some point


nodeLinker: "pnp"
13 changes: 0 additions & 13 deletions system-tests/projects/yarn-v3.1.1-pnp/cypress.config.js

This file was deleted.

29 changes: 29 additions & 0 deletions system-tests/projects/yarn-v3.1.1-pnp/cypress.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { defineConfig } from 'cypress'

export default defineConfig({
component: {
experimentalSingleTabRunMode: true,
devServer: {
framework: 'angular',
bundler: 'webpack',
webpackConfig: {
resolve: {
alias: {
'@angular/common/http': require.resolve('@angular/common/http'),
'@angular/common/testing': require.resolve('@angular/common/testing'),
'@angular/common': require.resolve('@angular/common'),
'@angular/core/testing': require.resolve('@angular/core/testing'),
'@angular/core': require.resolve('@angular/core'),
'@angular/platform-browser/testing': require.resolve('@angular/platform-browser/testing'),
'@angular/platform-browser': require.resolve('@angular/platform-browser'),
'@angular/platform-browser-dynamic/testing': require.resolve('@angular/platform-browser-dynamic/testing'),
'@angular/platform-browser-dynamic': require.resolve('@angular/platform-browser-dynamic'),
'zone.js/testing': require.resolve('zone.js/dist/zone-testing'),
'zone.js': require.resolve('zone.js'),
},
},
},
},
specPattern: 'src/**/*.cy.ts',
},
})
36 changes: 33 additions & 3 deletions system-tests/projects/yarn-v3.1.1-pnp/package.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,42 @@
{
"name": "yarn-v3.1.1-pnp",
"version": "1.0.0",
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"watch": "ng build --watch --configuration development",
"test": "ng test"
},
"dependencies": {
"lodash": "^4.17.21"
"@angular-devkit/build-angular": "^16.2.7",
"@angular-devkit/core": "^16.2.7",
"@angular/animations": "^16.1.0",
"@angular/common": "^16.1.0",
"@angular/compiler": "^16.1.0",
"@angular/core": "^16.1.0",
"@angular/forms": "^16.1.0",
"@angular/platform-browser": "^16.1.0",
"@angular/platform-browser-dynamic": "^16.1.0",
"@angular/router": "^16.1.0",
"rxjs": "^7.8.0",
"tslib": "^2.3.0",
"zone.js": "^0.13.0"
},
"devDependencies": {
"typescript": "^4.2.4"
"@angular/cli": "^16.1.0",
"@angular/compiler-cli": "^16.1.0",
"@types/jasmine": "^4.3.0",
"cypress": "^13.3.2",
"jasmine-core": "^4.5.0",
"karma": "^6.4.0",
"karma-chrome-launcher": "^3.1.0",
"karma-coverage": "^2.2.0",
"karma-jasmine": "^5.1.0",
"karma-jasmine-html-reporter": "^2.0.0",
"typescript": "^4.9.4"
},
"license": "MIT",
"projectFixtureDirectory": "angular",
"_cyRunScripts": true,
"_cyYarnV311": true
}
14 changes: 14 additions & 0 deletions system-tests/projects/yarn-v3.1.1-pnp/tsconfig.app.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "./out-tsc/app",
"types": []
},
"files": [
"src/main.ts",
"src/polyfills.ts"
],
"include": [
"src/**/*.d.ts"
]
}
11 changes: 11 additions & 0 deletions system-tests/projects/yarn-v3.1.1-pnp/tsconfig.cypress.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "./out-tsc/cy",
"allowSyntheticDefaultImports": true,
"types": [
"cypress"
]
},
"include": ["src/**/*.cy.ts", "cypress/support/component.ts", "src/polyfills.ts"]
}
32 changes: 27 additions & 5 deletions system-tests/projects/yarn-v3.1.1-pnp/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,31 @@
/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
"compileOnSave": false,
"compilerOptions": {
"target": "es5",
"lib": ["es5", "dom"],
"allowJs": true,
"moduleResolution": "node"
"baseUrl": "./",
"outDir": "./dist/out-tsc",
"forceConsistentCasingInFileNames": true,
"strict": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"sourceMap": true,
"declaration": false,
"downlevelIteration": true,
"experimentalDecorators": true,
"moduleResolution": "node",
"importHelpers": true,
"target": "es2017",
"module": "ESNext",
"lib": [
"es2018",
"dom"
]
},
"include": ["**/*.ts"]
"angularCompilerOptions": {
"enableI18nLegacyMessageIdFormat": false,
"strictInjectionParameters": true,
"strictInputAccessModifiers": true,
"strictTemplates": true
},
"include": ["./cypress.config.ts"]
}
Loading