Comments (9)
@jaens could you give an example of when this happens?
The docs in rehype-react
show process
and processSync
https://github.com/rhysd/rehype-react#use
Using the process
methods may work better with TS typings.
I'm cautious about using stringify
to return a non-string or setting it's typescript type to non-string, as this seems to run counter to its intended use.
from unified.
.stringify
is indeed “supposed” to return a string. Or at least the “compiled” syntax tree. All the compilers that go to a virtual DOM (remark-vdom, remark-react, rehype-react, etc) benefit from the fact that it doesn’t have to be.
In fact, anything returned by compiler
(or Compiler#compile
) is returned by .stringify
.
When using .process
, that value is set on file.contents
, which typically would be string
or Buffer
, but can also be anything.
I'm cautious about using stringify to return a non-string or setting it's typescript type to non-string, as this seems to run counter to its intended use.
— ChristianMurphy
Yeah, I feel the same way.
from unified.
This is for a two-stage pipeline, so process
is not an option, I think.
The first stage runs the parser, extracts the metadata etc., and the second stage renders the result from the first stage into React (this is done in two stages because this is a multi-page renderer with interdependencies between pages).
The code is roughly:
// Stage 1 (vfile as input, node as output)
let processor = unified()
.use(remark_parse)
.use(remark_frontmatter, "yaml")
.use(frontMatterExtractor);
let node = await processor.run(await processor.parse(vfile), vfile);
// Stage 2 (node as input, vfile as input, React as output)
let processor = unified().use(rehype_react, {
createElement: React.h
});
return ((await processor.stringify(
node,
vfile
)) as any) as React.VNode;
from unified.
@jaens from the sample code above, process
should work fine
import * as React from "react";
import { render } from "react-dom";
import unified from "unified";
import remarkParse from "remark-parse";
import remarkFrontmatter from "remark-frontmatter";
import remarkReact from "remark-react";
const { contents } = unified()
.use(remarkParse)
.use(remarkFrontmatter)
.use(remarkReact)
.processSync("# hello from remark");
function App() {
return <>{contents}</>;
}
const rootElement = document.getElementById("root");
render(<App />, rootElement);
live demo: https://codesandbox.io/s/unified-react-typescript-process-wepo4
this is done in two stages because this is a multi-page renderer with interdependencies between pages
This sounds like something that could be done in a plugin, but it's hard to tell without an example of "interdependencies" is.
Is there a more complete example you could share in a CodeSandbox?
from unified.
The example you pasted above does not allow to inspecting all the vfiles/nodes between the parsing and rendering (as I said, process
is not an option I think).
First, to clarify, this is about rendering multiple documents at once (in a static site generator).
Let's say you have an "all pages" React component you can have in the Markdown (that renders the list of all the pages in the site).
To render that, you need the titles of all the pages.
So you do two stages:
- Parse all the Markdown pages and extract front matters (title).
- Render all the Markdown pages (so they can use the "all pages" component).
from unified.
Let's say you have an "all pages" React component you can have in the Markdown (that renders the list of all the pages in the site).
To render that, you need the titles of all the pages.
Another approach would be to copy the metadata into vfile.data
and rendering the "all pages" component outside of remark-react
.
E.G. https://codesandbox.io/s/unified-react-typescript-process-7hd51
Going back to
Not sure what's the best solution here.
- Specify the "stringed" type as a generic parameter somewhere?
This might be a possibility.
My caution here is that we could get into a different typing mismatch mess doing this, if the generics cannot be inferred from the Parser
and Compiler
classes.
For example
(processor.stringify(node, vfile) as unknown) as VNode;
is not all that different from
processor.stringify<VNode>(node, vfile);
In that the type that is being cast/genericized may conflict with the type the Compiler
is returning, and TypeScript would be none the wiser.
We'd need to look into feasible to make Parser
and Compiler
generic and have that bubble up from the plugins into unified
.
/cc @Rokt33r
- Make the return type any?
any
should be avoided in the typings, any
disables the type system for a variable/indentifier, which largely defeats the purpose of having types and typings.
from unified.
Yes, changing the architecture so it doesn't allow arbitrary/generic components in Markdown of course "solves" this problem, but for a generic static site generator it's not really workable (it's desirable to allow anything anywhere instead of forcing one-off hacks for eg. sitemap or category pages).
re: the "actual" typing, looks like this is probably a bit tricky, as the type of the Processor
can change depending on what .use()
you call on it - so looks like it would require adding generic type parameters to the Plugin
, Compiler
and Processor
types and somehow propagating all of that through .use()
...
from unified.
stringify<P = string>(node: Unist.Node, file?: VFileCompatible): P
Would be the best option I guess?
re: the "actual" typing, looks like this is probably a bit tricky, as the type of the Processor can change depending on what .use() you call on it - so looks like it would require adding generic type parameters to the Plugin, Compiler and Processor types and somehow propagating all of that through .use()...
It would be nice to have. But I'm afraid that the propagating should be quite difficult to implement and buggy.
from unified.
stringify<P = string>(node: Unist.Node, file?: VFileCompatible): P
@Rokt33r So that fixes this issue?
You’re suggesting to replace:
Line 59 in 4d96f98
with the above right?
It would be nice to have. But I'm afraid that the propagating should be quite difficult to implement and buggy.
Yeah
from unified.
Related Issues (20)
- Update vfile to 4.2.1 HOT 1
- Logo not readable on github dark mode HOT 1
- Next major for the ecosystem HOT 46
- Dependencies need to be ESM HOT 6
- 3rd overload signature of `FrozenProcessor.run` should accept `ParseTree` instead of `CompileTree` HOT 5
- this.use() doesn't respect plugin order when combined with unified().use() HOT 6
- Support async compilers HOT 31
- Rethink how `*-stringify` should work HOT 16
- Throw on preset w/ neither `settings` nor `plugins` HOT 1
- unify AST types HOT 1
- Support `Node` typeParam in `Pluggable` and `PluggableList` HOT 9
- Notion Block AST HOT 4
- Error: No overload matches this call after library update. HOT 5
- Type errors on new major version → 11.0.2 HOT 5
- TypeScript error when doing simple unified markdown pipeline HOT 3
- CallableInstance throws error in older ECMA 5 targets HOT 6
- examples of tools? HOT 4
- Make VFileContents generic to support processors that return objects HOT 3
- tsc reports incorrect / missing types HOT 14
- VFile types do not support property result HOT 6
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from unified.