Comments (2)
Documentation is indeed very laconic currently. It's both lagging behind the code and fails to explain some of the core concepts.
Here is a JSX working test case for building a custom Nuemark extension:
https://github.com/nuejs/nue/blob/master/packages/nuemark/test/nuemark.test.js#L430
That's all there is now with regards to extension. Hope that helps. The idea is to finish the core pieces first and launch a v1.0, before moving into extensions and integrations. Nue is still an early beta.
from nue.
Thank you very much for your response and advice @tipiirai!
At the beginning I would like to sorry for my late response and share my results so maybe it can help also other developers to understand better the problem and solution.
Zag integration results
Let's forget about Zag. I was able to implement working integration with a simple Number Input component by myself, but I was not happy with the code. One of the biggest reason is the lack of the spread properties feature available in JSX/TSX. I had to implement my own solution for that. Another reason is that this library has its own logic implementation for each component based on the state machines. This is another custom abstraction layer and the library itself is also very much tightly coupled to the React, Solid, Vue and heavily relies on the concepts from these frameworks.
Because the main reason of the Nue framework is to be closer to the web standards I decided to search something else and I found Shoelace which is a collection of UI components build on web components standard. Thanks to this the components implementation is fully framework agnostic. Library looks mature and I am going to test these components together with Nue and built SPA with forms. It should eliminate any need to create custom integrations and so on.
Custom JSX/TSX components
Coming back now to the original problem. I decided to investigate further the custom components problem inspired by the Custom components section and especially TSX components section. My main idea was to create custom TSX components and render them on the client side in the browser in my SPA. In my previous attempts, I didn't know how to properly import Nuemark API. The reason was that I didn't read carefully Unbundled distribution section which says:
The default is to build, but not bundle. That is: the imported dependencies are not inlined into the file itself to form a single, bigger JS bundle.
So I decided to bundle the Nuemark API. Unfortunately the Bundled distribution section was not quite clear for me. I couldn't understand how the bundle: [ index.ts ]
option works. Whenever I tried to import Nuemark API like this:
// *.nue file
import { nuemarkdown } from "nuemark";
nothing happened... After transpiling the project files, the import
statement remained unchanged. To understand what was going on, I had to debug Nue CLI code to realize that the *.nue
files are not processed by Bun.build()
at all. The are just compiled by your custom mechanism into *.js
files. Only the *.js
and *.ts
files are processed by Bun.build()
and the bundle
option inside *.yaml
config files is used to determine in which files from the project, import
statements should be inlined after transpilation process. It was eureka! After that I created index.ts
file in my SPA project root with the content:
// index.ts
export { nuemarkdown } from "nuemark";
The Nuemark API has been finally inlined into generated index.js
file. Victory! ✌
The next step was to create TSX components that I could render in my SPA. According to the TSX components section I added following dependencies to the project folder:
// run in terminal
bun add react
bun add react-dom
and created TSX components library:
// components.tsx
// import of the React SSR (server-side rendering)
import { renderToString } from "react-dom/server";
// first custom tag
function MyTag(props: { message: string }) {
return <h1 style={{ color: "red" }}>{props.message}</h1>;
}
// second custom tag
function MyTag2(props: { message: string }) {
return <h1 style={{ color: "blue" }}>{props.message}</h1>;
}
const components = { MyTag, MyTag2 };
// Make lib compatible with Nuemark
export const tsx_lib = Object.keys(components).map((name) => {
return {
name,
render: function (data, lib) {
return renderToString(components[name](data, lib));
},
};
});
After debugging your code I already knew that Nue CLI treats *.tsx
files as static and copies them as is to the .dist/dev
directory so I had to transpile the file manually with Bun:
bun build ./components.tsx --outdir ./.dist/dev
After that the components.js
file appeared with all React dependencies inlined in place and I could finally create custom Nue component that gives possibility to render custom TSX components in my SPA:
// tsx-component.nue
<script>
import { nuemarkdown } from './index.js'
import { tsx_lib } from './components.js'
</script>
<div @name="tsx-component">
<script>
mounted({ name, data }) {
const html = nuemarkdown(`[${name}]`, {
data,
lib: tsx_lib,
});
/**
* The this.mountChild() method unfortunately is not documented enough
* so I had to use this ugly solution:
*/
this.$el.innerHTML = html
}
</script>
</div>
All I had to do was consume my amazing custom Nue component in SPA:
// home-view.nue
<section @name="home-view">
<script>
tag = { message: "My first custom tag!" }
tag2 = { message: "My second custom tag!" }
</script>
<h1>Hello, World!</h1>
<tsx-component name="my-tag" :data="tag" />
<tsx-component name="my-tag2" :data="tag2" />
</section>
The results are visible on the screenshot 🎉
Conclusions
I am sorry for such a long answer, but I wanted to share my solution with you @tipiirai and other developers. It might help to shed some light on the problems I faced during implementation of the custom JSX/TSX components and possible solutions. This PoC opens possibility to implement integrations with different frameworks, however I have no idea if your intention was to use Nuemark API in a such way on the client-side components. I have the impression that you prepared this API for server-side components, despite the fact that there is no mention of them in the documentation.
I am fully aware of that the idea is to finish the core pieces first and launch a v1.0, before moving into extensions and integrations, but just wanted to check if I implemented custom TSX components as intended or maybe you had different vision behind it.
Regards
from nue.
Related Issues (20)
- Update CLI help message to represent current options HOT 1
- Syntax error HOT 1
- Pending when creating projects with bun under Windows HOT 15
- The path of the route is expected to support regular expressions HOT 1
- component at layout.html compile error HOT 3
- When '{}' or',' in html , How to escape? HOT 1
- It can not start the server with nuekit 0.5.3, but works with nue 0.4.3 HOT 6
- auto generate manifest.json file
- a bug in the nuecli root HOT 5
- unmounted() Why is it not executed?
- Reactive values are not updated? why? HOT 3
- Page router doesn't mount components. Refresh needed to properly mount. HOT 2
- "draw_sections: true" results in nested sections HOT 5
- When iterating collections: can we render the markdown content of an item? HOT 5
- three-tiered directory structure layout HOT 1
- Add default`text` property to default `data` object available to page layouts.
- SPA demo not working when deploy on subpath of domain
- Nuemark: How to add svg inside a button HOT 2
- New website shaping up 🎉 HOT 4
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 nue.