2017-12-30 21 views
1

I持っていくつかのcomponentDidMountロジックと反応するコンポーネント:componentDidMount()ですべてが実行されますように、スクリーンショットを撮るために、何とか人形遣いに、小道具でこのコンポーネントを渡すため人形に反応成分を渡すことは可能ですか?

export default class MyComponent { 
    componentDidMount() { 
     // some changes to DOM done here by a library 
    } 

    render() { 
     return (
      <div>{props.data}</div> 
     ); 
    } 
} 

ことは可能ですか?これらの線に沿って何か:

const browser = await puppeteer.launch({ headless: true }); 
const page = await browser.newPage(); 

const html = ReactDOMServer.renderToString(<MyComponent data='' />); <-- but this skips the componentDidMount logic 
await page.setContent(html); 
await page.screenshot({ path: 'screenshot.png' }); 

私はpage.goto()を使用することができます知っているが、私はこのようなショートカットを避け、代わりにコンポーネントにちょうど直接必要なすべての小道具を渡すしたいと思いますいくつかの複雑なログイン・ロジックを持っていますか?

答えて

2

私はこの質問に答えましたhere。 ここでも同じことを試してみましょう。

babel、webpack、puppeteerパッケージをインストールします。

{ 
    "name": "react-puppeteer", 
    "version": "1.0.0", 
    "main": "index.js", 
    "license": "MIT", 
    "scripts": { 
    "compile": "webpack", 
    "build": "webpack -p", 
    "start": "webpack && node pup.js" 
    }, 
    "devDependencies": { 
    "babel-core": "^6.26.0", 
    "babel-loader": "^7.1.2", 
    "babel-preset-env": "^1.6.1", 
    "babel-preset-es2015": "^6.24.1", 
    "babel-preset-react": "^6.24.1", 
    "react": "^16.2.0", 
    "react-dom": "^16.2.0", 
    "webpack": "^3.10.0", 
    "webpack-dev-middleware": "^2.0.3" 
    }, 
    "dependencies": { 
    "puppeteer": "^0.13.0" 
    } 
} 

のWebPACKの設定を準備し、

const webpack = require('webpack'); 

const loaders = [ 
    { 
    test: /\.jsx?$/, 
    exclude: /node_modules/, 
    loader: 'babel-loader', 
    query: { 
     presets: ['babel-preset-es2015', 'babel-preset-react'], 
     plugins: [] 
    } 
    } 
]; 

module.exports = { 
    entry: './entry.js', 
    output: { 
    path: __dirname, 
    filename: 'bundle.js', 
    libraryTarget: 'umd' 
    }, 
    module: { 
    loaders: loaders 
    } 
}; 

は、このファイルには をエントリファイルを作成し、代わりに直接素子を実装、我々は、後でそれにアクセスできるように、ウィンドウにエクスポート。我々はwebpackを実行すると

import React from 'react'; 
import { render } from 'react-dom'; 

class Hello extends React.Component { 
    render() { 
    return <h1>Hello, {this.props.name}</h1>; 
    } 
} 

// accept a name for example and a domNode where to render 
function renderIt(name, domNode) { 
    render(<Hello name={name} />, domNode); 
} 

window.renderIt = renderIt; 

、bundle.jsファイルを生成するために起こっています。私たちは人形劇に使うことができます。

それらはpuppeteerのinjectFile関数を非推奨にしました。したがって、私たちはそれを復活させようとしています。ここにサンプルレポがあります。糸を追加することができます。

https://github.com/entrptaher/puppeteer-inject-file 

ここで、人形スクリプトを作成できます。

const puppeteer = require('puppeteer'); 
const injectFile = require('puppeteer-inject-file'); 

(async() => { 
    const browser = await puppeteer.launch({ headless: false }); 
    const page = await browser.newPage(); 
    await page.goto('https://github.com'); 
    await injectFile(page, require.resolve('./bundle.js')); 
    await page.evaluate(() => { 
    renderIt("Someone", document.querySelector('div.jumbotron.jumbotron-codelines > div > div > div > h1')); 
    }); 
    await page.screenshot({ path: 'example.png' }); 
    await browser.close(); 
})(); 

そして、我々はこれを実行すると、我々は次のような結果を得るため、

enter image description here

我々はcomponentDidMount()呼び出しを追加した場合、我々はあまりにもそれを行っている可能性があります。しかし、私たちがもっと修正を加えようとしているのであれば、人形師のスクリプトは他の質問で何度も議論されたことを待たなければなりません。

コンポーネントがロードされたら、何かを返すような状態になったとします。

class Hello extends React.Component { 
    state = { 
    jokes: null 
    }; 

    componentDidMount() { 
    const self = this; 
    const jokesUrl = `http://api.icndb.com/jokes/random?firstName=John&amp;lastName=Doe`; 
    fetch(jokesUrl) 
     .then(data => data.json()) 
     .then(data => { 
     self.setState({ 
      jokes: data.value.joke 
     }); 
     }); 
    } 

    render() { 
    if(!!this.state.jokes){ 
     return <p id='quote'>{this.state.jokes}</p> 
    } 
    return <h1>Hello, {this.props.name}</h1>; 
    } 
} 

人形遣いで、私たちはバベル・プリセット・ステージ2を必要とするかもしれません、このような要素のために

... 
    await injectFile(page, require.resolve('./bundle.js')); 
    await page.evaluate(() => { 
    renderIt("Someone", document.querySelector('div')); 
    }); 
    await page.waitFor('p#quote'); 
    ... 

を待つことができますが、私はあなたにそれを残しておきます。そして、ここでは...、忍耐のため

+0

おかげ

enter image description here

図は、問題を自分の残りの部分:)結果です!私は今、ウェブパックを避けようとしていたことを認識していますが、私はこれが行く方法ですね、もう一度ありがとう! – usagidon

関連する問題