Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/tinovyatkin/nest-puppeteer
Puppeteer (Headless Chrome) provider for Nest.js
https://github.com/tinovyatkin/nest-puppeteer
headless-chrome nestjs nestjs-library puppeteer
Last synced: 5 days ago
JSON representation
Puppeteer (Headless Chrome) provider for Nest.js
- Host: GitHub
- URL: https://github.com/tinovyatkin/nest-puppeteer
- Owner: tinovyatkin
- License: mit
- Created: 2020-06-16T17:49:00.000Z (over 4 years ago)
- Default Branch: master
- Last Pushed: 2023-11-07T23:12:53.000Z (about 1 year ago)
- Last Synced: 2024-12-03T23:41:00.330Z (18 days ago)
- Topics: headless-chrome, nestjs, nestjs-library, puppeteer
- Language: TypeScript
- Size: 1.6 MB
- Stars: 106
- Watchers: 4
- Forks: 23
- Open Issues: 23
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# nest-puppeteer [![codecov](https://codecov.io/gh/tinovyatkin/nest-puppeteer/branch/master/graph/badge.svg)](https://codecov.io/gh/tinovyatkin/nest-puppeteer)
## Description
This is a Puppeteer module for [NestJS](https://nestjs.com/), making it easy to inject the [Puppeteer](https://github.com/puppeteer/puppeteer) into your project. It's modeled after the official modules, allowing for asynchronous configuration and such.
## Installation
In your existing NestJS-based project:
```sh
npm install nest-puppeteer puppeteer
npm install -D @types/puppeteer
```## Usage
Overall, it works very similarly to any injectable module described in the NestJS documentation. You may want to refer to those docs as well -- and maybe the [dependency injection](https://docs.nestjs.com/fundamentals/custom-providers) docs too if you're still trying to wrap your head around the NestJS implementation of it.
### Simple example
In the simplest case, you can explicitly specify options you'd normally provide to your `puppeteer.launch` or the instance name using `PuppeteerModule.forRoot()`:
```typescript
import { Module } from '@nestjs/common';
import { PuppeteerModule } from 'nest-puppeteer';@Module({
imports: [
PuppeteerModule.forRoot(
{ pipe: true }, // optional, any Puppeteer launch options here or leave empty for good defaults */,
'BrowserInstanceName', // optional, can be useful for using Chrome and Firefox in the same project
),
],
})
export class CatsModule {}
```To inject the Puppeteer `Browser` object:
```typescript
import type { Browser } from 'puppeteer';
import { Injectable } from '@nestjs/common';
import { InjectBrowser } from 'nest-puppeteer';
import { Cat } from './interfaces/cat';@Injectable()
export class CatsRepository {
constructor(@InjectBrowser() private readonly browser: Browser) {}async create(cat: Cat) {
const version = await this.browser.version();
return { version };
}
}
```To inject a new incognito `BrowserContext` object:
```typescript
import { Module } from '@nestjs/common';
import { PuppeteerModule } from 'nest-puppeteer';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';@Module({
imports: [PuppeteerModule.forFeature()],
controllers: [CatsController],
providers: [CatsService],
})
export class CatsModule {}
``````typescript
import type { BrowserContext } from 'puppeteer';
import { Injectable } from '@nestjs/common';
import { InjectContext } from 'nest-puppeteer';
import { Cat } from './interfaces/cat';@Injectable()
export class CatsRepository {
constructor(
@InjectContext() private readonly browserContext: BrowserContext,
) {}async create(cat: Cat) {
const page = await this.browserContext.newPage();
await page.goto('https://test.com/');
return await page.content();
}
}
```Inject `Page` object:
```typescript
import { Injectable } from '@nestjs/common';
import { InjectPage } from 'nest-puppeteer';
import type { Page } from 'puppeteer';@Injectable()
export class CrawlerService {
constructor(@InjectPage() private readonly page: Page) {}async crawl(url: string) {
await this.page.goto(url, { waitUntil: 'networkidle2' });
const content = await this.page.content();
return { content };
}
}
```### Asynchronous configuration
If you want to pass in Puppeteer configuration options from a ConfigService or other provider, you'll need to perform the Puppeteer module configuration asynchronously, using `PuppeteerModule.forRootAsync()`. There are several different ways of doing this.
#### Use a factory function
The first is to specify a factory function that populates the options:
```typescript
import { Module } from '@nestjs/common'
import { PuppeteerModule } from 'nest-puppeteer'
import { ConfigService } from '../config/config.service'@Module({
imports: [PuppeteerModule.forRootAsync({
imports: [ConfigModule],
useFactory: (config: ConfigService) => {
launchOptions: config.chromeLaunchOptions,
},
inject: [ConfigService]
})]
})
export class CatsModule {}
```#### Use a class
Alternatively, you can write a class that implements the `PuppeteerOptionsFactory` interface and use that to create the options:
```typescript
import { Module } from '@nestjs/common';
import {
PuppeteerModule,
PuppeteerOptionsFactory,
PuppeteerModuleOptions,
} from 'nest-puppeteer';@Injectable()
export class PuppeteerConfigService implements PuppeteerOptionsFactory {
private readonly launchOptions = { pipe: true };
private readonly dbName = 'BestAppEver';createMongoOptions(): PuppeteerModuleOptions {
return {
launchOptions: this.launchOptions,
instanceName: this.instanceName,
};
}
}@Module({
imports: [
PuppeteerModule.forRootAsync({
useClass: PuppeteerConfigService,
}),
],
})
export class CatsModule {}
```Just be aware that the `useClass` option will instantiate your class inside the PuppeteerModule, which may not be what you want.
#### Use existing
If you wish to instead import your PuppeteerConfigService class from a different module, the `useExisting` option will allow you to do that.
```typescript
import { Module } from '@nestjs/common'
import { PuppeteerModule } from 'nest-puppeteer'
import { ConfigModule, ConfigService } from '../config/config.service'@Module({
imports: [PuppeteerModule.forRootAsync({
imports: [ConfigModule]
useExisting: ConfigService
})]
})
export class CatsModule {}
```In this example, we're assuming that `ConfigService` implements the `PuppeteerOptionsFactory` interface and can be found in the ConfigModule.
#### Use module globally
When you want to use `PuppeteerModule` in other modules, you'll need to import it (as is standard with any Nest module). Alternatively, declare it as a [global module](https://docs.nestjs.com/modules#global-modules) by setting the options object's `isGlobal` property to `true`, as shown below. In that case, you will not need to import `PuppeteerModule` in other modules once it's been loaded in the root module (e.g., `AppModule`).
```typescript
PuppeteerModule.forRoot({
isGlobal: true,
});
```## Stay in touch
- Author - [Konstantin Vyatkin]([email protected])
## License
`nest-puppeteer` is [MIT licensed](LICENSE).