Hi, I’m having trouble getting started with reusab...
# getting-started
i
Hi, I’m having trouble getting started with reusable components. I’m trying to use TypeScript to author a simple reusable component resource that I can use to deploy an S3 bucket on AWS. I’ll start a thread here to share what I have tried and the issue I’m having! 🧶
To demonstrate the issue I’m having, I have created two public GitHub repos: -
briancaffey/pulumi-alpha
(link) is the repo that consumes my S3 component -
briancaffey/pulumi-beta
(link) is the repo where I define the reusable S3 component I created both of these with
pulumi new aws-typescript
.
For
pulumi-beta
, I am using the following code to define my component resource:
Copy code
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

export interface S3BucketArgs {
  name: string;
}

export class S3Bucket extends pulumi.ComponentResource {
  public readonly bucket: aws.s3.Bucket;

  constructor(name: string, args: S3BucketArgs, opts?: pulumi.ComponentResourceOptions) {
    super("my:modules:S3Bucket", name, {}, opts);

    this.bucket = new aws.s3.Bucket(name, {
      bucket: args.name,
    }, { parent: this });
  }
}
In
pulumi-alpha
, I installed the
pulumi-beta
this package with the following command:
npm i git+<https://github.com/briancaffey/pulumi-beta.git>
Then I use it like this in `index.ts`:
Copy code
import * as pulumi from "@pulumi/pulumi";
import { S3Bucket } from "pulumi-beta";

const bucket = new S3Bucket("my-bucket", {
  name: "my-example-pulumi-bucket",
});

export const bucketName = bucket.bucket.id;
Then I ran
tsc
and I can see that it built the application in the
bin
directory:
Copy code
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.bucketName = void 0;
const pulumi_beta_1 = require("pulumi-beta");
const bucket = new pulumi_beta_1.S3Bucket("my-bucket", {
    name: "my-example-pulumi-bucket",
});
exports.bucketName = bucket.bucket.id;
//# sourceMappingURL=index.js.map
Now I want to run
pulumi preview
to see how things will look, but I get this error:
Copy code
~/git/github/pulumi-alpha$ pulumi preview
Previewing update (dev)

View Live: <https://app.pulumi.com/briancaffey/pulumi-alpha/dev/previews/f8469d80-a9d5-4e95-9d9f-8a5830220f5c>

     Type                 Name              Plan       Info
 +   pulumi:pulumi:Stack  pulumi-alpha-dev  create     1 error


Diagnostics:
  pulumi:pulumi:Stack (pulumi-alpha-dev):
    error: Running program '/Users/brian/git/github/pulumi-alpha' failed with an unhandled exception:
    /Users/brian/git/github/pulumi-alpha/node_modules/pulumi-beta/index.ts:1
    import * as pulumi from "@pulumi/pulumi";
    ^^^^^^

    SyntaxError: Cannot use import statement outside a module
Back in the
pulumi-beta
repo, I added
"type": "module",
to
package.json
, pushed to GitHub, then reinstalled everything in `pulumi-alpha`:
Copy code
rm -rf bin
rm -rf node_modules
rm package-lock.json
npm i
tsc
Running
pulumi preview
again I get the same error as before:
Copy code
Diagnostics:
  pulumi:pulumi:Stack (pulumi-alpha-dev):
    error: Running program '/Users/brian/git/github/pulumi-alpha' failed with an unhandled exception:
    /Users/brian/git/github/pulumi-alpha/node_modules/pulumi-beta/index.ts:1
    import * as pulumi from "@pulumi/pulumi";
    ^^^^^^

    SyntaxError: Cannot use import statement outside a module
Can anyone help guide me on how I can get this basic example to work?
m
Hi Brian, I will take a look into it
i
Hi @many-telephone-49025, thanks a lot! Please let me know if there is anything else I can provide.
m
Hey Brian, can you check this please? https://www.typescriptlang.org/docs/handbook/declaration-files/publishing.html#including-declarations-in-your-npm-package
Copy code
If your package has a main .js file, you will need to indicate the main declaration file in your package.json file as well. Set the types property to point to your bundled declaration file. For example:

{
  "name": "awesome",
  "author": "Vandelay Industries",
  "version": "1.0.0",
  "main": "./lib/main.js",
  "types": "./lib/main.d.ts"
}
Could be `pulumi-beta`is using the wrong
index.ts
when imported
i
OK, thanks for sharing @many-telephone-49025.
Copy code
If your package has a main .js file,
Should my
pulumi-beta
reusable component resource have a main
.js
file?
m
no could be index too
it was just the example from the TS page
i
"main": "index.ts",
This is what I have in my
pulumi-beta
package.json
This is also what I have in my
pulumi-alpha
repo (the pulumi project that consumes the
pulumi-beta
component resource)
"main": "index.ts",
m
probably change it to :
Copy code
{
  "name": "pulumi-beta",
  "main": "./bin/index.js",
  "types": "./bin/index.d.ts",
   ...
}
i
OK, thanks. I can try this.
v
we have a reusable component library. let me grab you the package.json
i
v
Copy code
{
  "name": "@jugo-io/jugo-pulumi-common",
  "version": "1.0.0",
  "description": "Jugo Common Pulumi Library",
  "main": "dist/index.js",
  "typings": "dist/index.d.ts",
  "scripts": {
    "build": "npx tsc",
    "lint": "node_modules/.bin/eslint .",
    "lint:fix": "node_modules/.bin/eslint . --fix"
  },
  "repository": {
    "type": "git",
    "url": ""
  },
  "release": {
    "branches": [
      "main"
    ]
  },
  "publishConfig": {
    "registry": "<https://npm.pkg.github.com>"
  },
  "files": [
    "dist"
  ],
  "peerDependencies": {
     ...
  },
  "author": "<mailto:jugo-admin+platform-team@gdsgroup.com|jugo-admin+platform-team@gdsgroup.com>",
  "license": "MIT",
  "devDependencies": {
    ...
  }
}
i
I’m still getting:
Copy code
import * as pulumi from "@pulumi/pulumi";
    ^^^^^^
    
    SyntaxError: Cannot use import statement outside a module
m
Ah thx @victorious-church-57397, so its "typings"
and the exact location of the d.ts
v
tsconfig is
Copy code
{
  "compilerOptions": {
    "module": "commonjs",
    "target": "es2015",
    "declaration": true,
    "outDir": "./dist"
  },
  "include": [
    "src/**/*"
  ]
}
hope this helps!
i
OK, thanks @victorious-church-57397 and @many-telephone-49025. I will try some of the suggestions here and post back here if i’m able to make this work or if I keep getting failures. I will keep my two repos updated with my latest changes so this can be easily reproducible if I’m still having issues.
@victorious-church-57397 I noticed that your package.json file does not have a type: module, so I will remove that from my
pulumi-beta
repo
v
yeah we did originally have it in there but it was causing us problems
i
OK.
v
if you adapt the package.json and the tsconfig.json i've sent over, it should work for you
i
Awesome! I will report back here soon
🟡 Hmm, I’m still not having luck with this. I made the following changes and I’m getting the same error about
SyntaxError: Cannot use import statement outside a module
in
pulumi-beta
: • add
"declaration": true,
in
tsconfig.json
• add
"files": ["bin"]
(I’m using
bin
where you are using
dist
@victorious-church-57397. If I do this, then nothing is installed in
node_modules
in when i run
npm i
in
pulumi-alpha
, since I am not committing the
bin
directory to the repo on GitHub
Does anyone know of any good open-source examples of what I’m trying to do?
(publish a simple pulumi package with typescript, and consume it in another pulumi project)
v
I have closed source examples I can probably tweak
i
That would be helpful @victorious-church-57397, thanks
m
I will try to reconstruct your case
So I can better play around but maybe @victorious-church-57397 is quicker with his source code
i
Thanks @many-telephone-49025. I think one issue might be that in
pulumi-alpha
when I do
npm i
, it only has
.ts
files and doesn't have any
.js
files. I am not super experienced with typescript, but I think that is part of what is going on with the error message I am seeing. Thank you for helping me to reproduce this 🙏
Could this be because I'm installing directly from github? I didn't want to bother pushing to npm
maybe I just need to add a
build
script in package.json?
c
@important-australia-24045 If I understand your issue properly, you want to split your deployment code as multiple TypeScript packages, and your issue is that Pulumi doesn't understand TypeScript across packages? Here is how solve this as a monorepo: https://github.com/pmuller/website Basically, I use yarn to manage the monorepo, and yarn.build to manage dependencies. Not sure however that you can do that across repositories (did not try that).
i
c
Yep, we're talking about the same thing here.
i
It’s not really pulumi-specific. I think there are some good suggestions in the answer here: https://stackoverflow.com/a/58257602/6084948
c
I tried all methods described in your SO answer. Monorepos is the cleanest approach IMO.
i
I do like this one tho:
Copy code
"postinstall": "tsc --outDir ./build"
Maybe it will be easier if I just publish to npm then, I guess
c
I did that in the past. I don't remember why I discarded that approach (maybe because it didn't work with a complex set of dependencies?)
v
You don’t need to publish to npm, you can use gh packages
I can send over my examples probably tomorrow if this could wait?
c
Maybe it will be easier if I just publish to npm then, I guess
I did that too. Working with multi repos and packages does the job. But that's still a lot of overhead compared to monorepos.
i
Thanks @victorious-church-57397, I think I’m OK at this point. I thought I had some weird issues in all of the config files, but I now realize that installing from github directly with typescript has some limitations that I need to work around in some way
v
What do you mean? We use GitHub in multiple repos and it’s fine
You need to setup a token which utilises packages and just run a build and then npm publish
c
"Overhead" = You still need to do release management of multiple packages and setup CI for them
v
I can send over a full template repo tomorrow, it’s worth doing right sometimes. Depends if you’re a one man band or will be expanding.
c
That's a good point. I went the monorepo way on a 3 people-sized project.
v
I love monorepo for smaller projects and even larger ones, I think for a package you might be using in multiple places should probably be independently managed and released
c
We lived with multi-repos + GH packages for a while, but we were quite happy to get rid of this as we had no need for such complexity.
v
That’s just my opinion though
Yeah it’s all about context
i
Copy code
~/git/github/pulumi-alpha$ pulumi preview
Previewing update (dev)

View Live: <https://app.pulumi.com/briancaffey/pulumi-alpha/dev/previews/f28c1725-f76e-4631-a26d-5fef4670eeca>

     Type                    Name              Plan       
 +   pulumi:pulumi:Stack     pulumi-alpha-dev  create     
 +   └─ my:modules:S3Bucket  my-bucket         create     
 +      └─ aws:s3:Bucket     my-bucket         create     


Outputs:
    bucketName: output<string>

Resources:
    + 3 to create

~/git/github/pulumi-alpha$
m
Nice, what did you do?
i
Thanks everyone for helping me with this. Now I can get started actually building things 🙂
As I described above, I had to commit the
bin
directory to my
pulumi-alpha
repo @many-telephone-49025, this is because I’m installing directly from github. Then I removed
"type": "module"
from the
pulumi-beta
repo and it worked
m
Nice work!
i
Helpful article: https://cameronnokes.com/blog/the-30-second-guide-to-publishing-a-typescript-package-to-npm/ I was able to use this to publish my dummy package and then install it in
pulumi-alpha
v
Let me know if you still want any examples tomorrow @important-australia-24045
Good stuff getting it working tho
m
Interesting @important-australia-24045 that in the article it is written
types
but you still have
typings
in yor
package.json
of
pulumi-beta
! And it’s still working!