.evaluate
ne retourne pas un élément dom. Et, vous essayez de modifier les éléments dans un contexte différent. La page dans la fenêtre du navigateur et le contexte que vous avez dans votre nodeJS sont absolument différents.
Voici une façon différente de traiter React et Puppeteer. D'abord, j'ai un fichier d'entrée où j'exporte la fonction à la fenêtre. En faisant cela, je peux facilement y accéder à partir du contexte des navigateurs. Au lieu de fenêtre, vous pouvez réellement l'exporter et essayer s'exposer-chargeur et ainsi de suite. Je vais utiliser webpack pour le construire.
import React from 'react';
import { render } from 'react-dom';
function Hello() {
return <h1>Hello from React</h1>;
}
function renderIt(domNode) {
render(<Hello />, domNode);
}
window.renderIt = renderIt;
Sur la configuration 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
}
};
Maintenant, chaque fois que je lance webpack, il va créer un fichier bundle.js pour moi. Maintenant, nous allons avoir un fichier marionnettiste,
const puppeteer = require('puppeteer');
(async() => {
const browser = await puppeteer.launch({ headless: false });
const page = await browser.newPage();
await page.goto('https://github.com');
await page.addScriptTag({ path: require.resolve('./bundle.js') });
await page.evaluate(() => {
renderIt(document.querySelector('div.jumbotron.jumbotron-codelines > div > div > div > h1'));
});
await page.screenshot({ path: 'example.png' });
await browser.close();
})();
Comme vous pouvez le voir, je suis en utilisant la fonction renderIt que j'exposé à la fenêtre précédente. Et quand je le lance, voici le résultat,
Sweet! Bonjour de réagir :)
Oh! Et s'il échoue à exécuter le script sur la page en raison du problème CORS, vous pouvez l'injecter à la place en utilisant l'ancienne fonction injectFile, jusqu'à ce qu'ils corrigent leur fonction addScriptTag ou suppriment la dépréciation de injectFile.
/**
* injects file to puppeteer page context
* @param {Object} page context where to execute the script
* @param {String} filePath path of specific script
* @return {Promise} Injects content to page context
*/
const fs = require('fs');
async function injectFile(page, filePath) {
let contents = await new Promise((resolve, reject) => {
fs.readFile(filePath, 'utf8', (err, data) => {
if (err) return reject(err);
resolve(data);
});
});
contents += `//# sourceURL=` + filePath.replace(/\n/g, '');
return page.mainFrame().evaluate(contents);
}
// usage: await injectFile(page, require.resolve('FILE PATH'));
// export it if you want to keep things seperate
Que contient le testDocument.html? At-il tous les prérequis pour le rendu d'une application de réaction? Si c'est le cas, vous devriez le rendre dans la fonction d'évaluation, pas en dehors de celle-ci (où console.log (testWrapper)) est maintenant. – tomahaug
peut-être faire référentiel minimaliste pour reproduire l'erreur, donnera une facilité à examiner le problème. –