egg-view-nrssr

    1.0.13 • Public • Published

    egg-view-nrssr

    NPM version build status Test coverage David deps Known Vulnerabilities npm download

    eggjs框架的nunjucks模板插件

    依赖说明

    依赖的 egg 版本

    egg-view-nrssr 版本 egg 1.x
    1.x 😁
    0.x

    开启插件

    // config/plugin.js
    exports.nrssr = {
      enable: true,
      package: 'egg-view-nrssr',
    };

    使用场景

    • 此插件主要用于使用nunjucks作为html模板的react同构应用。
      它运用nunjucks自定义扩展能力,将服务端渲染的结果输出到html中。

    • 使用方法:

      eggjs框架中启用该模板插件

      // config/plugin.js
      exports.nrssr = {
        enable: true,
        package: 'egg-view-nrssr',
      };

      配置egg-view-nrssr

      // config/config.default.js
      module.exports = () => {
        const config = {};
       
        config.nrssr = {
          customTagName: 'pagelet',
          hydrate: 'hydrate',
          manifestPath: path.join(process.cwd(), 'app/public/manifest.json'),
          ...otherConfig,
        };
       
        config.view = {
          defaultViewEngine: 'nrssr',
          defaultExtension: '.html',
        };
       
        return config;
      };

      controller中渲染nunjucks模板

      // app/controller/home.js
      class HomeController extends Controller {
        async index() {
          const props = await ctx.service.home.getProps();
          const body = await ctx.renderView('index', {
            pageletProps: {
              home: {
                ...props,
              }
            }
          });
        }
      }

      view定义nunjucks模板

      <!-- app/view/index.html -->
      <!DOCTYPE html>
      <html>
        <head>
          <title>My App</title>
          <meta charset="utf-8">
        </head>
        <body>
          {% pagelet 'home' %}
        </body>
      </html>

      controller中的pageletProps会传给egg-view-nrssregg-view-nrssr解析app/view/index.html模板,
      解析到{% pagelet 'home' %}时,renderToString会寻找home组件,将pageletProps['home']作为props渲染home组件得到html替换{% pagelet 'home' %}得到最终的html

    详细配置

    /**
     * @property {Boolean} noCache - nunjucks配置,不使用缓存,每次都重新编译
     * @property {Function} getLoadableBundles - react-loadable服务端渲染需要。获取当前页面懒加载的bundle打包后的文件名,以便提前插入到html中。
     *                                           因为react-loadable懒加载应该用于前端路由变化时,在由服务端渲染页面时,
     *                                           应该先在服务端通过preloadAll方法提前加载所有bundle,直接渲染当前页面完整内容。
     *                                           然后在客户端先由script标签提前加载所有bundle,接着通过preloadReady方法告知bundle已经提前加载,
     *                                           从而客户端混合时是和服务端一致的完整页面。
     *                                           该方法接收一个参数modules,它是当前页面所有bundle名的数组。
     *                                           当前页面所有bundle名要在服务端渲染页面时通过react-loadable提供的Capture高阶组件捕获。
     *                                           具体参见react-loadable文档。
     * @property {String} basename - react-router的basename。如果使用了react-router,服务端渲染react应用时需要此配置,以渲染出正确的内容
     * @property {AsyncFunction} beforeStart - 在应用启动前执行。可以将服务端渲染时耗时长的操作放到这里提前执行。
     *                                         比如把react组件提前通过babel编译读入内存;提前执行react-loadable的preloadAll等,以减少服务端渲染的时长
     * @property {String} customTagName - nunjucks自定义扩展的tag标识符,我们称一个自定义扩展tag形成的块为pagelet。
     * @property {Function | AsyncFunction} renderToString - 服务端渲染方法。渲染pagelet。
     *                                                       接收的参数:pageletProps 该页面所有pagelet的属性
     *                                                                 name 当前pagelet的名称
     *                                                                 reactRouterContext react-router服务端渲染的context,
     *                                                                                    用于Redirect在服务端渲染时的重定向等。
     *                                                                                    具体参见react-router Server Rendering文档
     *                                                                 loadableModules 收集当前页面react-loadable所有懒加载bundle名的数组
     *                                                                 ctx 当前请求的上下文,包含eggjs的ctx
     *                                                                 basename react-router的basename
     * @property {String} hydrate - 用于客户端混合react的文件名
     * @property {String} manifestPath - webpack打包生成的manifest文件路径。用于根据源码文件名找到打包后的文件名,打包后的文件名可能带有hash值。
     *                                   本地开发时,manifest文件是从webpack虚拟文件系统读取,请使用的egg-webpack插件
     * @property {String} commonFiles - webpack通过splitChunks分离出来的公共文件名。一般都是第三方库文件,这些文件需要提前注入到html中
     * @property {String} renderHtml - nunjucks编译完后最后一次改变html的机会,原始需求是替换react-document-title生成的title。具体见react-document-title服务端渲染的文档
     */
    exports.nrssr = {
      noCache: false,  // default false    
      getLoadableBundles: modules => [], // default () => [], required only if react-loadable used
      basename: '', // default '', required only if react-router used
      beforeStart: async app => [], // no default, not required
      customTagName: 'pagelet', // no default, required
      renderToString: async ({
        pageletProps: {
          [pagelet]: {}
        },
        name: '',
        reactRouterContext: {},
        loadableModules: [],
        ctx: {
          ctx: {
            app
          }
        },
        basename: '',
      }) => html, // no default, required
      hydrate: 'hydrate', // no default, required
      manifestPath: '/path/to/app/public/mainfest.json', // no default, reqiured
      commonFiles: [
        'react',
        'react-dom',
      ], // no default, not required
      renderHtml: html => html // no default, not required
    };
    • 其中noCachenunjunks的配置,你还可以使用任何其他的nunjunks配置

    注意事项

    webpack打包需要将React组件文件和hydrate文件导出为commonjs模块。因为为了减少客户端全局变量,我们使用了唯一全局变量exports。参考如下配置:

    output: {
      filename: '[name].js',
      libraryTarget: 'commonjs',
      library: '[name]',
      libraryExport: 'default',
    }

    提问交流

    请到 egg-view-nrssr issues 异步交流。

    License

    MIT

    Install

    npm i egg-view-nrssr

    DownloadsWeekly Downloads

    1

    Version

    1.0.13

    License

    MIT

    Unpacked Size

    20.1 kB

    Total Files

    11

    Last publish

    Collaborators

    • mclemore