aws / aws-cdk

The AWS Cloud Development Kit is a framework for defining cloud infrastructure in code
https://aws.amazon.com/cdk
Apache License 2.0
11.71k stars 3.93k forks source link

(aws-cdk-lib): Document deep import restrictions and importing experimental packages #18163

Closed terrificdm closed 2 years ago

terrificdm commented 2 years ago

What is the problem?

When using EdgeFunction from "aws_cloudfront.experimental" module via CDK v2, you need to modify ".../node_modules/aws-cdk-lib/package.json" to define package subpath of './aws-cloudfront/lib/experimental' by "exports". If not doing such, you will encounter the error as below: "Error: Package subpath './aws-cloudfront/lib/experimental' is not defined by "exports" in .../node_modules/aws-cdk-lib/package.json"

Reproduction Steps

Import "EdgeFunction" in your codes for using L@E of CloudFront(CDK v2), conduct 'cdk synth' or 'cdk deploy', then the error comes. import {EdgeFunction} from 'aws-cdk-lib/aws-cloudfront/lib/experimental';

What did you expect to happen?

Without extra manual modifications to ".../node_modules/aws-cdk-lib/package.json" file, just through a simple import to use EdgeFunction, which is similar to the process of CDK v1.

What actually happened?

Needs extra manual modifications to ".../node_modules/aws-cdk-lib/package.json" file

CDK CLI Version

2.3.0

Framework Version

No response

Node.js Version

v16.13.1

OS

Amazon Linux2

Language

Typescript

Language Version

No response

Other information

No response

somen440 commented 2 years ago

I had the same problem.

error message

yarn cdk diff
...
...
Package subpath './aws-elasticloadbalancingv2/lib/shared/enums' is not defined by "exports"

code

import * as elbv2 from "aws-cdk-lib/aws-elasticloadbalancingv2";
...
...
  public readonly loadBalancer: elbv2.ApplicationLoadBalancer;
...
...

env

❯ yarn cdk version
yarn run v1.22.10
$ cdk version
2.3.0 (build beaa5b2)
✨  Done in 1.11s.

package.json

  "devDependencies": {
    "@aws-cdk/assert": "2.3.0",
    "@types/humps": "^2.0.0",
    "@types/jest": "^26.0.10",
    "@types/node": "10.17.27",
    "@typescript-eslint/eslint-plugin": "^4.14.0",
    "@typescript-eslint/parser": "^4.14.0",
    "aws-cdk": "2.3.0",
    "eslint": "^7.18.0",
    "eslint-config-prettier": "^7.2.0",
    "eslint-plugin-import": "^2.22.1",
    "eslint-plugin-prettier": "^3.3.1",
    "humps": "^2.0.1",
    "jest": "^26.4.2",
    "prettier": "^2.2.1",
    "ts-jest": "^26.2.0",
    "ts-node": "^9.0.0",
    "typescript": "~3.9.7"
  },
  "dependencies": {
    "aws-cdk-lib": "2.3.0",
    "constructs": "^10.0.0",
    "source-map-support": "^0.5.16"
  }
somen440 commented 2 years ago

I will write a concrete method to solve the syntax error.


edit node_modules/aws-cdk-lib/package.json

    "./aws-elasticloadbalancingv2": "./aws-elasticloadbalancingv2/index.js",
+    "./aws-elasticloadbalancingv2/lib/shared/enums": "./aws-elasticloadbalancingv2/lib/shared/enums.js",

I didn't know what was happening... 😢

somen440 commented 2 years ago

Different from this problem https://github.com/aws/aws-cdk/issues/18089

explicitly exporting https://github.com/aws/aws-cdk/blob/65da9e1a7e84265820ab1acdc075fb3558c99fcc/packages/%40aws-cdk/aws-elasticloadbalancingv2/lib/index.ts#L20


Apparently in my case this problem occurred when I was importing aws-cdk on my own package. As long as I imported it into flat, I didn't have any problems. However, the correct remedy is still unknown.

somen440 commented 2 years ago

I'm sorry ... This problem has been self-solved. The cause was in the package I made.

Originally, there was the following inappropriate description and it was corrected.

- import * as lbEnum from "aws-elasticloadbalancingv2/lib/shared/enums"
+ import * as elbv2 from "aws-elasticloadbalancingv2" 

I forgot to rebuild after this fix. It seems that the phenomenon occurred because the data of import aws-elasticloadbalancingv2/lib/shared/enums remained in the js file.

Perhaps this Issue itself has a similar problem. For the time being, I will leave. Thank you very much.

peterwoodworth commented 2 years ago

I'm unable to reproduce this @terrificdm. Here are the steps I took

  1. npm install -g aws-cdk@latest // Will install 2.3.0 as of right now
  2. cdk init ...
  3. Create new EdgeFunction, with this as the import: import { EdgeFunction } from 'aws-cdk-lib/aws-cloudfront/lib/experimental';
  4. cdk synth

This will result in a successfully produced template.

terrificdm commented 2 years ago

@peterwoodworth Hi, the issue will emerge when you really create a lambda resource in your CDK codes by "EdgeFunction", just like below steps:

  1. npm install -g aws-cdk@latest
  2. mkdir edgefunction && cd edgefunction && cdk init --language typescript
  3. uncomment env. variable to CDK_DEFAULT_ACCOUNT/REGION of "edgefunction.ts" file in "bin" folder
  4. replace "edgefunction-stack.ts" file in "lib" folder with below one
    
    import { Stack, StackProps } from 'aws-cdk-lib';
    import { Construct } from 'constructs';
    import * as lambda from 'aws-cdk-lib/aws-lambda';
    import {EdgeFunction} from 'aws-cdk-lib/aws-cloudfront/lib/experimental';

export class EdgefunctionStack extends Stack { constructor(scope: Construct, id: string, props?: StackProps) { super(scope, id, props);

new EdgeFunction(this, 'LambdaFunction', {
  runtime: lambda.Runtime.NODEJS_14_X,
  handler: 'index.handler',
  code: lambda.Code.fromAsset('./lambda'),
  stackId: 'LambdaEdgeStack'
});

} }


5. create a "lambda" folder under root directory of "edgefunction" folder, then put a sample code of lambda in folder.
6. cdk synth

And you will the error...

The weird thing is if I don't specifically import {EdgeFunction} from "..aws-cloudfront/lib/experimental", just import "aws-cloudfront" directly, and use "cloudfront.experimental.EdgeFunction" to reprsent {EdgeFunction} in my codes, it works... Eventhough my IDE is with an error notice "Property 'experimental' doesn't exist..." just like below screenshot, which confused me a lot.
<img width="614" alt="Screen Shot 2021-12-29 at 10 36 19 AM" src="https://user-images.githubusercontent.com/62762145/147622346-f108b9b0-0d25-4fbd-a4ac-9621bdb6e3b4.png">
peterwoodworth commented 2 years ago

I don't know how I wasn't able to reproduce this yesterday - I can reproduce this just fine now. Thanks for following up

It turns out this is expected - We have prevented "deep imports" since 2.2.0. See the PR here #17707. Only specifically exported packages in package.json are allowed to be imported by the user.

As it turns out, the experimental library is not in this package. However, the folder lies inside the cloudfront package, and this folder is exported by cloudfront's index.js. So the correct way to use the experimental library in v2 is as described in the above comment:

import * as cf from 'aws-cdk-lib/aws-cloudfront';

    new cf.experimental.EdgeFunction(this, 'ef', {
      code: Code.fromAsset('./lambda'),
      handler: 'hello.handler',
      runtime: Runtime.NODEJS_14_X
    });

Or

import { experimental } from 'aws-cdk-lib/aws-cloudfront';

    new experimental.EdgeFunction(this, 'ef', {
      code: Code.fromAsset('./lambda'),
      handler: 'hello.handler',
      runtime: Runtime.NODEJS_14_X
    });

My IDE doesn't complain for me here though 😅

peterwoodworth commented 2 years ago

I think our documentation here needs to be improved - users are frequently getting tripped up by the deep import change - #17950 #18089 #18211

terrificdm commented 2 years ago

I think our documentation here needs to be improved - users are frequently getting tripped up by the deep import change - #17950 #18089 #18211

Agree that the documentation needs some explanation for importing modules which hide deeply :) And, appreciated for letting me know this restriction.

github-actions[bot] commented 2 years ago

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see. If you need more assistance, please either tag a team member or open a new issue that references this one. If you wish to keep having a conversation with other community members under this issue feel free to do so.

peterwoodworth commented 2 years ago

I'm going to reopen this so we can track fixing the documentation 🙂

badfun commented 2 years ago

Thanks @peterwoodworth . This tripped me up for awhile.

peterwoodworth commented 2 years ago

I actually don't believe we need to address this in the docs anymore, I haven't seen anyone get tripped up by this in a while, and we never say you can do this in the first place. Closing, thanks everyone 🙂

github-actions[bot] commented 2 years ago

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see. If you need more assistance, please either tag a team member or open a new issue that references this one. If you wish to keep having a conversation with other community members under this issue feel free to do so.

marketasolanikova commented 2 years ago

I've just encountered the same issue and the exact error for me was: Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: Package subpath './aws-cloudfront/lib/experimental' is not defined by "exports".

This tread helped me to use proper import, but it would be very helpful to have it described in the CDK documentation.

LDMGN commented 2 years ago

Encountered the same issue just now. The route to a solution was not ideal. I found the migration docs describing alpha packes, but there is no @aws-cdk-lib/aws-cloudfront-alpha, so that was confusing. Then I found this example on CDK V2 EdgeFunctions. If only that example had included the import * as cf-line, it would have resolved my issue right away. Luckily I eventually found @peterwoodworth 's example from Dec 29th, which resolved my issue.

I guess not including import-lines in examples keeps them cleaner, but for someone who's lost they can really help.

sjain24 commented 2 years ago

Facing similar issue : Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: Package subpath './aws-ec2/lib/cfn-init' is not defined by "exports" in node_modules/aws-cdk-lib/package.json