Socket
Socket
Sign inDemoInstall

nuejs-core

Package Overview
Dependencies
Maintainers
0
Versions
12
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

nuejs-core - npm Package Compare versions

Comparing version 0.4.0 to 0.5.0

57

package.json
{
"name": "nuejs-core",
"version": "0.4.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"
"name": "nuejs-core",
"version": "0.5.0",
"description": "HTML microlibrary for UX developers",
"homepage": "https://nuejs.org",
"license": "MIT",
"type": "module",
"main": "index.js",
"repository": {
"url": "https://github.com/nuejs/nue",
"directory": "packages/nuejs",
"type": "git"
},
"license": "MIT",
"type": "module",
"scripts": {
"test": "cd test && bun test",
"compile": "cd test && bun compile.js"
},
"main": "index.js",
"dependencies": {
"htmlparser2": "^9.0.0"
},
"engines": {
"bun": ">= 1",
"node": ">= 18"
}
"engines": {
"bun": ">= 1",
"node": ">= 18"
},
"scripts": {
"test": "node --experimental-vm-modules ../../node_modules/jest/bin/jest.js --runInBand",
"compile": "cd test && bun compile.js"
},
"dependencies": {
"htmlparser2": "^9.1.0"
},
"jest": {
"setupFilesAfterEnv": [
"jest-extended/all",
"<rootDir>/../../setup-jest.js"
]
}
}
<a href="https://nuejs.org">
<img src="https://nuejs.org/img/nuejs-banner-big.png">
</a>
# Nue JS
Nue JS is a tiny (2.3kb minzipped) JavaScript library for building web interfaces. It is the layout engine for [Nue web framework](https://nuejs.org) providing both server-side templating and client-side reactive islands.
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.
## HTML microlibrary for UX developers
Nue template syntax is designed for [UX developers](https://nuejs.org/docs/) who prefer to write user interfaces with clean, semantic HTML instead of JavaScript. Think Nue as standard HTML, that you can extend with custom HTML-based components. These components help you build modern web applications in a simple, declarative way. For example:
## "It's just HTML"
Nue uses a simple HTML-based template syntax that you can use for both server-side layouts and reactive, client-side components. For example:
``` html
```html
<div class="{ type }">

@@ -25,52 +22,10 @@ <img src="{ img }">

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.
If React is "Just JavaScript", then Nue is "Just HTML" because any valid HTML is also valid Nue.
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.
### Links
* [Template syntax](https://nuejs.org/docs/template-syntax.html)
* [Reactive components](https://nuejs.org/docs/reactive-components.html)
## 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_:
``` html
<form @submit.prevent="submit">
<input type="email" name="email" placeholder="your@address.com" required>
<button>Submit</button>
<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>
</form>
```
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.
Learn the reasoning behind HTML- and class based syntax from our Blog article: [rethinking reactivity](https://nuejs.org/blog/rethinking-reactivity/)
### Getting Started
Please see https://nuejs.org/docs/
### The big picture
The ultimate goal of Nue is to build a content first alternative to **Vercel** and **Netlify**, which is extremely fast and ridiculously easy to use.
![Nue Roadmap](https://nuejs.org/img/roadmap4-big.png)
#### Why Nue?
- [Content first](https://nuejs.org/docs/why-nue/content-first.html)
- [Extreme performance](https://nuejs.org/docs/why-nue/extreme-performance.html)
- [Closer to standards](https://nuejs.org/docs/why-nue/closer-to-standards.html)
### Contributing

@@ -77,0 +32,0 @@

@@ -252,5 +252,4 @@

// constructor
if (Impl) {
impl = self.impl = new Impl(ctx)
if (Impl) impl = self.impl = new Impl(ctx)
// for

@@ -260,4 +259,3 @@ impl.mountChild = self.mountChild

impl.update = update
}
walk(root)

@@ -277,3 +275,3 @@

append(to) {
const wrap = document.createElement('b')
const wrap = document.createElement('_')
to.append(wrap)

@@ -330,3 +328,7 @@ return self.mount(wrap)

} else {
self[key] = val
if (Object.prototype.hasOwnProperty.call(impl, key)) {
impl[key] = val
} else {
self[key] = val
}
}

@@ -333,0 +335,0 @@ return true

@@ -124,2 +124,3 @@

space: [' ', 'spacebar', 'space bar'],
tab: ['tab'],
up: ['arrowup'],

@@ -202,2 +203,3 @@ down: ['arrowdown'],

export function parse(src) {
src = src.replace(/\r\n|\r/g, '\n')
const { children } = mkdom(src)

@@ -204,0 +206,0 @@

@@ -16,9 +16,9 @@

const SVG = 'animate animateMotion animateTransform circle clipPath defs desc ellipse\
feBlend feColorMatrix feComponentTransfer feComposite feConvolveMatrix feDiffuseLighting\
feDisplacementMap feDistantLight feDropShadow feFlood feFuncA feFuncB feFuncG feFuncR\
feGaussianBlur feImage feMerge feMergeNode feMorphology feOffset fePointLight feSpecularLighting\
feSpotLight feTile feTurbulence filter foreignObject g hatch hatchpath image line linearGradient\
marker mask metadata mpath path pattern polygon polyline radialGradient rect set stop style svg\
switch symbol text textPath title tspan use view'.split(' ')
const SVG = 'animate animatemotion animatetransform circle clippath defs desc ellipse\
feblend fecolormatrix fecomponenttransfer fecomposite feconvolvematrix fediffuselighting\
fedisplacementmap fedistantlight fedropshadow feflood fefunca fefuncb fefuncg fefuncr\
fegaussianblur feimage femerge femergenode femorphology feoffset fepointlight fespecularlighting\
fespotlight fetile feturbulence filter foreignobject g hatch hatchpath image line lineargradient\
marker mask metadata mpath path pattern polygon polyline radialgradient rect set stop style svg\
switch symbol text textpath title tspan use view'.split(' ')

@@ -37,3 +37,3 @@ STD.push(...SVG)

const { attribs } = root
const name = attribs['@name'] || attribs['data-name'] || attribs.id
const name = attribs['@name'] || attribs['data-name'] // || attribs.id
delete attribs['@name']

@@ -40,0 +40,0 @@ return name

@@ -59,3 +59,3 @@

let val = attribs[key]
if (!val) return
if (val === null || val === undefined) return

@@ -173,6 +173,7 @@ // TODO: check all non-strings here

let child = comp.create({ ...data, ...attribs }, deps, node.children) || ''
if (typeof child == 'string') child = parseDocument(child)
// merge attributes
const child = comp.create({ ...data, ...attribs }, deps, node.children)
if (child.children.length == 1) mergeAttribs(child.firstChild.attribs, attribs)
DOM.replaceElement(node, child)

@@ -245,3 +246,3 @@ }

if (attribs.for) {
const html = data[attribs.for]
const html = exec(setContext(attribs.for), data)
if (html) DOM.replaceElement(node, mkdom(html))

@@ -302,2 +303,4 @@ else removeNode(node)

const Impl = js[0] && exec(`class Impl { ${ js } }\n${global_js}`)
// must be after getJS()
const tmpl = getOuterHTML(node)

@@ -356,2 +359,3 @@

export function parse(template) {
template = template.replace(/\r\n|\r/g, '\n')
const { children } = mkdom(template)

@@ -383,3 +387,1 @@ const nodes = children.filter(el => el.type == 'tag')

}

@@ -104,10 +104,10 @@

'<p :for="({ name }, i) in items">{ i }. { name }</p>' : '<p>0. John</p><p>1. Alice</p>',
'<p :for="({ name }, i) in items">{ i }. { name }</p>': '<p>0. John</p><p>1. Alice</p>',
// loop custom tag
'<show :for="el in items" :value="el.name"/> <b @name="show">{ value }</b>' :
'<show :for="el in items" :value="el.name"/> <b @name="show">{ value }</b>':
'<b>John</b><b>Alice</b>',
// loop slots
'<thing :for="el in items" :bind="el"><b>{ el.age }</b></thing><u @name="thing">{name}: <slot/></u>' :
'<thing :for="el in items" :bind="el"><b>{ el.age }</b></thing><u @name="thing">{name}: <slot/></u>':
'<u>John: <b>22</b></u><u>Alice: <b>33</b></u>',

@@ -119,6 +119,8 @@

'<i :for="el in falsy">{el}</i>': '<i></i><i>false</i><i>0</i><i>NaN</i><i></i><i></i>'
}, {
items: [ { name: 'John', age: 22 }, { name: 'Alice', age: 33 }],
items: [{ name: 'John', age: 22 }, { name: 'Alice', age: 33 }],
person: { name: 'Nick', email: 'nick@acme.org', age: 10 },
nums: [-1, 0, 1],
falsy: ['', false, 0, NaN, null, undefined],
})

@@ -149,3 +151,3 @@ })

// :attr (:bind works the same on server side)
'<dd :attr="person"></dd>': '<dd name="Nick" age="10"></dd>',
'<dd :attr="person"></dd>': '<dd name="Nick" age="0"></dd>',

@@ -162,6 +164,6 @@ '<hey :val/>': '<div is="hey">\n <script type="application/json">{"val":"1"}</script>\n</div>',

}, {
person: { name: 'Nick', age: 10 },
person: { name: 'Nick', age: 0 },
page: '<main>Hello</main>',
nums: [1, 2],
val: 1
val: 1,
})

@@ -172,7 +174,12 @@

const GLOBAL_SCRIPT = `
const GLOBAL_FUNCTIONS = `
<script>
// only functions are allowed globally. so no variables or import statements ATM
function toLower(str) {
return str.toLowerCase()
}
function getArray() {
return [1, 2, 3]
}
</script>

@@ -183,3 +190,9 @@

<p :for="num in iterator()">* { num }</p>
<script>
iterator() {
return getArray()
}
lower(str) {

@@ -192,7 +205,11 @@ return toLower(str)

test('Global script', () => {
const html = render(GLOBAL_SCRIPT, { title: 'Hey' })
const html = render(GLOBAL_FUNCTIONS, { title: 'Hey' })
expect(html).toStartWith('<div>')
expect(html).toInclude('hey')
expect(html).toInclude('<p>* 1</p><p>* 2</p>')
})
const GA = `

@@ -227,3 +244,3 @@ <body>

test('If sibling', () => {
const els = [{ label: 'First'}]
const els = [{ label: 'First' }]
const html = render(IF_SIBLING, { els })

@@ -230,0 +247,0 @@ expect(html).toInclude('First')

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc