
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
passing-notes-ui
Advanced tools
A middleware for delivering code to the browser during development
It leverages native support for ES modules to avoid the overhead in writing large bundles. npm packages are compiled to separate, standalone ESM files and cached by the browser. Application code is built and bundled incrementally.
It uses esbuild under the hood and has limited support for non-standard JavaScript features.
Install passing-notes-ui by running:
yarn add passing-notes-ui
Given a directory (say, ./ui) containing HTML, CSS, and JS files, we provide
several ways to serve them over HTTP.
To quickly start a server that does nothing aside from serving those files:
yarn serve-ui ./ui
To add this functionality as a middleware to an existing app:
import {compose, Logger} from 'passing-notes'
import serveUi from 'passing-notes-ui'
const logger = new Logger()
export default compose(
serveUi({path: './ui', logger}),
() => () => ({status: 404})
)
serveUi will compile any JavaScript (.js) files requested by the browser,
bundling project source code into a single file. Any npm packages imported via
bare specifiers (e.g. 'react') are externalized and bundled separately and
ultimately imported via HTTP:
import React from '/npm/react'
JavaScript, CSS, and other files from npm packages can be requested directly via URL:
<link href="/npm/the-new-css-reset/css/reset.css" rel="stylesheet">
Currently, serveUi compiles as needed on each request. In the future, it may
instead compile only when files change.
Optionally, "virtual files" can be specified.
import {compose, Logger} from 'passing-notes'
import serveUi from 'passing-notes-ui'
const logger = new Logger()
export default compose(
serveUi({
logger,
path: './ui',
files: {
'index.html': `
<!doctype html>
<script type="module" src="/index.js"></script>
`,
'index.js': `
import text from './text.js'
document.body.textContent = text
`
}
}),
() => () => ({status: 404})
)
These virtual files are compiled and served as if they were written directly to the file system at the given paths.
Code splitting is accomplished by having the browser import from different entry points. A bundle is created for each entry point.
If both bundles end up importing the same file, the code in that file is duplicated into both bundles.
To prevent such duplication, "boundaries" can be defined. Bundles will never include files that cross a boundary, leaving them to be imported via HTTP at runtime.
Here's an intended example use case:
import {compose, Logger} from 'passing-notes'
import serveUi from 'passing-notes-ui'
const logger = new Logger()
export default compose(
serveUi({
path: './ui',
boundaries: ['./ui/lib/*'],
logger
}),
() => () => ({status: 404})
)
If the main entry point for the app is at ./ui/index.js and that file imports
./ui/lib/one/index.js and ./ui/lib/two/index.js, three bundles will be
created:
./ui/lib/one/index.js and any files it imports from
within ./ui/lib/one/./ui/lib/two/index.js and any files it imports from
within ./ui/lib/two/./ui/index.js and any files it imports that are outside
of ./ui/libNote that files within ./ui/lib/one/ should only import files from within
./ui/lib/one/. If they import files in outer directories, additional bundles
will be created.
These boundaries should correspond to actual boundaries within the codebase where imports that cross are strictly controlled.
Internally, caches and resources are setup to speed up compilation, which may
prevent the process from exiting, especially in automated test. There is a
teardown function that will clean up these caches and resources:
import test from 'ava'
import {compose, Logger, startServer, stopServer} from 'passing-notes'
import serveUi, {teardown} from 'passing-notes-ui'
test('serving a UI', async (t) => {
const logger = new Logger()
const server = await startServer(
{port: 10_000},
compose(
serveUi({
logger,
path: './ui',
files: {
'index.html': `
<!doctype html>
<script type="module" src="/index.js"></script>
`,
'index.js': `
document.body.textContent = 'Hello World!'
`
}
}),
() => () => ({status: 404})
)
)
t.teardown(async () => {
await stopServer(server)
await teardown('./ui')
})
t.pass()
})
teardown() can optionally take in a directory path, only removing resources
related to that directory and its descendents.
FAQs
A middleware for delivering code to the browser during development
The npm package passing-notes-ui receives a total of 131 weekly downloads. As such, passing-notes-ui popularity was classified as not popular.
We found that passing-notes-ui demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.