Get started - Node plugin
Node plugin
Install
v.usePlugin()
method.require('valyrian.js');
let NodePlugin = require('valyrian.js/plugins/node');
v.usePlugin(NodePlugin);
This plugin provides what is necessary to work on the server side without having to change the client code. As well as the tools for the inclusion of minified JS / CSS in HTML and the generation of the required files for a PWA.Inline css and js
Assume this client side app
// client.js
require('valyrian.js');
let Router = require('valyrian.js/plugins/router.js');
v.usePlugin(Router);
let Component = () => <div>Hello worlddiv>;
let router = v.Router();
router.get('/', () => Component);
// Main container component
let HtmlComponent = (null, ...children) => [
'',
<html lang="en">
<head>
<title>My awesome apptitle>
{v.inline.css().map(({raw, map}) => <style>{raw}{map}style>)}
head>
<body>
{children}
{v.inline.js().map(({raw, map}) => <script>{raw}{map}script>)}
body>
html>
];
// Export main container component
module.exports = HtmlComponent;
Create entry point for server side requiring Valyrian.js register hook// index.js - server side entry point
// Register Valyrian.js in fly transpilation
require('valyrian.js/register');
// Require server file
require('./server.js');
Implement SSR with Express// server.js with Express
// Require express
let express = require('express');
// Require valyrian and main html container
let HtmlComponent = require('./client.js');
let nodePlugin = require('valyrian.js/plugins/node');
v.usePlugin(nodePlugin);
// We make this an async function because top level await is still an experimental function in nodejs
let init = async () => {
// Init express
let app = express();
// Compile and minimize client.js and bootstrap.css
await v.inline('./client.js', './some-awesome.css');
// Same as call await v.inline.js('./client.js') && await v.inline.css('./some-awesome.css');
// Add home route
app.get('/', (req, res) => v.routes.go(HtmlComponent, '/').then(res.send))
// Init the server
app.listen(3000);
});
init();
The result to call our home route in the browser will be:DOCTYPE html>
<html lang="en">
<head>
<title>My awesome apptitle>
<style>
// inline minified some awesome css minimized
// some awesome css source map
style>
head>
<body>
<div>Hello worlddiv>
<script>
// Inline, bundled as iife, client js code
// client js source map
script>
body>
html>
v.inline
method
The inline method takes any number of arguments and will perform the next steps:- For each passed file path
- It will extract the extension of that passed file path
- If the inline method does not have a convenience method for this extension it will create it. (inlining a `txt` file will create a `v.inline.txt` getter/setter method)
- Then it will pass the file path to this method to get its contents
- The method will push the contents to an array to be used as the store for this extension
If you pass a file path it will get the contents of that file.
If you does not pass a file, then, it will return the contents of the stored files.
At the start the inline method will only have the
v.inline.js
and the v.inline.css
methods.Will also have an v.inline.uncss
method whose implementation is different from the previous ones, keep reading to know more about this method.v.inline.js
method
The v.inline.js
inline method not only will get the contents of the file, but also compile and minimize the code by passing it to a customizedRollup configuration. The result will be an object like:{
raw, // Bundled and minimized code
map, // Generated source map for this code
file // The name of the entry file
}
This will allow us to embed the client side source code directly in the html response without the need of a transpilation/build step and reduce the need of a js file request for the client. Also, this method will receive an options object as a second parameter that will be passed to rollup.This object must have the next shape:
{
inputOptions: {
// Some custom options
},
outputOptions: {
// Some output options
}
}
v.inline.css
method
The v.inline.css
inline method not only will get the contents of the file, but also will minify the css by passing it to a default instance of the CleanCSS optimizer. The result will be an object like:{
raw, // Minimized styles
map: null,
file // The name of the entry file
}
Similar to the v.inline.js
, this method will receive an options object as a second parameter that will be passed directly to CleanCSS.v.inline.uncss
method
Although the styles getted by the v.inline.css
method will be minified, the result will be the whole styles, no matter if the styles are used or not by the site. This minimized styles allow us to develop faster, but for production we recommend to include only the styles that will be used by the site. For this task we have the v.inline.uncss
method which works different from the other convenience methods.You will need to use the
v.inline.css
method first for this to work. After minimize some css files with the v.inline.css
method you can pass a set of html strings to the v.inline.uncss
method to get only the used css styles.Example:
Given this css file:
// style.css file
span{display:block;}
span.hello{display: inline-block}
// js file
let html = "Hello world";
await v.inline.css('./style.css');
let cleanCss = await v.inline.uncss([html]); // -> "span{display:block}"
This method will use PurgeCSS to do this cleaning of styles, and can also receive an options object as a second parameter that will be passed directly to the PurgeCSS.purge
method.