manage.py runserver可以执行npm脚本吗?

时间:2017-02-27 22:38:52

标签: django reactjs webpack webpack-dev-server webpack-2

我正在开发一个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的类似工作。

3 个答案:

答案 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,但这是另一个主题)。