manage.py runserver 可以执行npm 脚本吗?
Can manage.py runserver execute npm scripts?
我正在开发一个 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
.
的工作
您不应乱用内置管理命令,但您可以创建自己的命令: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 等 运行(运行ning runserver
分开,但这是另一个话题)。
如果您已经在使用 webpack 和 django,您可能会对使用 webpack-bundle-tracker 和 django-webpack-loader 感兴趣。
基本上每次构建 bundle 时 webpack-bundle-tracker 都会创建一个 stats.json 文件,django-webpack-loader 会监视这些 stats.json 文件以重新启动开发服务器。这个堆栈允许分离服务器和客户端之间的关注点。
有a couple of posts out there explaining条管道。
我晚了两年半,但这是一个管理命令,它实现了 OP 想要的解决方案,而不是重定向到另一个解决方案。继承staticfiles 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 注意到 .py
文件更改。无论如何,Webpack 应该会自动重新加载。
使用--webpack-command
参数改变运行的webpack命令(比如我使用--webpack-command 'vue-cli-service build --watch'
使用 --webpack-quiet
禁用命令的输出,因为它会变得混乱。
如果您真的想覆盖默认运行服务器,请将文件重命名为 runserver.py
并确保它所在的应用程序位于 之前 django.contrib.static
您的设置模块的 INSTALLED_APPS
.
我正在开发一个 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
.
您不应乱用内置管理命令,但您可以创建自己的命令: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 等 运行(运行ning runserver
分开,但这是另一个话题)。
如果您已经在使用 webpack 和 django,您可能会对使用 webpack-bundle-tracker 和 django-webpack-loader 感兴趣。
基本上每次构建 bundle 时 webpack-bundle-tracker 都会创建一个 stats.json 文件,django-webpack-loader 会监视这些 stats.json 文件以重新启动开发服务器。这个堆栈允许分离服务器和客户端之间的关注点。
有a couple of posts out there explaining条管道。
我晚了两年半,但这是一个管理命令,它实现了 OP 想要的解决方案,而不是重定向到另一个解决方案。继承staticfiles 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 注意到 .py
文件更改。无论如何,Webpack 应该会自动重新加载。
使用--webpack-command
参数改变运行的webpack命令(比如我使用--webpack-command 'vue-cli-service build --watch'
使用 --webpack-quiet
禁用命令的输出,因为它会变得混乱。
如果您真的想覆盖默认运行服务器,请将文件重命名为 runserver.py
并确保它所在的应用程序位于 之前 django.contrib.static
您的设置模块的 INSTALLED_APPS
.