suprya

0.0.1 • Public • Published

Suprya npm Travis CI

The most flexible JavaScript static site generator, powered by Webpack.


✨ Features

  • Bundle your app using only a package.json and webpack.config.js
  • Opinionated Webpack defaults for both development and production modes
  • Prerenders all your app routes (via prerender-loader)
  • Everything is configurable (and uses technologies you already know)

🔧 Installation

Install suprya using npm:

npm i -D suprya

The minimum supported Node version is v6.9.0

📦 Usage

Suprya takes your Webpack config as an input and adds its own opinionated config values for the ultimate developer experience. To start, open your webpack.config.js and wrap your exported config with the suprya() function:

const suprya = require('suprya');
 
const isProduction = process.env.NODE_ENV === 'production';
 
module.exports = suprya({
  mode: isProduction ? 'production' : 'development',
  module: {
    rules: [
      {
        test: /\.js$/,
        loader: 'babel-loader'
      }
    ]
  }
});

Suprya will take care of adding the entry (./src/index.js) and output (defaults to the dist directory) options, adding vendor chunk splitting and applying all the plugins for you. But, don't worry; you can still change all these options if you need more flexibility.

Next, we will add the src/template.html file which will be the base of all the prerendered outputs (but will also be used in development mode):

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
  </head>
  <body>
    <div id="root">
      {{prerender:./src/prerender.js}}
    </div>
  </body>
</html>

As you can see, we've used a Handlebars expression that tells Suprya that the prerendered content (generated by the prerender.js file, which we will create on the next step) needs to be appended under #root.

Thanks to prerender-loader you can either export a String which will be used as the static HTML or automatically render it on the #root element. Depending on what library you're using its contents may vary. Here are some examples:

React app

Suprya supports any kind of router such as react-router or Reach router.

src/prerender.js

import React from 'react';
import { renderToString } from 'react-dom/server';
 
import App from './components/App';
 
export default () => renderToString(<App />);

You can also take a look at the example React app on examples/react. It has a README which explains things related to React in greater detail.

Preact app

TODO

Submit your own!

You can add your own library by submitting a PR! 😀

Suprya will call your prerender.js default exported function on production for each one of your routes (we take care of setting the right window.location value for you).

Also note that you can export an async function or a Promise in case you might want to wait for the DOM rendering to settle down before allowing Suprya to serialize the document to static HTML:

// Taken from the prerender-loader docs
import { render, options } from 'dom-library';
import App from './App';
 
// We're done when there are no renders for 50ms:
const IDLE_TIMEOUT = 50;
 
export default () => new Promise(resolve => {
  let timer;
 
  // Each time your library re-renders, reset our idle timer:
  options.debounceRendering = commit => {
    clearTimeout(timer);
    timer = setTimeout(resolve, IDLE_TIMEOUT);
    commit();
  }
 
  // Render into <body> using normal client-side rendering:
  render(<App />, document.body);
})

Everything that's left is telling Suprya about what routes you want to prerender (you might not want to render all of them, but it's recommended) by passing a routes array to the Suprya config. Go to your webpack.config.js file and add the following:

const suprya = require('suprya');
 
module.exports = suprya({
  routes: [
    {
      url: '/',
      title: 'Home Page'
    },
    {
      url: '/contact',
      title: 'Contact Me'
    }
  ],
  defaultTitle: 'My Awesome App'
  // ...
});

Suprya will now prerender / and /contact on production mode by calling your prerender.js default export to produce the dist/index.html and dist/contact/index.html files.

That's it! You can now run webpack using your preferred CLI. We recommend using the following:

  • webpack-command for bundling your files for production. Here are some useful flags and tips:
    • --bail will stop the build on the first error.
    • --run-prod will apply additional optimizations such as UglifyJS on top of Suprya. (Details)
    • --progress will show a nice progress bar.
    • Don't forget to set NODE_ENV to production (Instructions)
  • webpack-serve for hot reloading your app during development. Here are some useful tips:

🔨 Options

Suprya shares the same configuration object as Webpack, but will remove all its values from the final Webpack config e.g., in order to pass the disabled option you would add the disabled key to your webpack.config.js file as follows:

const suprya = require('suprya');
 
module.exports = suprya({
  disabled: true,
  // Other Webpack or Suprya options
});
Option Type Default Description
routes [{ url, title, meta, ... }] undefined Which routes you want to prerender. Each route has a required url key, an optional title and additional html-webpack-plugin options.
defaultTitle string "Suprya App" The default title used for pages which haven't specified one.
templatePath string "src/template.html" The location of the HTML template used for prerendering (also used in development mode).
shouldUseSourceMap boolean mode === 'production' Whether to generate production or development source maps. You can also add the Webpack's devtool option which will override Suprya's choice.
disabled boolean false Disables Suprya entirely (will return the same passed config). Useful for debugging.

✅ Opinionated Webpack options

Suprya is an opinionated static-site generator, but stands to be as flexible as possible, so any settings specified below can be overrided (by setting your preferred value on your webpack.config.js):

Suprya applies these Webpack options on production mode:

Option Value Description
entry ./src/index.js Which module Webpack will use to begin building out its internal dependency graph.
output
{
path: '[cwd]/dist',
filename: '[name].[chunkhash].js',
publicPath: '/'
}
Directory where the compiled files will be written.
devtool source-map Place source maps on a different file (ending in .js.map).
optimization
{
splitChunks: {
chunks: 'all'
},
runtimeChunk: true
}
Splits vendor dependencies and keeps the runtime chunk separated.

Suprya also applies these Webpack options on development mode:

Option Value Description
entry ./src/index.js Which module Webpack will use to begin building out its internal dependency graph.
output
{
path: '[cwd]/dist',
filename: '[name].[chunkhash].js',
publicPath: '/'
}
Directory where the compiled files will be written.
devtool cheap-module-source-map Generate fast (but bigger) source maps.
devServer
{
contentBase: '[cwd]/public'
}
Serve static assets from the public directory.
serve [see src/historyApiFallback.js] Applies the historyApiFallback addon.

Additionally, Suprya adds an HtmlWebpackPlugin instance in development mode and multiple ones (to make prerendering possible) on production mode. That means you don't need to add the HtmlWebpackPlugin to your webpack.config.js file.

Note: [cwd] refers to the current working directory i.e. the directory where you run the webpack CLI from.

🛣 Roadmap

  • Inlining the critical CSS and lazy-loading the rest (via Critters)
  • Configless route detection (might involve library specific plugins)
  • Automatic template and prerender.js creation.
  • Prerender all the routes

🥂 License

Suprya is open source software licensed as MIT.

Package Sidebar

Install

npm i suprya

Weekly Downloads

1

Version

0.0.1

License

MIT

Unpacked Size

28.5 kB

Total Files

5

Last publish

Collaborators

  • hugmanrique