4

I use nunjucks for templating the frontend in a python project. Nunjucks templates must be precompiled in production. I don't use extensions or asynchronous filters in the nunjucks templates. Rather than use grunt-task to listen for changes to my templates, I prefer to use the nunjucks-precompile command (offered via npm) to sweep the entire templates directory into templates.js.

The idea is to have the nunjucks-precompile --include ["\\.tmpl$"] path/to/templates > templates.js command execute within setup.py so I can simply piggyback our deployer scripts' regular execution.

I found a setuptools override and a distutils scripts argument might serve the right purpose, but I'm not so sure either is the simplest approach to execution.

Another approach is to use subprocess to execute the command directly within setup.py, but I've been cautioned against this (rather preemptively IMHO). I don't really deeply understand why not.

Any ideas? Affirmations? Confirmations?

Update (04/2015): - If you don't have the nunjucks-precompile command available, simply use Node Package Manager to install nunjucks like so:

$ npm install nunjucks
4

2 回答 2

6

请原谅快速的自我回答。我希望这可以帮助外面的人。现在我想分享这个,因为我已经制定了一个我满意的解决方案。

这是一个安全的解决方案,基于Peter Lamut 的文章。请注意,这不会子进程调用中使用 shell=True。您可以绕过 Python 部署系统上的 grunt-task 要求,也可以将其用于混淆和 JS 打包。

from setuptools import setup
from setuptools.command.install import install
import subprocess
import os

class CustomInstallCommand(install):
    """Custom install setup to help run shell commands (outside shell) before installation"""
    def run(self):
        dir_path = os.path.dirname(os.path.realpath(__file__))
        template_path = os.path.join(dir_path, 'src/path/to/templates')
        templatejs_path = os.path.join(dir_path, 'src/path/to/templates.js')
        templatejs = subprocess.check_output([
            'nunjucks-precompile',
            '--include',
            '["\\.tmpl$"]',
            template_path
        ])
        f = open(templatejs_path, 'w')
        f.write(templatejs)
        f.close()
        install.run(self)

setup(cmdclass={'install': CustomInstallCommand},
      ...
     )
于 2015-01-14T22:33:32.850 回答
-1

我认为这里的链接封装了您想要实现的目标。

于 2017-06-21T03:41:28.790 回答