我正在开发一个Web应用程序,前端为React
,后端为Django
。我使用Webpack
来监视React应用的更改和捆绑代码。
问题是我必须同时运行两个命令,一个用于React,另一个用于Django:
webpack --config webpack.config.js --watch
./manage.py runserver
有没有办法自定义runserver
命令来执行npm脚本,比如npm run start:dev
?当您使用Node.js作为后端平台时,您可以执行类似npm run build:client && npm run start:server
的类似工作。
答案 0 :(得分:1)
如果您已经在使用webpack和django,可能您可能对使用webpack-bundle-tracker和django-webpack-loader感兴趣。
基本上webpack-bundle-tracker将在每次构建bundle时创建一个stats.json文件,django-webpack-loader将监视这些stats.json文件以重新启动dev服务器。该堆栈允许分离服务器和客户端之间的关注点。
a couple此管道中有explaining个帖子。
答案 1 :(得分:1)
我已经迟了两年半了,但这是一个管理命令,可以实现OP想要的解决方案,而不是重定向到另一个解决方案。它从静态文件runserver继承,并在线程中同时运行webpack。
在<some_app>/management/commands/my_runserver.py
处创建此管理命令:
import os
import subprocess
import threading
from django.contrib.staticfiles.management.commands.runserver import (
Command as StaticFilesRunserverCommand,
)
from django.utils.autoreload import DJANGO_AUTORELOAD_ENV
class Command(StaticFilesRunserverCommand):
"""This command removes the need for two terminal windows when running runserver."""
help = (
"Starts a lightweight Web server for development and also serves static files. "
"Also runs a webpack build worker in another thread."
)
def add_arguments(self, parser):
super().add_arguments(parser)
parser.add_argument(
"--webpack-command",
dest="wp_command",
default="webpack --config webpack.config.js --watch",
help="This webpack build command will be run in another thread (should probably have --watch).",
)
parser.add_argument(
"--webpack-quiet",
action="store_true",
dest="wp_quiet",
default=False,
help="Suppress the output of the webpack build command.",
)
def run(self, **options):
"""Run the server with webpack in the background."""
if os.environ.get(DJANGO_AUTORELOAD_ENV) != "true":
self.stdout.write("Starting webpack build thread.")
quiet = options["wp_quiet"]
command = options["wp_command"]
kwargs = {"shell": True}
if quiet:
# if --quiet, suppress webpack command's output:
kwargs.update({"stdin": subprocess.PIPE, "stdout": subprocess.PIPE})
wp_thread = threading.Thread(
target=subprocess.run, args=(command,), kwargs=kwargs
)
wp_thread.start()
super(Command, self).run(**options)
对于尝试编写从runserver继承的命令的其他任何人,请注意,您需要检查DJANGO_AUTORELOAD_ENV
变量以确保您不会在每次django注意到{{1}时都未创建新线程}文件更改。无论如何,Webpack应该自己进行自动重装。
使用.py
参数来更改运行的webpack命令(例如,我使用--webpack-command
使用--webpack-command 'vue-cli-service build --watch'
禁用命令的输出,因为它可能会变得混乱。
如果您真的想覆盖默认的运行服务器,请将该文件重命名为--webpack-quiet
,并确保它所在的应用在设置模块的{{ 1}}。
答案 2 :(得分:0)
您不应该使用内置的管理命令,但是您可以创建自己的命令:https://docs.djangoproject.com/en/1.10/howto/custom-management-commands/。
在您所在的位置,我将runserver
保留到位并创建一个以运行您的自定义(在这种情况下为npm
)脚本,即使用os.execvp
。
理论上,您可以运行两个并行子进程,一个执行例如django.core.management.execute_from_command_line
,另一个运行脚本。但它会使pbd
这样的工具变得不可能(这使得工作变得非常困难)。
我这样做是因为我利用Docker和Docker编写。然后当我使用docker-compose up -d
我的数据库服务时,npm脚本,redis等在后台运行(分别运行runserver
,但这是另一个主题)。