【问题标题】:What's the pythonic way to package a web app with a generation step?使用生成步骤打包 Web 应用程序的 Pythonic 方式是什么?
【发布时间】:2015-12-24 10:07:15
【问题描述】:

我有一个基于 Python 的网络应用程序,我正在尝试将其打包为 setuptools 包,以便可以使用 pip 和/或 python setup.py xxxxx 安装它。此 Web 应用程序还包含用于 React 前端的静态文件。我使用 webpack(因此也使用 node.js)为网站生成 JavaScript 包。我试图找出最pythonic的方式来打包它。通过谷歌搜索,我发现nodeenv 似乎相关。

理想情况下,我希望这个包具有以下特征:

  • 当与pip installpython setup.py install 一起安装时,它不应安装nodewebpack,但安装的包应该包含webpack输出。

  • webpack 生成的输出应该需要检查到源代码库中。 (即它需要在打包过程中的某个时刻生成。)

  • 当通过pip install -epython setup.py develop 设置包进行开发时,它应该安装nodewebpack(我怀疑前面提到的nodeenv 将是在这方面很有用。)此时也应该运行webpack,这样之后webpack生成的内容就存在了。

  • 如果这很简单,如果 webpack 可以在 virtualenv 激活时以“监视”模式启动,并在它被停用时停止,那也是很酷的(但这完全 一个延伸目标。)

考虑到这些要求,我的预感是我需要将sdist 命令子类化,以便在源代码分发生成时生成 webpack 输出。我也猜想我需要继承 develop 命令来注入仅用于开发的需求。

这似乎是一座必须有人曾经走过的桥。有没有人指点一下?

【问题讨论】:

    标签: python node.js reactjs setuptools webpack


    【解决方案1】:

    我认为您最好将这些问题分成不同的构建步骤,如果我们稍微剖析您的过程,就会出现这些步骤(假设 nodenpmvirtualenv 已经安装在您的框)

    1. 在本地 virtualenv 中安装所需的 python 模块。
    2. 安装 webpack 和运行 webpack 脚本所需的 npm 模块。
    3. 运行 webpack 配置,以便在本地编译您的静态资产。

    这些步骤中的每一个都代表一个命令,该命令可以以 Makefile 结尾,或者只是一个简单的 shell 脚本(例如,如果您想坚持使用 python,请使用 Fabric),这样您就可以结束使用以下命令:

    • python-requirements
    • node-requirements
    • build-static
    • build -> python-requirements, node-requirements, build-static

    现在你可以随意运行这些命令了!例如,如果您正在部署,您将运行 build,它将连续运行每个步骤。

    【讨论】:

    • 我试图替换的解决方案就是这种东西。我真的希望我能在一个单元中捕获它。自从提出要求后,我实际上已经按照我的问题中的描述(子类化installsdistdevelop),但想看看是否有任何现有的指导逃脱了我的谷歌搜索。 distutilssetuptools 有很大的灵活性(同时也有很多漏洞),通常很难知道你是否以“正确”的方式做事。
    • 真正正确地打包一个 python 应用程序真的很棘手,virtualenv 中的--relocatable 标志是错误的并且被认为已弃用。查看 docker 以获得真正的可部署包装器。
    • 这里的基本思想是在docker build时间从私有PyPi服务器获取pip installed到docker容器中,所以我很熟悉。如果不出意外,感谢您确认这很棘手...... :)
    【解决方案2】:

    我们不是同一个部署系统,但寻求相同的东西:生产不需要节点,但使用 webpack 构建最终部署。我们正在使用 docker 来运行一个临时构建机器......

    构建器安装它需要的所有分发包,然后签出代码,调用setup.py 来构建自己,运行无数测试,最后将构建目录部署到 prod。

    1. 所以我把它留给了 docker 的配置,以确保通过将 curl... && apt-get 等添加到 Dockerfile 来安装 nodejsnpm

    2. 我对@9​​87654326@ 进行了子类化,并将run 命令修改为在运行时仅在命令行上运行npm installwebpack

    所以在setup.py

    setup(
        name='myapp',
        ...
        cmdclass={'sdist': MySdistCommand}
        ...)
    

    那么MySdistCommand就是

    from setuptools.command.sdist import sdist
    
    class MySdistCommand(sdist):
       def run(self):
           import subprocess
           subprocess.check_call(['npm', 'install'])
           subprocess.check_call(['./node_modules/.bin/webpack', '-p'])
           sdist.run(self)
    

    到目前为止,这似乎有效。当我们尝试将其部署到 prod 时(通过相当扭曲的 docker+puppet 系统),我会告诉你是否出现了怪癖。我不确定当它尝试真正运行时它会在哪个目录中找到自己,但它可以在 dev 中运行。 :-D

    【讨论】:

      【解决方案3】:

      抱歉(令人难以置信的迟到)答案。但是我遇到了同样的问题,并通过一个入口点解决了它,比如this。添加入口点允许我们添加一个脚本,该脚本将与您可能拥有的 webpack 配置位于同一文件夹中。

      因此,您可以只检查入口点,是否已发生构建,如果没有发生则构建 :) 或者,如果您必须在运行 setup.py 时进行构建,您可以在您的入口点,只需在您的 setup.py install develop 步骤上运行设置功能,然后使用自定义构建步骤来执行 npm install 或类似的东西。

      你需要的主要部分是:

      entry_points={
          "console_scripts": [
              "mywebpack=script_build:main",
          ]
      },
      

      我的脚本看起来像

      from os.path import exists, dirname, join
      from subprocess import Popen
      import sys
      
      
      def main():
      
          # Find the path of the script
          path = dirname(__file__)
      
          # Get the arguments that should pass to webpack
          args = sys.argv[1:]
      
          # Call webpack with the arguments passed to this program
          webpack_invocation = join(path, 'node_modules', '.bin', 'webpack')
          webpack_command = [webpack_invocation] + args
          process = Popen(webpack_invocation, cwd=path, shell=True)
          process.wait()
      
      
      if __name__ == "__main__":
          main()
      

      然后你可以从控制台使用它

      mywebpack <options>
      

      这将保证它使用本地安装的 webpack 版本:) 希望对您有所帮助!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-05-19
        • 2016-05-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-06-21
        相关资源
        最近更新 更多