Skip to content

Commit

Permalink
Merge branch 'master' into fix-win32-jest
Browse files Browse the repository at this point in the history
  • Loading branch information
tipiirai authored Jan 15, 2024
2 parents 0789dce + c0df54a commit f109eeb
Show file tree
Hide file tree
Showing 11 changed files with 102 additions and 41 deletions.
38 changes: 35 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,38 @@ Please try to use the original style in the codebase. Do not introduce new rules
Nue is not using Prettier or ESLint because they will increase the project size to 40MB. The `.prettierrc.yaml` file on the root directory does the job well enough.





### Testing

```sh
# if using bun
bun install
bun install --no-save esbuild
bun test

# if using node
npm install
npm install --no-save jest jest-extended esbuild
node --experimental-vm-modules node_modules/jest/bin/jest --runInBand
```


### Linking

```sh
# if using bun
bun install
cd packages/nuekit
bun link
cd my/nue/project
nue
nue build --production

# if using node
npm install
cd packages/nuekit
npm link
cd my/nue/project
npm install --save-dev esbuild
node $(which nue)
node $(which nue) build --production
```
2 changes: 1 addition & 1 deletion packages/nuekit/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

<a href="https://nuejs.org">
<img src="https://nuejs.org/img/nue-banner-big.png">
<img src="https://nuejs.org/img/nue-banner-big.png?1">
</a>

# Nue &nbsp;[![test](https://github.com/nuejs/nue/actions/workflows/test.yaml/badge.svg?branch=master)](https://github.com/nuejs/nue/actions/workflows/test.yaml)
Expand Down
3 changes: 2 additions & 1 deletion packages/nuekit/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "nuekit",
"version": "0.2.0",
"version": "0.3.1",
"description": "The closer-to-standards web framework. Build sites and apps with less effort.",
"homepage": "https://nuejs.org",
"license": "MIT",
Expand All @@ -19,6 +19,7 @@
"dependencies": {
"diff-dom": "^5.0.6",
"es-main": "^1.3.0",
"import-meta-resolve": "^4.0.0",
"js-yaml": "^4.1.0",
"nuejs-core": "^0.3.0",
"nuemark": "^0.1.0"
Expand Down
1 change: 1 addition & 0 deletions packages/nuekit/src/browser/app-router.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@

// Router for single-page applications
import { onclick, loadPage, setSelected } from './page-router.js'

const is_browser = typeof window == 'object'
Expand Down
78 changes: 51 additions & 27 deletions packages/nuekit/src/browser/page-router.js
Original file line number Diff line number Diff line change
@@ -1,37 +1,48 @@

// MPA router

const is_browser = typeof window == 'object'
// Router for multi-page applications

export async function loadPage(path) {
dispatchEvent(new Event('before:route'))

// DOM of the new page
const dom = mkdom(await getHTML(path))

// title
// change title
document.title = $('title', dom)?.textContent

// main / body
const main = $('main')
const main2 = $('main', dom)

if (main && main2) {
main.replaceWith(main2)
} else {
$('body').innerHTML = $('body2', dom).innerHTML
$('body').classList = $('body2', dom).classList
}

// inline CSS
const new_styles = swapStyles($$('style'), $$('style', dom))
new_styles.forEach(style => $('head').appendChild(style))

// body class
$('body').classList = $('body2', dom).classList

// content
for (const query of ['header', 'main', 'footer']) {
const a = $('body >' + query)
const b = $('body2 >' + query, dom)

// update (if changed)
if (a && b) {
if (a.outerHTML != b.outerHTML) a.replaceWith(b)

// remove
} else if (a) {
a.remove()

// add
} else {
const fn = query == 'footer' ? 'append' : 'prepend'
document.body[fn](b)
}
}

// stylesheets
// external CSS
const paths = swapStyles($$('link'), $$('link', dom))

loadCSS(paths, () => {
scrollTo(0, 0)
setSelected(path)
dispatchEvent(new Event('route'))
})
}
Expand Down Expand Up @@ -64,24 +75,37 @@ export function onclick(root, fn) {
})
}

// TODO: switch to aria-selected
export function setSelected(path, className='selected') {
const el = $(`[href="${path}"]`)

// remove old selections
$$('.' + className).forEach(el => el.classList.remove(className))
el?.classList.add(className)

// add new ones
$$(`[href="${path}"]`).forEach(el => el.classList.add(className))
}


// Fix: window.onpopstate, event.state == null?
// https://stackoverflow.com/questions/11092736/window-onpopstate-event-state-null
is_browser && history.pushState({ path: location.pathname }, 0)
// browser environment
const is_browser = typeof window == 'object'

if (is_browser) {

// Fix: window.onpopstate, event.state == null?
// https://stackoverflow.com/questions/11092736/window-onpopstate-event-state-null
history.pushState({ path: location.pathname }, 0)

// autoroute / document clicks
onclick(document, async path => {
await loadPage(path)
history.pushState({ path }, 0, path)
})

// initial selected
setSelected(location.pathname)
}


// autoroute / document clicks
is_browser && onclick(document, (path) => {
loadPage(path)
history.pushState({ path }, 0, path)
setSelected(path)
})


/* -------- utilities ---------- */
Expand Down
3 changes: 2 additions & 1 deletion packages/nuekit/src/builder.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@
/* Builders for CSS, JS, and TS */

import { join, extname } from 'node:path'
import { resolve } from 'import-meta-resolve'

export async function getBuilder(is_esbuild) {
try {
return is_esbuild ? await import('esbuild') : Bun
return is_esbuild ? await import(await resolve('esbuild', `file://${process.cwd()}/`)) : Bun
} catch {
throw 'Bundler not found. Please use Bun or install esbuild'
}
Expand Down
1 change: 1 addition & 0 deletions packages/nuekit/src/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export function getArgs(argv) {
else if (['-h', '--help'].includes(arg)) args.help = true
else if (['-v', '--verbose'].includes(arg)) args.verbose = true
else if (['-s', '--stats'].includes(arg)) args.stats = true
else if (['-b', '--esbuild'].includes(arg)) args.esbuild = true

// string values
else if (['-e', '--environment'].includes(arg)) opt = 'env'
Expand Down
2 changes: 1 addition & 1 deletion packages/nuekit/src/init.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export async function init({ dist, is_dev, esbuild }) {


// has all latest?
const latest = join(outdir, '.020')
const latest = join(outdir, '.031')
try {
return await fs.stat(latest)

Expand Down
11 changes: 6 additions & 5 deletions packages/nuekit/src/nuekit.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const DOCTYPE = '<!doctype html>\n\n'
const NOT_FOUND = -2

export async function createKit(args) {
const { root, is_prod, env } = args
const { root, is_prod, esbuild } = args

// site: various file based functions
const site = await createSite(args)
Expand All @@ -28,7 +28,7 @@ export async function createKit(args) {
const is_dev = !is_prod

// make sure @nue dir has all the latest
if (!args.dryrun) await init({ dist, is_dev })
if (!args.dryrun) await init({ dist, is_dev, esbuild })



Expand Down Expand Up @@ -61,7 +61,7 @@ export async function createKit(args) {
async function setupScripts(dir, data) {

// components
if (!data.no_automount) data.components = await site.getAssets(dir, ['nue'], 'js')
if (data.automount !== false) data.components = await site.getAssets(dir, ['nue'], 'js')

// scripts
const scripts = data.scripts = await site.getScripts(dir, data.include)
Expand All @@ -72,8 +72,8 @@ export async function createKit(args) {
}

// system scripts
if (!data.is_spa && data.page_router) push('page-router')
if (is_dev && !data.no_hotreload) push('hotreload')
if (!data.is_spa && data.router) push('page-router')
if (is_dev && data.hotreload !== false) push('hotreload')
if (data.page?.isomorphic) push('nuemark')
if (data.components?.length) push('mount')
}
Expand Down Expand Up @@ -186,6 +186,7 @@ export async function createKit(args) {
await buildJS({
outdir: join(process.cwd(), dist, file.dir),
path: join(process.cwd(), root, path),
esbuild,
minify: is_prod,
bundle
})
Expand Down
2 changes: 1 addition & 1 deletion packages/nuekit/test/nuekit.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ test('page data', async () => {

test('page scripts', async() => {
const kit = await getKit()
await write('scripts/app.yaml', 'include: [hello.js]\nno_hotreload: true')
await write('scripts/app.yaml', 'include: [hello.js]\nhotreload: false')
await write('scripts/index.md', '# Hey')
await write('scripts/hello.nue', '<div/>')
await write('scripts/hello.ts', 'var a')
Expand Down
2 changes: 1 addition & 1 deletion packages/nuemark/src/render.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ const renderer = {
const rich = parseHeading(html)

delete plain.text
const a = elem('a', { href: `#${plain.id}`, title: `Permlink for '${title}'` })
const a = elem('a', { href: `#${plain.id}`, title: title })
return elem(`h${level}`, plain, a + rich.text)
},

Expand Down

0 comments on commit f109eeb

Please sign in to comment.