nuejs-core
Advanced tools
Comparing version 0.1.2 to 0.2.0
{ | ||
"name": "nuejs-core", | ||
"version": "0.2.0", | ||
"description": "The Nue framework for building user interfaces", | ||
"homepage": "https://nuejs.org", | ||
"repository": { | ||
"url": "https://github.com/nuejs/nue", | ||
"directory": "packages/nuejs", | ||
"type": "git" | ||
}, | ||
"license": "MIT", | ||
"type": "module", | ||
"name": "nuejs-core", | ||
"main": "ssr/index.js", | ||
"version": "0.1.2", | ||
"main": "index.js", | ||
"scripts": { | ||
"test": "cd test && bun test", | ||
"minify": "bun scripts/minify.js", | ||
"compile": "cd test && bun compile.js" | ||
@@ -15,4 +27,5 @@ }, | ||
"engines": { | ||
"bun": ">= 1" | ||
"bun": ">= 1", | ||
"node": ">= 18" | ||
} | ||
} |
112
README.md
<a href="https://nuejs.org"><img src="https://nuejs.org/logo.svg" width="80"></a> | ||
<a href="https://nuejs.org"> | ||
<img src="https://nuejs.org/global/logo/logo.png" width="275" alt="Nue logo"> | ||
</a> | ||
# Nue JS | ||
[Documentation](//nuejs.org/docs/nuejs/) • | ||
[Examples](//nuejs.org/docs/nuejs/examples/) • | ||
[Getting started](//nuejs.org/docs/nuejs/getting-started.html) | ||
[Rethinking reactivity](//nuejs.org/blog/blog/rethinking-reactivity/) • | ||
Nue JS is a tiny (2.3kb minzipped) JavaScript library for building web interfaces. It is the core layout engine in [Nue](https://nuejs.org) providing both server-side templating and client-side reactive islands. | ||
# What is Nue JS? | ||
Nue JS is an exceptionally small (2.3kb minzipped) JavaScript library for building web interfaces. It is the core of the upcoming [Nue toolset](//nuejs.org/tools/). It’s like **Vue.js, React.js**, or **Svelte** but there are no hooks, effects, props, portals, watchers, provides, injects, suspension, or other unusual abstractions on your way. Learn the basics of HTML, CSS, and JavaScript and you are good to go. | ||
## Build user interfaces with cleaner code | ||
With Nue your UI code is cleaner and usually smaller: | ||
![The difference in coding style](https://nuejs.org/docs/img/react-listbox.jpg?1) | ||
It's not unusual to see [2x-10x differences](//nuejs.org/compare/component.html) in the amount of code you need to write. | ||
## "It's just HTML" | ||
Nue uses an HTML-based template syntax: | ||
Nue uses a simple HTML-based template syntax that you can use for both server-side layouts and reactive, client-side components. For example: | ||
@@ -40,86 +23,35 @@ ``` html | ||
While React and JSX claim to be "Just JavaScript", Nue can be thought of as "Just HTML". Nue is perfect for [UX developers][divide] focusing on interaction design, accessibility, and user experience. | ||
If React is __"just JavaScript"__, then Nue is __"just HTML"__ because any valid HTML is also valid Nue. You can extend the standard HTML with [template expressions](https://nuejs.org/docs/reference/template-syntax.html) that help you build modern websites and web- applications in a simple, declarative way. | ||
Nue is best suited for *UX developers* dealing with the [front of the frontend](https://bradfrost.com/blog/post/front-of-the-front-end-and-back-of-the-front-end-web-development/) and with topics like interaction design, accessibility, and user experience. | ||
## Built to scale | ||
Three reasons why Nue scales extremely well: | ||
1. [Minimalism](//nuejs.org/why/#minimalism), a hundred lines of code is easier to scale than a thousand lines of code | ||
## Class- based | ||
Nue uses ES6 classes to make web development feel more natural and standards-based. Here is an example Nue- component with a `submit()` _instance method_: | ||
1. [Separation of concerns](//nuejs.org//why/#soc), easy-to-understand code is easier to scale than "spaghetti code" | ||
1. **Separation of talent**, when UX developers focus on the [front of the frontend][back] and JS/TS developers focus on the back of the frontend your team skills are optimally aligned: | ||
![The best results are gained when UX developers and JavaScript developers work together without overlaps](https://nuejs.org/docs/img/ux-developer-big.png) | ||
## Reactive, hybrid, and isomorphic | ||
Nue has a rich component model and it allows you to create all kinds of applications using different kinds of components: | ||
1. [Server components](//nuejs.org/docs/nuejs/server-components.html) are rendered on the server. They help you build content-focused websites that load faster without JavaScript and are crawled by search engines. | ||
2. [Reactive components](//nuejs.org/docs/nuejs/reactive-components.html) are rendered on the client. They help you build dynamic islands or single-page applications. | ||
3. [Hybrid components](//nuejs.org/docs/nuejs/isomorphic-components.html#hybrid) are partly rendered on the server side, and partly on the client side. These components help you build reactive, SEO-friendly components like video tags or image galleries. | ||
3. [Universal components](//nuejs.org/docs/nuejs/isomorphic-components.html) are used identically on both server- and client side. | ||
## UI library files | ||
Nue allows you to define multiple components on a single file. This is a great way to group related components together and simplify dependency management. | ||
``` html | ||
<!-- shared variables and methods --> | ||
<script> | ||
import { someMethod } from './util.js' | ||
</script> | ||
<form @submit.prevent="submit"> | ||
<input type="email" name="email" placeholder="your@address.com" required> | ||
<button>Submit</button> | ||
<!-- first component --> | ||
<article @name="todo"> | ||
... | ||
</article> | ||
<script> | ||
// input validation is natively taken care of by the browser | ||
async submit({ target }) { | ||
await fetch(`/api/leads?email=${target.email.value}`) | ||
location.href = '/thank-you' | ||
} | ||
</script> | ||
<!-- second component --> | ||
<div @name="todo-item"> | ||
... | ||
</div> | ||
<!-- third component --> | ||
<time @name="cute-date"> | ||
... | ||
</time> | ||
</form> | ||
``` | ||
With library files, your filesystem hierarchy looks cleaner and you need less boilerplate code to tie connected pieces together. They help in packaging libraries for others. | ||
The most notable thing is the `<script>` tag, which is now nested _inside_ the component. This is the place for your ES6 class variables and methods. | ||
ES6 classes make your code look amazingly compact and clean. You can add variables, methods, [getters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get), [setters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/set), and `async` methods with the cute and short syntax. There are no hooks, effects, props, portals, watchers, provides, injects, suspension, or other unusual abstractions on your way. Learn the basics of HTML, CSS, and JavaScript and you are good to go. | ||
## Simpler tooling | ||
Nue JS comes with a simple `render` function for server-side rendering and a `compile` function to generate components for the browser. There is no need for toolchains like Webpack or Vite to hijack your natural workflow. Just import Nue to your project and you are good to go. | ||
Learn the reasoning behind HTML- and class based syntax from our Blog article: [rethinking reactivity](https://nuejs.org/blog/rethinking-reactivity/) | ||
You can of course use a bundler on the business model if your application becomes more complex with tons of dependencies. [Bun](//bun.sh) and [esbuild](//esbuild.github.io/) are great options. | ||
## Use cases | ||
Nue JS is a versatile tool that supports both server- and client-side rendering and helps you build both content-focused websites and reactive single-page applications. | ||
1. **UI library development** Create reusable components for reactive frontends or server-generated content. | ||
2. **Progressive enhancement** Nue JS is a perfect micro library to enhance your content-focused website with dynamic components or "islands" | ||
3. **Static website generators** Just import it into your project and you are ready to render. No bundlers are needed. | ||
4. **Single-page applications** Build simpler and more scalable apps together with an upcoming *Nue MVC*- project. | ||
5. **Templating** Nue is a generic tool to generate your websites and HTML emails. | ||
[fourteen]: https://developer.mozilla.org/en-US/docs/Web/Performance/How_browsers_work#tcp_slow_start_14kb_rule | ||
[divide]: https://css-tricks.com/the-great-divide/ | ||
[back]: https://bradfrost.com/blog/post/front-of-the-front-end-and-back-of-the-front-end-web-development/ | ||
import { compile, compileFile } from '../ssr/compile.js' | ||
import { compile } from '..' | ||
/* | ||
@@ -87,2 +86,13 @@ Format of individual tests on the TESTS array: | ||
test(':for error', () => { | ||
try { | ||
compile('<h1>Hey</h1>\n<b :for="foo bar"></b>') | ||
} catch (e) { | ||
expect(e.expr).toBe('foo bar') | ||
expect(e.column).toBe(9) | ||
expect(e.line).toBe(2) | ||
} | ||
}) | ||
// good for testing a single thing with test.only() | ||
@@ -89,0 +99,0 @@ test('Unit test', () => { |
import { parseFor, parseClass, setContext, setContextTo, parseExpr } from '../ssr/expr.js' | ||
import { parseFor, parseClass, setContext, setContextTo, parseExpr } from '../src/expr.js' | ||
@@ -4,0 +4,0 @@ |
import { parse, render } from '../ssr/render.js' | ||
import { render } from '..' | ||
@@ -52,3 +52,7 @@ | ||
runTests({ | ||
'<div><b :if="am > 100">No</b><p>Yes</p></div>': '<div><p>Yes</p></div>', | ||
'<b :if="flag">{ val }</b>': '', | ||
'<html><style :if="nope">{ nope }</style></html>': '<html></html>', | ||
'<html><style :if="css">{ css }</style></html>': '<html><style>body { font-family: 100; }</style></html>', | ||
'<div><b :if="am > 100">No</b><p><a href="#{val}">Yes</a></p></div>': '<div><p><a href="#A">Yes</a></p></div>', | ||
'<div><b :if="am > 100">No</b><p :else><a href="#{val}">Yes</a></p></div>': '<div><p><a href="#A">Yes</a></p></div>', | ||
'<a><em :if="flag"></em><b :else>{ val }</b></a>': '<a><b>A</b></a>', | ||
@@ -59,4 +63,5 @@ '<div><b :if="am > 100">No</b><b :else-if="am == 100">Yes</b><b :else>No</b></div>': '<div><b>Yes</b></div>', | ||
}, { | ||
css: 'body { font-family: 100; }', | ||
am: 100, | ||
val: 'A' | ||
val: 'A', | ||
}) | ||
@@ -83,3 +88,3 @@ }) | ||
color: '#ccc', | ||
thing: 'thing' | ||
thing: 'thing', | ||
}) | ||
@@ -136,3 +141,3 @@ }) | ||
// return debug('<html><slot for="page"/></html>', { page: '<main>Hello</main>' }) | ||
// return debug('', { val: 1 }) | ||
@@ -150,2 +155,3 @@ runTests({ | ||
'<html><slot for="none"/><b>{ val }</b></html>': '<html><b>1</b></html>', | ||
'<html><slot for="page"/></html>': '<html><main>Hello</main></html>', | ||
@@ -163,2 +169,3 @@ | ||
}) | ||
}) | ||
@@ -203,1 +210,24 @@ | ||
test(':for error', () => { | ||
try { | ||
render('<div>\n<h1>Hey</h1>\n<b :for="foo bar"></b></div>') | ||
} catch (e) { | ||
expect(e.lineText).toInclude(':for="foo bar"') | ||
expect(e.column).toBeGreaterThan(1) | ||
expect(e.line).toBe(3) | ||
} | ||
}) | ||
test('{ expr } error', () => { | ||
try { | ||
render('<div>\n<b>Hey { foo[0] } { title }</b></div>') | ||
} catch (e) { | ||
expect(e.subexpr).toBe('foo[0]') | ||
expect(e.line).toBe(2) | ||
expect(e.column).toBe(9) | ||
} | ||
}) | ||
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
No website
QualityPackage does not have a website.
Found 1 instance in 1 package
1526
1
0
79874
24
57
2