- Zero / Minimal Webpack5 configration.
- Out of box for react project.
- Support CSR, SSR build
- CLI and Nodejs interface.
Let's take w-popover for example.
- dev command: node pack
- build command: node pack --build
/* filename: pack.js */
const { default: pack } = require('packw');
const argv = require('yargs').argv;
const path = require('path');
const isBuild = !!argv.build;
pack(!isBuild, {
entry: {
index: `./demo/index`,
},
output: {
path: path.resolve(__dirname, !isBuild ? '.dev' : 'docs'),
publicPath: '',
},
devServer: {
port: 9101,
},
resolve: {
alias: {
'w-popover': path.resolve(__dirname, './src'),
},
},
});
- Add a server side rendering entry.
/* filename: index.ssr.jsx */
import React from 'react';
import { renderToString } from 'react-dom/server';
import App from './App';
export default function () {
return renderToString(<App />);
}
- Add nodejs to generate a commonjs library to run above SSR function.
// filename: pack.ssr.js
const { getNodeLib } = require('packw');
const chalk = require('chalk');
getNodeLib({ index: './demo/index.ssr.jsx' }, () => {
console.log(chalk.greenBright('ssr library generated!'));
});
- For Prerendering, please configuare the html template. Thus we can use templateContent function to dynamically inject the prerendered html content.
// filename: index.tpl.js in root directory.
const path = require('path');
const fs = require('fs');
module.exports = function (htmlWebpackPlugin) {
let renderer = {};
if (fs.existsSync(path.resolve(`./ssr-lib/index.js`))) {
renderer = require(`./ssr-lib/index.js`).default;
}
const body = renderer?.();
return `
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="format-detection" content="telephone=no, email=no" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-touch-fullscreen" content="yes" />
${htmlWebpackPlugin.tags.headTags}
<link rel="shortcut icon" />
<title>w-popover demo</title>
</head>
<body>
<div id="root">${body}</div>
${htmlWebpackPlugin.tags.bodyTags}
</body>
</html>
`;
};
- The combined commands for prerendering
node pack.ssr && node pack --build
- SSR with expressjs
just like prerender, except for that we run the ssr function for each request. below is an example with express.js
const express = require('express');
const app = express();
const path = require('path');
const ssrRenderer = require('./ssr-lib/index');
app.disable('x-powered-by');
app.enable('trust proxy');
app.set('view engine', 'html');
app.engine('html', require('ejs').renderFile);
app.set('views', path.resolve(__dirname, 'dist'));
const distRoot = path.resolve(__dirname, 'dist');
app.use(express.static(distRoot));
app.use((req, res, next) => {
const context = {};
res.render(
'index',
{ html: ssrRenderer.indexRender(req.url, context), delimiter: '?' },
(err, str) => {
if (err) {
throw err;
}
res.send(str);
}
);
});
app.use(function (err, req, res, next) {
if (err) {
res.status(500).send('server is down.');
}
});
const PORT = process.env.PORT || 8080;
app.listen(PORT, () => {
console.info(`==> 🍺 Express server running at localhost: ${PORT}`);
});