在文章使用webpack打包react应用程序中讲述了浏览器端的 React 组件的语法转换和打包过程。要使组件能在服务器端渲染,也必须使用 babel 转换成目前 node.js 版本支持的语法。下面介绍的方法就是,在开发过程中让 src 中的组件代码发生修改时,转译一份 node.js 端能直接使用的版本。它们就像原像和镜像一样,原像发生变化时,镜像跟着变化。
除了安装 babel 的核心模块、预设模块和插件外,我们还需要安装 grunt-babel 插件:
yarn add grunt-babel --dev安装 grunt-contrib-watch 文件监听插件:
yarn add grunt-contrib-watch --devGruntfile.js 的相关配置如下:
'use strict';
module.exports = function (grunt) {
const {dir} = require('./Grunt.config');
grunt.initConfig({
watch: {
watchNode: {
files: [
'Gruntfile.js',
'grunt.config.js',
`${dir.frontComponents}/**/*.js`
],
tasks: ['babel']
}
},
babel: {
options: {
sourceMap: false,
presets: ["@babel/preset-env", "@babel/preset-react"],
plugins: ["@babel/plugin-proposal-class-properties"]
},
dist: {
files: [{
expand: true,
cwd: `${dir.frontComponents}`,
src: ['**/*.js'],
dest: `${dir.nodeComponents}`
}]
}
}
});
require('load-grunt-tasks')(grunt);
grunt.registerTask('babel-jsx', ['babel']);
grunt.registerTask('watch-node', ['watch:watchNode']);
}就这样,当运行 npm run watch 监听 src/front 下的 React 组件并打包时,同时运行 grunt watch-node,转译一份 node.js 支持的版本到 src/node 目录下。
在服务器端渲染组件时需要注意如下问题:
- 需要在服务器端同时安装组件依赖的模块。
- 如果使用 export default App; 的方式导出组件时,babel 会把导出的 App 对象添加到 default 属性下。所以使用 export {App}; 的方式导出更直接。
- 在服务器端会执行组件的 constructor、static getDerivedStateFromProps、render 等的方法,所以应该避免在这些方法内执行浏览器端操作,不然就需要做类似 typeof document !== 'undefined' 这样的环境判断。