背景

前端渲染模式asset 渲染模式 章节讲到了基于 React 的前端渲染模式,但都依赖 egg-view-react-ssr 插件,那如何基于已有 egg 模板引擎 (egg-view-nunjucksegg-view-ejs) + Webpack 完全自定义前端方案呢?

关键问题

  • 本地开发 Webpack 与 Egg 集成,可以直接使用 egg-webpack, 该插件可以独立使用, 当然你可以实现。
  • 通过 egg-view-nunjucksegg-view-ejs 插件进行数据绑定
  • 通过 html-webpack-plugin 插件生成 HTML 文件,并自动注入 JS/CSS 依赖
  • 本地开发时,需要通过 write-file-webpack-plugin 插件把 Webpack HTML 文件写到本地。Webpack 默认是在内存里面,无法直接读取。

如何实现

这里以 egg-view-nunjucks 为例,其它模板引擎类似。

npm install egg-view-nunjucks --save
npm install egg-webpack --save-dev

  1. // ${root}/package.json
  2. {
  3. "dependencies": {
  4. "egg-webpack": "^4.0.0",
  5. "egg-view-nunjucks": "^2.2.0",
  6. }
  7. }
  1. // ${root}/config/plugin.local.js
  2. exports.webpack = {
  3. enable: true,
  4. package: 'egg-webpack',
  5. };
  6. // ${root}/config/plugin.js
  7. exports.nunjucks = {
  8. enable: true,
  9. package: 'egg-view-nunjucks',
  10. };
  • 配置 layout.tpl 模板
  1. <!DOCTYPE html>
  2. <html lang='en'>
  3. <head>
  4. <title>{{title}}</title>
  5. <meta name='keywords'>
  6. <meta name='description'>
  7. <meta http-equiv='content-type' content='text/html;charset=utf-8'>
  8. <meta name='viewport' content='initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui'>
  9. <link rel='shortcut icon' href='/favicon.ico' type='image/x-icon' />
  10. <!-- html-webpack-plugin 自动注入 css -->
  11. </head>
  12. <body>
  13. <div id='app'></div>
  14. <script type="text/javascript">
  15. window.__INITIAL_STATE__ = {{ }};
  16. </script>
  17. <!-- html-webpack-plugin 自动注入 js -->
  18. </body>
  19. </html>
  • 配置默认渲染引擎
  1. // ${root}/config/local.js
  2. module.exports = app => {
  3. const exports = {};
  4. exports.webpack = {
  5. webpackConfigList: require('@easy-team/easywebpack-react').getWebpackConfig()
  6. };
  7. return exports;
  8. }
  9. // ${root}/config/default.js
  10. module.exports = app => {
  11. const exports = {};
  12. exports.view = {
  13. defaultViewEngine: 'nunjucks',
  14. mapping: {
  15. '.tpl': 'nunjucks'
  16. },
  17. };
  18. return exports;
  19. }
  • render默认调用,使用 nunjucks 模板引擎
  1. const egg = require('egg');
  2. module.exports = class AppController extends egg.Controller {
  3. async home(ctx) {
  4. await ctx.render('app.tpl', { title: 'HTML渲染' });
  5. }
  6. }
  1. const HtmlWebpackPlugin = require('html-webpack-plugin');
  2. module.exports = {
  3. egg: true,
  4. target: 'web',
  5. entry: {
  6. app: 'app/web/page/app/app.js'
  7. },
  8. plugins: [
  9. new HtmlWebpackPlugin({
  10. chunks: ['runtime','common', 'app'],
  11. filename: '../view/app.tpl',
  12. template: './app/web/view/layout.tpl'
  13. }),
  14. new HtmlWebpackPlugin({
  15. chunks: ['runtime','common', 'test'],
  16. filename: '../view/test.tpl',
  17. template: './app/web/view/layout.tpl'
  18. }),
  19. ]
  20. };

依赖插件

骨架项目

https://github.com/easy-team/egg-react-webpack-boilerplate/tree/feature/green/html