als-view v0.5.0
als-view
⚠ Warning: Beta Testing Stage
This library is currently in beta testing and is not yet recommended for use in production environments. While it offers a powerful framework for dynamic server-side rendering, active development and testing are ongoing, and certain features or behaviors may be subject to change.
Introduction
als-view is a powerful yet straightforward Node.js library designed to simplify the server-side rendering of dynamic web pages with integrated, on-the-fly component rendering. Built to meet the needs of modern applications, als-view allows developers to create robust, SEO-friendly pages that render JSX-like components dynamically — no React and pre-build required.
By leveraging two core tools, als-layout and als-render, this library enables a fluid and high-performance approach to web page generation:
SEO Optimization and Content Management: Using
als-layout,als-viewprovides a DOM-like structure with rapid configuration of SEO elements, scripts, styles, and other dynamic content. This allows you to fully manage page content with flexible, server-side tools.Dynamic Component Rendering: The integration with
als-renderletsals-viewrender React-like components on the server and in the browser without any build step. JSX-like components work directly on the server and can be executed in the browser as well, bridging server and client seamlessly.
Key Advantages
- Simplified Dynamic Page Creation:
als-viewcombines the ease of creating SEO-optimized dynamic pages with JSX-like component rendering. - Unified Rendering for Server and Client: Components are rendered on demand and can function in both server and browser environments without requiring a separate build process.
- Production-Optimized Caching: In Production mode,
als-viewautomatically writes component bundles to static files, allowing browsers to cache scripts efficiently for optimal performance.
Whether you’re building a full-fledged server-side rendered application or need a lightweight solution for server-rendered pages with reusable components, als-view offers the flexibility and performance to meet your needs.
Chang log
- updated als-render library to new version
- no context.routes and context.publics
- langs now extends parent's langs
instance.optionsafter usingrendermethod- inheritance for render options from parent
- if not rendered,
instance.renderedreturn null (may cause errors)
Installation
Requirements
- Node.js version 14 or higher
Install als-view
To get started with als-view, use npm to install the package:
npm install als-viewUsage
Setup Environment
Before creating views, you need to configure the environment and global layout settings:
const View = require("als-view");
// Set global environment
View.env = {
host: "https://example.com",
minified: true,
bundleAsRoute: false,
jsx: true,
bundleName: "main-bundle",
cyclicDependencies: false,
logger: console,
};
// Configure global layout
View.layout
.viewport()
.title("Default Title")
.description("Default Description")
.favicon("/path/to/favicon.ico")
.link("/styles/main.css");
View.context = { appName: "Cool app" };
View.browserContext = { appName: "Cool app" };Creating Views
You can create views based on the global layout or extend existing views.
Basic Example
const view = new View("main");
// Render a component
view.render("./components/Home", {
cyclicDependencies: false,
version: "1.0",
langs: {
langs: ["en", "es"],
dictionary: { welcome: ["Welcome", "Bienvenido"] },
},
renderOptions = {
parameters:['name'],
scriptBefore:'if(name) console.log(`Hello ${name}`)'
},
bundleRenderOptions = {
parameters:['name'],
scriptBefore:'console.log(`Hello ${name}`)'
}
defaultLang: "en",
});
// Build and send the response
const html = view.build({ user: "John Doe" }, "en",{
parameters:['Alex'],
bundleParameters:['"Alex"'],
});
res.send(html.outerHTML);View Inharitance
You can use an existing view and as prototype for inharitance:
const dashboard = new View('dashboard')
// Update layout for the dashboard
dashboard.layout.title('Dashboard').description('User Dashboard')
// Create list layout which exteds dashboard layout
const list = dashboard.view('list').render('./components/List')
// Create users and products layouts which exteds list layout
list.view('users').layout.title('Users')
list.view('products').layout.title('products')
// Use users layout by it's path
View.view('dashboard/list/users').build({users},'ru').end(res)
// Use products layout as child of list layout
list.view('products').build({products},'ru').end(res)Components
A component is a self-contained unit responsible for rendering a part of the page. Components can interact with the layout and modify the document dynamically.
Example Component
class UserCard extends Component {
constructor(props) {
super(props)
}
render() {
if (context.isBrowser === false) {
context.layout.title(`User: ${this.props.user.name}`)
context.layout.body.classList.add('user-card-page')
}
return (
<div class="user-card">
<h1>{this.props.user.name}</h1>
<p>{this.props.user.bio}</p>
</div>
)
}
}
module.exports = UserCardDynamic JavaScript
als-view allows embedding dynamic JavaScript code that can execute in the browser. Each rendered page includes a bundled function for dynamic behavior.
Example
const profile = new View('userProfile')
profile.render('./components/Profile', {
cyclicDependencies: true,
defaultLang: 'en'
})
profile
.build({ user: 'John Doe' }, 'en') // Build the page
.end(res) // The resulting page includes a `<script>` tag with dynamic JavaScript.Localization
Localization is supported through the langs and dictionary options. Use context.lang and localization functions like _(text) in components.
Example
const localizedView = new View('Greeting')
localizedView.render('./components/Greeting', {
langs: { langs: ['en', 'es'], dictionary: { hello: ['Hello', 'Hola'] } },
defaultLang: 'es'
})
localizedView.build({}, 'es').end(res)Initializing Project Structure with als-view
To quickly set up your project structure with als-view, use the provided copy.js script. This script creates a default folder structure within your project’s directory, which includes essential resources like layouts, views, pages, and error handling components.
Running the copy.js Script
Run the Command: To execute the script, use the following command from your project's root directory. This will copy the default
als-viewfolder structure into your project:node ./node_modules/als-view/copyUsing the
--overwriteFlag: The--overwriteflag allows you to overwrite any existing resources within the target directory. This is useful if you want to reset the folder structure or update it with the latest version:node ./node_modules/als-view/copy --overwriteNote: Use the
--overwriteflag carefully, as it will replace any existing files in the target directory.
Folder Structure Created by the copy.js Script
After running the copy.js script, your project directory will contain the following resources structure:
my-project/
├── resources/
│ ├── index.js # Main entry point for configuring views and environment
│ └── components/
│ ├── Error.js # Error component
│ └── Root.js # Main component
│ ├── lang/
│ ├── tools/
│ └── error-codes.js # Error codes map
│ └── views/
│ ├── main.js # Main view setup
│ └── error.js # Error view setupUsage Example
Once the structure is created, you can use it directly in your application code to configure and serve views and pages. Here’s a quick example of setting up the root and error pages:
const express = require('express')
const app = express()
// Import the main View setup
const View = require('./resources');
app.use(View.mw())
app.get('/',(req,res) => req.view('main').end(res))
app.get('/dashboard/users',(req,res) => {
try {
req.view('dashboard/users',{users}).end(res)
} catch (error) {
req.view('error',{status:500,msg:error.message},'ru').end(res)
}
})
View.env.publish(app,express)
app.listen(3000)With this setup, your als-view project structure is ready to use for server-side rendering, including error handling and SEO configurations.
API Reference
Static Methods and Properties
View.views: object with all views. The key is a path and value view instanceView.mw(env): return middleware which adds to reqreq.view(path,data, lang, context, browserContext)get View.env: getter for envView.env.publics: Includes all public file and folders as {url:path}View.env.routes: Include get routes as {url:content}View.env.publish(app,express): publishing all routes and public files and folders
set View.env: Configures the global environment.get View.layout: Accesses the global layout.View.context: global context to include in context withbuildmethodView.browserContext: global browserContext to include in context withbuildmethod
Instance Methods
constructor(name, parentView, addToViews = true)name- String:required.
view.view(name): Creates view child or return existing view childname- String:required.
view.parentview.viewsview.nameview.pathget view.renderedrender(path, options): Renders a component at the specifiedpathwith the givenoptions.path: Relative path to the component file (no need for.jsextension).options:cyclicDependencies: (boolean) Handle cyclic dependencies.version: (string) Optional version identifier.langs: (object) Localization settings.defaultLang: (string) Default language.selector: (string) DOM selector to attach the rendered content.renderOptions = {parameters=[], scriptBefore='', scriptAfter=''}bundleRenderOptions = {parameters=[], scriptBefore='', scriptAfter=''}
build(data, lang, context = {}, browserContext = {}): Builds the final HTML document.data: Data passed to the component.lang: Language for localization.options={}context: Additional context for the layout (includes View.context).browserContext: Context for browser-side rendering (includes View.browserContext).parametersbundleParameters