Giter Club home page Giter Club logo

html-to-react-components's Introduction

Logo

If you like what I do, consider supporting my work via donation

Extract annotated portions of HTML into React components as separate modules. The structure of HTML is preserved by importing child components and replacing appropriate pieces of HTML with them. As a result you get an entire components tree ready to be rendered.

Try in online REPL

usage example animation

Contents

When to use it

This utility was designed to free React developers from a boring task of translating HTML into components.

Imagine you just got a pile of HTML from your designers. The first thing you will do is break HTML into React components. This is boring and should be automated!

Installation

$ npm i -g html-to-react-components

Usage

HTML element with data-component attribute will be converted into separate React components. The value of the attribute is the name of the React component.

Additionally specify which HTML attributes should be exposed as React props using public: prefix.

<input public:type="text" id="input" data-component="Input" />
// at usage place
<Input type="text" />;
// ----^^^^^^^^^^^

// in component's module
class Input extends React.Component {
  render() {
    const { type } = this.props; // <----
    return <input type={type} id="input" />;
    // -----------^^^^^^^^^^^
  }
}

See and run test.js file for usage example and output.

CLI

$ html2react "./src/*.html"

You can also use any glob pattern to recursively generate the corresponding react file. Just make sure to use double quotes when specifying the pattern:

$ html2react "./src/**/*.html"

Options

componentType, --component, -c

Type of generated React components.

Values:

  • functional (default)
  • class
  • es5

moduleType, --module, -m

Type of generated JavaScript modules.

Values:

  • es (EcmaScript module, default)
  • cjs (CommonJS)

moduleFileNameDelimiter, --delimiter, -d

Delimiter character to be used in modules filename.

If you don't specify a delimiter, or pass -d without a value, then the component name in the HTML will be used unchanged as the filename. If you do specify a delimiter character, then the module name is broken into words, joined with the delimiter and lower-cased.

output

Configuration options for output to file system.

path, --out, -o

Output directory path.

Default is components directory in the current directory.

fileExtension, --ext, -e

Output files extension.

Default value is js.

Node.js API

const extractReactComponents = require("html-to-react-components");

extractReactComponents(
  `<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>
<body>

  <header class="header" data-component="Header">

    <h1 class="heading" data-component="Heading">Hello, world!</h1>

    <nav class="nav" data-component="Nav">
      <ul class="list">
        <li class="list-item" data-component="ListItem">#1</li>
        <li class="list-item" data-component="ListItem">#2</li>
      </ul>
    </nav>

  </header>

</body>
</html>
`,
  {
    componentType: "functional",
    moduleType: false,
  }
);

/*
{ Header: 'const Header = () => <header className="header">\n\n    <Heading></Heading>\n\n    <Nav></Nav>\n\n  </header>;',
  Heading: 'const Heading = () => <h1 className="heading">Hello, world!</h1>;',
  Nav: 'const Nav = () => <nav className="nav">\n      <ul className="list">\n        <ListItem></ListItem>\n        <ListItem></ListItem>\n      </ul>\n    </nav>;',
  ListItem: 'const ListItem = () => <li className="list-item">#2</li>;' }
*/

Building for browser

When building for in-browser usage an env variable IN_BROWSER is required to be set at compile time in order to disable Node.js-specific modules. Note that code formatting is not included in in-browser bundle.

Example of defining a var in Webpack config:

  plugins: [
    new webpack.DefinePlugin({
      IN_BROWSER: JSON.stringify(true),
    }),
  ],

Resources

A quick video demo on converting a simple HTML page into React components and rendering them into the same looking UI.

Annotating HTML in the editor is not the best experience, because you cannot see rendered UI itself. It's possible to annotate HTML using DevTools. Be aware that you'll have to spend time on copying and pasting markup from DevTools into files which will be processed.

usage example with DevTools animation

Ecosystem

  • extract-to-react is an extension for Chrome and Chromium browsers built on top of html-to-react-components which allows you to extract HTML and CSS into React components and load them in CodePen or JSFiddle.

Contributing

If you spotted a bug, please, submit a pull request with a bug fix. If you would like to add a feature or change existing behaviour, open an issue and tell about what exactly you want to change/add.

License

MIT

html-to-react-components's People

Contributors

benjaminmwilson avatar chun-yang avatar dependabot[bot] avatar gitter-badger avatar jesstelford avatar roman01la avatar sballesteros avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

html-to-react-components's Issues

Question: Glob Pattern Support

Hi, I was wondering if it's possible to use a glob pattern like this:

html2react ./static/**/*.html

I have tried it and it only picks up one of the files. I have a feeling it's because of glob(cli.input[0]... in lib/cli.js.

This is the folder structure that I have:

./static/
├── profile
│   ├── profile.css
│   └── profile.html
└── settings
    ├── settings.css
    └── settings.html

Thanks!

Plugin error

Hi,

I'm facing this issue when running against my index.html

'''/usr/local/lib/node_modules/html-to-react-components/node_modules/babylon/lib/index.js:4457
throw err;
^

SyntaxError: Unexpected token (21:59)
at Parser.pp$5.raise (/usr/local/lib/node_modules/html-to-react-components/node_modules/babylon/lib/index.js:4454:13)
at Parser.pp.unexpected (/usr/local/lib/node_modules/html-to-react-components/node_modules/babylon/lib/index.js:1761:8)
at Parser.pp$9.jsxParseIdentifier (/usr/local/lib/node_modules/html-to-react-components/node_modules/babylon/lib/index.js:7029:10)
at Parser.pp$9.jsxParseNamespacedName (/usr/local/lib/node_modules/html-to-react-components/node_modules/babylon/lib/index.js:7040:19)
at Parser.pp$9.jsxParseAttribute (/usr/local/lib/node_modules/html-to-react-components/node_modules/babylon/lib/index.js:7135:20)
at Parser.pp$9.jsxParseOpeningElementAt (/usr/local/lib/node_modules/html-to-react-components/node_modules/babylon/lib/index.js:7147:31)
at Parser.pp$9.jsxParseElementAt (/usr/local/lib/node_modules/html-to-react-components/node_modules/babylon/lib/index.js:7169:29)
at Parser.pp$9.jsxParseElementAt (/usr/local/lib/node_modules/html-to-react-components/node_modules/babylon/lib/index.js:7182:30)
at Parser.pp$9.jsxParseElementAt (/usr/local/lib/node_modules/html-to-react-components/node_modules/babylon/lib/index.js:7182:30)
at Parser.pp$9.jsxParseElementAt (/usr/local/lib/node_modules/html-to-react-components/node_modules/babylon/lib/index.js:7182:30)'''

Bug: Quotation marks not being converted correctly? Renders as unknown character.

Yesterday I ran code through the package and it was fine, but today it failed to process any of the quotation marks in my html document when converting to react component. I 'm not 100% sure that something on my end didn't set it off, though I am at a loss to what that could have been. Nothing has changed other than some of the html content in the file and the file name, which was updated to reflect the version I am working on.

This happened with all single and double quotation marks.

image

Update:

Also failed to convert:

Ellipses--

image

Dash--

image

should be:

image

Potential Redundancy (No-op)

Definitely not urgent, but in the file jsx.js near the bottom of the childrenToComponents function it looks like you do the same filter on the children array twice. Maybe you meant to use temp in the return block?


const temp = children.filter(function(child, i) {
    return children.indexOf(child) === i;
  })

  return {
    ast: ast,
    children: children.filter(function(child, i) {
      return children.indexOf(child) === i;
    }),
    childPublicAttrs
  };

First property of inline style missing trailing comma

On commit 775e9b1

This minimal test case:

console.log(require('html-to-react-components')(
  '<div data-component="Component" style="padding:0; display:inline"></div>'
).Component);

Produces this output:

import React from 'react';

const Component = React.createClass({
  render() {
    return <div style={{
        padding: 0
        display: 'inline'
      }} />;
  }
});

Notice the padding: 0 line is missing a trailing comma.

When more than two inline style elements exist, commas are correctly inserted for properties other than the first. For example:

console.log(require('html-to-react-components')(
  '<div data-component="Component" style="padding:0; display:inline; margin: 10; border: none"></div>'
).Component);

Produces

import React from 'react';

const Component = React.createClass({
  render() {
    return <div style={{
        padding: 0
        display: 'inline',
        margin: 10,
        border: 'none'
      }} />;
  }
});

API Usage: Call with Browserfy in effect returns [object Object]

Hi @roman01la ,

So I've implemented all the changes for v1.6 and when I call html2react(html_text_blob) the output is simply [object Object]. I've attached the output that I'm capturing along with trying to generate react components along with the code of the plugin that generates the zip contents.

Any guidance you could provide would be great and much appreciated.

grapesjs_reactjs_components_1518209170035.zip

`import grapesjs from "grapesjs";
import JSZip from "jszip";
import FileSaver from "file-saver";
import html2reactjs from "html-to-react-components";

export default grapesjs.plugins.add(
"reactjs-component-builder",
(editor, opts = {}) => {
const options = {
...{
// default options
},
...opts
};

  let c = opts || {};
let config = editor.getConfig();
let stylePrefix = config.stylePrefix;
let button = document.createElement("BUTTON");
let cmd = "gjs-export-reactjs";
let defaults = {
  addReactJsButton: 1,
  ReactJsButtonLabel: "Export ReactJS",
  preHtml: '<!doctype html><html lang="en"><head><meta charset="utf-8"><link rel="stylesheet" href="./css/style.css"></head><body>',
  postHtml: "</body><html>",
  preCss: "",
  postCss: ""
};

for (let name in defaults) {
  if (!(name in c)) {
    c[name] = defaults[name];
  }
}

button.innerHTML = c.ReactJsButtonLabel;
button.className = stylePrefix + "btn-prim";
button.style.paddingLeft = "30px";

// Add command
editor.Commands.add(cmd, {
  run() {

    alert("Starting Generation of ReactJS Components");

    let fileNamePrefix = "grapesjs_reactjs_components_";
    let fileExtension = ".zip";
    let htmlFileName = "reactjs_index.html";
    let cssFileName = "reactjs_style.css";
    let jsxFileName = "reactjs_components.jsx";

    alert("Set Variables");

    let zip = new JSZip();
    let htmlDir = zip.folder("html");
    let cssDir = zip.folder("css");
    let componentsDir = zip.folder("components");

    alert("Setup Zip Structure");

    let fn = fileNamePrefix + Date.now() + fileExtension;
    let htmlPage = c.preHtml + editor.getHtml() + c.postHtml;
    let htmlStyle = c.preCss + editor.getCss() + c.postCss;

    alert("HTML: " + htmlPage);
    alert("CSS: " + htmlStyle);

    htmlDir.file(htmlFileName, htmlPage);
    cssDir.file(cssFileName, htmlStyle);

    alert("Stored HTML & CSS to Zip");

    let out = html2reactjs(htmlPage) + "";
    componentsDir.file(jsxFileName, out);
    
    alert("Generated ReactJS Components: " + out);

    zip.generateAsync({ type: "blob" }).then(content => {
      FileSaver.saveAs(content, fn);
    });

    alert("ReactJS saved to: " + fn);        
  }
});

//Add button inside export dialog
if (c.addReactJsButton) {
  editor.on("run:export-template", () => {
    editor.Modal.getContentEl().appendChild(button);
    button.onclick = () => {
      editor.runCommand(cmd);
    };
  });
}

}
);`

Error SyntaxError: Unexpected token

Hi,

i'm on Mac and i installed through this command "npm i -g html-to-react-components".

To take a test I took your index.html present in "example" and run this command in the same path "html2react "./*.html" ".

It brings me back this error:

image

This error happens to me even when I type only the "html2react" command.
I did a test on Linux and the same thing happens.

Fix tests

Tests are failing due to API changes in transitive dependencies 😡. I don't have time to fix this.

 FAIL  test/test.js
  ● Test suite failed to run

    SecurityError: localStorage is not available for opaque origins

      at Window.get localStorage [as localStorage] (node_modules/jsdom/lib/jsdom/browser/Window.js:257:15)
          at Array.forEach (<anonymous>)

Test Suites: 1 failed, 1 total
Tests:       0 total
Snapshots:   0 total
Time:        0.738s

is there debugging mode?

I tried to run html2react "./index.html" and get Successfully generated 0 components: and I want to get more data on where go wrong.... or maybe @roman01la you know a way I should dig into the code base and best entry point for this situation?

Thanks!

Inline styling leaves out "px" with line-height conversions

I have ran the converter a few times and noticed it does not convert 'line-height' accurately.
Instead of converting it as with other styling items such as 'width' or 'align' where the value is placed in quotation marks (ex. "35px"), it converts it to number only and leaves out the size value and quotation marks. It does make the conversion to camel case.
html2react-texteditorview

example:
Plain html style:

html-inline-styling

same file converted using html-to-react-components

html2react-inline-styling

npm warn

hello there, i got errors from running command just to let you know !

Command :
npm install html-to-react-components or npm i -g html-to-react-components

Output :

npm WARN deprecated [email protected]: this library is no longer supported
npm WARN deprecated [email protected]: Please upgrade  to version 7 or higher.  Older versions may use Math.random() in certain circumstances, which is known to be problematic.  See https://v8.dev/blog/math-random for details.
npm WARN deprecated [email protected]: request has been deprecated, see https://github.com/request/request/issues/3142
npm WARN deprecated [email protected]: core-js@<3.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Please, upgrade your dependencies to the actual version of core-js.
npm WARN deprecated [email protected]: core-js@<3.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Please, upgrade your dependencies to the actual version of core-js.

added 188 packages, and audited 189 packages in 7s

9 packages are looking for funding
  run `npm fund` for details

9 vulnerabilities (7 low, 2 high)

To address all issues, run:
  npm audit fix

Run `npm audit` for details.

Command :
html2react index.html

Output :

html2react: The term "html2react" is not recognized as the name of a cmdlet, function, script file, or
executable program. Check the spelling of the name, or if a path exists, verify that the path
is correct and try again.
At character Line: 1: 1
+ html2react index.html
+ ~~~~~~~~~~
     + CategoryInfo: ObjectNotFound: (html2react: String) [], CommandNotFoundException
     + FullyQualifiedErrorId: CommandNotFoundException

Unterminated JSX contents

I have tried to convert html to React, but received such an error

Romans-MacBook-Pro:test r0m4$ sudo html2react index.html
/usr/local/lib/node_modules/html-to-react-components/node_modules/prettier/index.js:9750
throw error;
^

SyntaxError: Unterminated JSX contents (1158:11)
1156 |
1157 |

1158 | ;
| ^
1159 | }
1160 |
1161 | }
at e (/usr/local/lib/node_modules/html-to-react-components/node_modules/prettier/parser-babylon.js:1:282)
at Object.parse (/usr/local/lib/node_modules/html-to-react-components/node_modules/prettier/parser-babylon.js:1:262260)
at Object.parse (/usr/local/lib/node_modules/html-to-react-components/node_modules/prettier/index.js:9739:19)
at coreFormat (/usr/local/lib/node_modules/html-to-react-components/node_modules/prettier/index.js:13252:23)
at format (/usr/local/lib/node_modules/html-to-react-components/node_modules/prettier/index.js:13510:73)
at formatWithCursor (/usr/local/lib/node_modules/html-to-react-components/node_modules/prettier/index.js:13526:12)
at /usr/local/lib/node_modules/html-to-react-components/node_modules/prettier/index.js:44207:15
at Object.format (/usr/local/lib/node_modules/html-to-react-components/node_modules/prettier/index.js:44226:12)
at /usr/local/lib/node_modules/html-to-react-components/lib/format.js:5:27
at Array.reduce () {
loc: { start: { line: 1158, column: 11 } },
codeFrame: '\x1B[0m \x1B[90m 1156 | \x1B[39m \x1B[33m<\x1B[39m\x1B[33m/\x1B[39m\x1B[33mdiv\x1B[39m\x1B[33m>\x1B[39m\x1B[0m\n' +
'\x1B[0m \x1B[90m 1157 | \x1B[39m \x1B[33m<\x1B[39m\x1B[33m/\x1B[39m\x1B[33mfooter\x1B[39m\x1B[33m>\x1B[39m\x1B[0m\n' +
'\x1B[0m\x1B[31m\x1B[1m>\x1B[22m\x1B[39m\x1B[90m 1158 | \x1B[39m \x1B[33m<\x1B[39m\x1B[33m/\x1B[39m\x1B[33mdiv\x1B[39m\x1B[33m>\x1B[39m\x1B[33m;\x1B[39m\x1B[0m\n' +
'\x1B[0m \x1B[90m | \x1B[39m \x1B[31m\x1B[1m^\x1B[22m\x1B[39m\x1B[0m\n' +
'\x1B[0m \x1B[90m 1159 | \x1B[39m }\x1B[0m\n' +
'\x1B[0m \x1B[90m 1160 | \x1B[39m\x1B[0m\n' +
'\x1B[0m \x1B[90m 1161 | \x1B[39m}\x1B[0m'
}

here is the HTML that I tried to convert: https://drive.google.com/file/d/1JYDMWeFsBl1bJU0Oz8UtlOBBYOjuSepI/view?usp=sharing

Format generated code

The output code currently goes straight from Babylon generator and AST doesn't include code formatting information. Since generated code is intended to be used later by developers, it should be formatted according to some preferences. This will free developers from formatting every module by hand.

The sample output currently is the following:

ES5 React component as ES6 module

import React from "react";
import Heading from "./heading";
import Nav from "./nav";
const Header = React.createClass({
  render() {
    return <header className="header">
        <Heading></Heading>
        <Nav></Nav>
      </header>;
  }

});
export default Header;

ES5 React component as CommonJS module

const React = require("react");

const Heading = require("./heading");

const Nav = require("./nav");

const Header = React.createClass({
  render() {
    return <header className="header">
        <Heading></Heading>
        <Nav></Nav>
      </header>;
  }

});
module.exports = Header;

ES6 React component as ES6 module

import React from "react";
import Heading from "./heading";
import Nav from "./nav";

class Header extends React.Component {
  render() {
    return <header className="header">
        <Heading></Heading>
        <Nav></Nav>
      </header>;
  }

}

export default Header;

ES6 React component as CommonJS module

const React = require("react");

const Heading = require("./heading");

const Nav = require("./nav");

class Header extends React.Component {
  render() {
    return <header className="header">
        <Heading></Heading>
        <Nav></Nav>
      </header>;
  }

}

module.exports = Header;

Stateless React component as ES6 module

import React from "react";
import Heading from "./heading";
import Nav from "./nav";

const Header = () => <header className="header">
        <Heading></Heading>
        <Nav></Nav>
      </header>;

export default Header;

Stateless React component as CommonJS module

const React = require("react");

const Heading = require("./heading");

const Nav = require("./nav");

const Header = () => <header className="header">
        <Heading></Heading>
        <Nav></Nav>
      </header>;

module.exports = Header;

The code should be formatted using CST. This format supports whitespace, punctuators and comments.

TODO

  • Insert new line character between import/require declarations block and component's variable declaration in ES5 React components as ES6 modules.
  • Insert new line character between component's variable declaration and export declaration in ES5 React components as ES6 and CommonJS modules.
  • Remove new line characters between imported module variable declarations in CommonJS modules.
  • Wrap JSX into parens if root JSX element doesn't have child JSX elements and move JSX on a new line.

TBD

  • Use .eslintrc config for code formatting, if one exists in the project.

Successfully generated 0 components?

Hi, I tried a simple command "html2react index.html" on a few sample index.html but all I got is "Successfully generated 0 components"?

One example index.html I used is just a good old CRA index.html.

I think the issue may be I did not annotate everything in data-component, let me try it and get back to this issue.

Update: yep, that's the issue, closing this issue.

Functional option doesn't work

I tried the example from the README for Node API and it seems to only return class components.
This is the example:

const extractReactComponents = require("html-to-react-components");

extractReactComponents(
  `<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>
<body>

  <header class="header" data-component="Header">

    <h1 class="heading" data-component="Heading">Hello, world!</h1>

    <nav class="nav" data-component="Nav">
      <ul class="list">
        <li class="list-item" data-component="ListItem">#1</li>
        <li class="list-item" data-component="ListItem">#2</li>
      </ul>
    </nav>

  </header>

</body>
</html>
`,
  {
    componentType: "functional",
    moduleType: false,
  }
);

/*
{ Header: 'const Header = () => <header className="header">\n\n    <Heading></Heading>\n\n    <Nav></Nav>\n\n  </header>;',
  Heading: 'const Heading = () => <h1 className="heading">Hello, world!</h1>;',
  Nav: 'const Nav = () => <nav className="nav">\n      <ul className="list">\n        <ListItem></ListItem>\n        <ListItem></ListItem>\n      </ul>\n    </nav>;',
  ListItem: 'const ListItem = () => <li className="list-item">#2</li>;' }
*/

When I run it in a completely new Node environment without anything else installed, this is what it outputs:

{       
  Header: 'import React from "react";\n' +
    'import Heading from "./Heading";\n' +
    'import Nav from "./Nav";\n' +
    '\n' +
    'class Header extends React.Component {\n' +
    '  render() {\n' +
    '    return (\n' +
    '      <header className="header">\n' +
    '        <Heading></Heading>\n' +
    '        <Nav></Nav>\n' +
    '      </header>\n' +
    '    );\n' +
    '  }\n' +
    '}\n' +
    '\n' +
    'export default Header;\n',
  Heading: 'import React from "react";\n' +
    '\n' +
    'class Heading extends React.Component {\n' +
    '  render() {\n' +
    '    return <h1 className="heading">Hello, world!</h1>;\n' +
    '  }\n' +
    '}\n' +
    '\n' +
    'export default Heading;\n',
  Nav: 'import React from "react";\n' +
    'import ListItem from "./ListItem";\n' +
    '\n' +
    'class Nav extends React.Component {\n' +
    '  render() {\n' +
    '    return (\n' +
    '      <nav className="nav">\n' +
    '        <ul className="list">\n' +
    '          <ListItem></ListItem>\n' +
    '          <ListItem></ListItem>\n' +
    '        </ul>\n' +
    '      </nav>\n' +
    '    );\n' +
    '  }\n' +
    '}\n' +
    '\n' +
    'export default Nav;\n',
  ListItem: 'import React from "react";\n' +
    '\n' +
    'class ListItem extends React.Component {\n' +
    '  render() {\n' +
    '    return <li className="list-item">#1</li>;\n' +    
    '  }\n' +
    '}\n' +
    '\n' +
    'export default ListItem;\n'
}

several same html component may convert into one and lost some component

input:

      <div class="field" data-component="Field">
        <label for="input" data-component="Label">Input<span>label</span></label>
        <input type="text" id="input" data-component="Input">
        <button onclick="location.href='http://www.baidu.com'" type="button" data-component="Input">跳转到百度</button>
        <button onclick="location.href='http://www.qq.com'" type="button" data-component="Input">跳转到QQ</button>
        <button onclick="location.href='http://www.sohu.com'" type="button" data-component="Input">跳转到sohu</button>
        <p><a href="index2.html" data-component="A">跳转到本地文件</a></p>
      </div>

output:

import React from "react";
  
class Input extends React.Component {
  render() {
    return (
      <button onclick="location.href='http://www.sohu.com'" type="button">
        跳转到sohu
      </button>
    );
  }
}

export default Input;

And which newbee can tell me why

Inline required images are broken

When requiring images inline like:

<img src={require('...')} />

The generated output adds quotes around breaking the image.

<img src="{require('...')}" />

Is there anyway to support this syntax?

Successfully generated 0 components:

the command html2react "./html/index.html" cannot generate any component
results in message
Successfully generated 0 components:
Saved into "components" directory

Successfully generated 0 components

Hello,

I installed the CLI tool and ran it against an HTML file, a directory of HTML files, but it just says...

image

I'm on Windows x64 but tried it on my Debian x64 build and got the same result.

Tried Nodejs 14.15.5 and 15,8.0.

Unexpected token

This is the content of my test.html file.

<div class="card__inner color-background-2 gradient ratio" style="--ratio-percent: 75.0128270908158%;" data-component="Test">
    <div class="card__media">
        <div class="media media--transparent media--hover-effect">
            <img
            srcset="//cdn.shopify.com/s/files/1/0557/2853/7679/products/20221220_102926.jpg?v=1671528780&amp;width=165 165w,//cdn.shopify.com/s/files/1/0557/2853/7679/products/20221220_102926.jpg?v=1671528780&amp;width=360 360w,//cdn.shopify.com/s/files/1/0557/2853/7679/products/20221220_102926.jpg?v=1671528780&amp;width=533 533w,//cdn.shopify.com/s/files/1/0557/2853/7679/products/20221220_102926.jpg?v=1671528780&amp;width=720 720w,//cdn.shopify.com/s/files/1/0557/2853/7679/products/20221220_102926.jpg?v=1671528780&amp;width=940 940w,//cdn.shopify.com/s/files/1/0557/2853/7679/products/20221220_102926.jpg?v=1671528780&amp;width=1066 1066w,//cdn.shopify.com/s/files/1/0557/2853/7679/products/20221220_102926.jpg?v=1671528780 3898w"
            src="//cdn.shopify.com/s/files/1/0557/2853/7679/products/20221220_102926.jpg?v=1671528780&amp;width=533"
            sizes="(min-width: 1200px) 267px, (min-width: 990px) calc((100vw - 130px) / 4), (min-width: 750px) calc((100vw - 120px) / 3), calc((100vw - 35px) / 2)"
            alt="Kom bare ind - Dørhænger i træ" class="motion-reduce" loading="lazy" width="3898"
            height="2924">
        </div>
    </div>
    <div class="card__content">
        <div class="card__information">
            <h3 class="card__heading">
            <a href="/products/kom-barr-ind-dorhaenger-i-trae" class="full-unstyled-link">
                Kom bare ind - Dørhænger i træ
            </a>
            </h3>
        </div>
        <div class="card__badge bottom left"></div>
    </div>
</div>

html2react test.html throws an error

C:\Users\Piotrek\AppData\Roaming\npm\node_modules\html-to-react-components\node_modules\babylon\lib\index.js:4457
  throw err;
  ^

SyntaxError: Unexpected token (1:71)
    at Parser.pp$5.raise (C:\Users\Piotrek\AppData\Roaming\npm\node_modules\html-to-react-components\node_modules\babylon\lib\index.js:4454:13)
    at Parser.pp.unexpected (C:\Users\Piotrek\AppData\Roaming\npm\node_modules\html-to-react-components\node_modules\babylon\lib\index.js:1761:8)
    at Parser.pp$3.parseIdentifier (C:\Users\Piotrek\AppData\Roaming\npm\node_modules\html-to-react-components\node_modules\babylon\lib\index.js:4332:10)
    at Parser.pp$3.parsePropertyName (C:\Users\Piotrek\AppData\Roaming\npm\node_modules\html-to-react-components\node_modules\babylon\lib\index.js:4156:96)
    at Parser.pp$3.parseObj (C:\Users\Piotrek\AppData\Roaming\npm\node_modules\html-to-react-components\node_modules\babylon\lib\index.js:4045:12)
    at Parser.pp$3.parseExprAtom (C:\Users\Piotrek\AppData\Roaming\npm\node_modules\html-to-react-components\node_modules\babylon\lib\index.js:3719:19)
    at Parser.parseExprAtom (C:\Users\Piotrek\AppData\Roaming\npm\node_modules\html-to-react-components\node_modules\babylon\lib\index.js:7238:22)
    at Parser.pp$3.parseExprSubscripts (C:\Users\Piotrek\AppData\Roaming\npm\node_modules\html-to-react-components\node_modules\babylon\lib\index.js:3494:19)
    at Parser.pp$3.parseMaybeUnary (C:\Users\Piotrek\AppData\Roaming\npm\node_modules\html-to-react-components\node_modules\babylon\lib\index.js:3474:19)
    at Parser.pp$3.parseExprOps (C:\Users\Piotrek\AppData\Roaming\npm\node_modules\html-to-react-components\node_modules\babylon\lib\index.js:3404:19) {
  pos: 71,
  loc: Position { line: 1, column: 71 }
}

html2react 1.6.6 node v16.15.1

Any idea what's wrong with test.html? Thanks in advance for the answer.

PS:
Instead of marking the same HTML this way:

<div class="card__inner color-background-2 gradient ratio" style="--ratio-percent: 75.0128270908158%;" data-component="Test">
    <div class="card__media">
        ...
    </div>
    <div class="card__content">
        ...
    </div>
</div>

Marking HTML this way works:

<div class="card__inner color-background-2 gradient ratio" style="--ratio-percent: 75.0128270908158%;">
    <div class="card__media" data-component="Test">
        ...
    </div>
    <div class="card__content" data-component="Test2">
        ...
    </div>
</div>

Successfully generated 0 components after adding data-component argument

Hi,
I'm looking at your html2react tool and i have an issue regarding the usage.
I have inserted the "data-component" argument to every element present in my index.html, yet when I run :
html2react <path_to_my_index.html>

I get this :
Successfully generated 0 components: Saved into "components" directory

When i try on the sample you provided, it works fine, I'm wondering if I did something wrong here.
I appreciate your help !

SyntaxError: Unexpected token, expected

Hello I get this error
/usr/local/lib/node_modules/html-to-react-components/node_modules/babylon/lib/index.js:4457
throw err;
With the following file (Note it is an HTML file just converted to .log for github purposes.

topbar.log

SyntaxError: Unexpected token, expected , (3:88)

Hi I try to use this tool at first time and get this error. What should i do for fixing it?

html2react ./zectStudioPages/index.html -o ./src/components                                                                                                                                                                                                   
/home/sherlock/.nvm/versions/node/v13.2.0/lib/node_modules/html-to-react-components/node_modules/babylon/lib/index.js:4633
    throw err;
    ^

SyntaxError: Unexpected token, expected , (3:88)
    at Parser.pp$5.raise (/home/sherlock/.nvm/versions/node/v13.2.0/lib/node_modules/html-to-react-components/node_modules/babylon/lib/index.js:4630:15)
    at Parser.pp.unexpected (/home/sherlock/.nvm/versions/node/v13.2.0/lib/node_modules/html-to-react-components/node_modules/babylon/lib/index.js:1911:10)
    at Parser.pp.expect (/home/sherlock/.nvm/versions/node/v13.2.0/lib/node_modules/html-to-react-components/node_modules/babylon/lib/index.js:1899:35)
    at Parser.pp$3.parseObj (/home/sherlock/.nvm/versions/node/v13.2.0/lib/node_modules/html-to-react-components/node_modules/babylon/lib/index.js:4148:18)
    at Parser.pp$3.parseExprAtom (/home/sherlock/.nvm/versions/node/v13.2.0/lib/node_modules/html-to-react-components/node_modules/babylon/lib/index.js:3885:29)
    at Parser.parseExprAtom (/home/sherlock/.nvm/versions/node/v13.2.0/lib/node_modules/html-to-react-components/node_modules/babylon/lib/index.js:7426:30)
    at Parser.pp$3.parseExprSubscripts (/home/sherlock/.nvm/versions/node/v13.2.0/lib/node_modules/html-to-react-components/node_modules/babylon/lib/index.js:3655:21)
    at Parser.pp$3.parseMaybeUnary (/home/sherlock/.nvm/versions/node/v13.2.0/lib/node_modules/html-to-react-components/node_modules/babylon/lib/index.js:3635:21)
    at Parser.pp$3.parseExprOps (/home/sherlock/.nvm/versions/node/v13.2.0/lib/node_modules/html-to-react-components/node_modules/babylon/lib/index.js:3565:21)
    at Parser.pp$3.parseMaybeConditional (/home/sherlock/.nvm/versions/node/v13.2.0/lib/node_modules/html-to-react-components/node_modules/babylon/lib/index.js:3542:21) {
  pos: 263,
  loc: Position { line: 3, column: 88 }
}

Suggestion: Support /dev/stdin and absolute paths

It would be useful to pipe HTML directly into this tool with something like:

curl $URL | pup 'body' | npx -p html-to-react-components html2react

or

curl $URL | pup 'body' | npx -p html-to-react-components html2react -

It would also be useful to support absolute paths like:

curl $URL | pup 'body' | npx -p html-to-react-components html2react /dev/stdin

or

curl $URL | pup 'body' > /tmp/file.html && npx -p html-to-react-components html2react /tmp/file.html

If there is support for this issue I will try to implement, unless the maintainer already has a method in mind.
I thought there might be some interface considerations since globbing is used.

Possible to decide data-components automatically?

First of all, kudos for creating this project! ❤️

When dealing with a huge template with multiple pages of HTML content with no annotated data-components attribute, would it be possible to automatically decide the components (like, split into very very granular level). I mean, I'd be happier being served LOTs of trivially-small components as the default functionality (ie, when no data-components is specified) rather than ending up with 0 components.

Am I missing something? Is this feature already existent?

Build Error: API Usage in browser build

Get a slew of errors when attempting to import the npm package.

Won't post the whole thing but the first line is:
ERROR in C:/nvm/v8.9.4/node_modules/html-to-react-components/node_modules/htmltojsx/src/htmltojsx.js

Installed the pkg globally as instructed.
Linked local node_modules to global installation.
ran npm run build -> lots of errors

Any guidance you can provide regarding usage of your pkg in js would be very welcome. Example code below ..

import html2reactjs from 'html-to-react-components'

htmlPage = 'html page content stuff here';

html2reactjs(
htmlPage, {
path: compFolder,
fileExtension: 'jsx'
}
);

Code on homepage

The Heading component is called Header too

// header.js
import React from 'react';
import Heading from './heading';

const Header = React.createClass({
  render() {
    return (
      <header className="header">
        <Heading></Heading>
      </header>
    );
  }
});

export default Header;

// heading.js
import React from 'react';

const Header = React.createClass({
  render() {
    return <h1 className="heading">Hello, world!</h1>;
  }
});

export default Heading;

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.