django服务器端渲染,由包裹捆绑器提供支持
django-parcel-ssr的Python项目详细描述
Django包裹SSR
零配置为Django web framework执行javascript服务器端呈现,由Parcel bundler提供支持。
安装
pip install django-parcel-ssr npm install parcel-bundler esm
React是即时支持的,但是可以使用任何支持服务器端呈现的javascript视图库(请参见scripts
选项和examples)。要使用react,请安装其他依赖项:
npm install react react-dom react-helmet styled-jsx
默认的react设置附带可选的^{.babelrc
文件添加到项目根目录:
{"plugins":["styled-jsx/babel"]}
note对于typescript用户:packet 1.x不支持用于typescript的babel插件。查看TypeScript example以获得解决方案。
更新settings.py
中的INSTALLED_APPS
、TEMPLATES
和STATICFILES_DIRS
项:
INSTALLED_APPS=['ssr',# ...]TEMPLATES=[{'BACKEND':'ssr.backends.javascript.Components','DIRS':[],'APP_DIRS':True,'OPTIONS':{# 'extensions': ['js', 'jsx', 'ts', 'tsx'],# 'output_dirname': 'dist/',# 'json_encoder': 'django.core.serializers.json.DjangoJSONEncoder',# 'cache': True,# 'env': {# 'NODE_ENV': 'development' if DEBUG else 'production',# 'NODE_OPTIONS': '-r esm',# 'WORKER_TTL': 1000,# },# 'scripts': {# 'server': os.path.join(BASE_DIR, '.ssr', 'scripts', 'react', 'server.js'),# 'client': os.path.join(BASE_DIR, '.ssr', 'scripts', 'react', 'client.js'),# }}},# ...]STATICFILES_DIRS=(os.path.join(BASE_DIR,'.ssr','static'),# ...)
在wsgi.py
:
# ...importssrssr.setup()
我们建议将.ssr/
目录添加到.gitignore
,以避免提交生成。
用法
安装的django应用程序的bundles
目录中的javascript文件用作包入口点,它们必须提供根组件作为默认导出。避免将非根组件放在bundles
目录中以防止不必要的绑定:
bundles/
template.js
components/
layout.js
navbar.js
...
在已安装的应用程序目录中创建示例bundles/template.js
文件:
importReactfrom'react'import{Helmet}from'react-helmet'exportdefaultprops=>{const[count,setCount]=React.useState(props.count)return(<div><Helmet><title>{props.title}</title></Helmet><h1>Count:{count}</h1><buttononClick={()=>setCount(count+1)}>+</button><buttononClick={()=>setCount(count-1)}>-</button><stylejsx>{` h1 { color: ${props.color}; } `}</style></div>)}
模板引擎可以使用bundle进行服务器端呈现,但是context必须是json可序列化的(请参见下面的限制)。
在urls.py
:
fromdjango.urlsimportpathfromdjango.shortcutsimportrenderdefreact_view(request):returnrender(request,'template.js',context={'title':'Django SSR''count':0,'color':'red'})urlpatterns=[# ...path('',react_view)]
运行./manage.py runserver
,并导航到http://localhost:8000
。
查阅Parcel documentation了解支持的资产、配方等。
限制
模板上下文必须是json可序列化的值,因为实际的呈现是由javascript处理的。django对象必须是serialized;查询集可以呈现为字典,而不是使用^{
展开
如果NODE_ENV
选项设置为production
(默认情况下,当DEBUG = False
时会发生这种情况),则启动django应用程序不会自动绑定入口点。您需要手动调用管理命令,然后收集静态文件:
./manage.py bundle ./manage.py collectstatic -l
选项
扩展
默认值:['js', 'jsx', 'ts', 'tsx']
捆绑包的有效文件扩展名列表。
输出目录名
默认值:'dist/'
包裹束输出目录的名称。尾随斜杠是必需的。
JSON编码器
默认值:'django.core.serializers.json.DjangoJSONEncoder'
用于将视图上下文序列化为属性的JSON编码器类。
缓存
默认值:True
启用或禁用包裹捆绑器缓存。
环境节点环境
默认值:'development' if DEBUG else 'production'
开发模式使用hmr(热模块更换)激活bundle watcher。生产模式执行单个构建并输出优化的包。
环境节点选项
默认值:'-r esm'
节点工作器的cli选项。
服务器端呈现程序使用^{
环境工作者
默认值:1000
毫秒数的节点工作人员将等待Django在退出之前重新启动。
scripts.server
默认值:'{BASE_DIR}/.ssr/scripts/react/server.js'
自定义createRenderer
函数的绝对路径,用于创建render
函数,该函数必须返回HTML文档字符串。此文件是在服务器上传输和执行的。
import{createElement,renderToString}from'some-view-library'exportdefaultComponent=>({script,stylesheet},props)=>{constcomponent=createElement(Component,props)consthtml=renderToString(component)constserializedProps=encodeURIComponent(JSON.stringify(props))return` <!DOCTYPE html> <head> <!-- ... -->${stylesheet&&`<link src="${stylesheet}" rel="stylesheet">`} </head> <body> <div id="root" data-props="${serializedProps}">${process.env.NODE_ENV==='production'?html:''}</div> <script src="${script}"></script> </body> `}
脚本.客户端
默认值:'{BASE_DIR}/.ssr/scripts/react/client.js'
自定义hydrate
函数的绝对路径,用于在加载页时更新根dom节点。这个文件是透明的泰德在浏览器里。
import{createElement,hydrate,render}from'some-view-library'exportdefaultComponent=>{constroot=document.getElementById('root')constprops=JSON.parse(decodeURIComponent(root.dataset.props))constcomponent=createElement(Component,props)constmount=process.env.NODE_ENV==='production'?hydrate:rendermount(component,root)}
示例
对于高级用例,如使用客户端路由、状态管理库或不同的javascript视图库,请查看examples: