【问题标题】:Any modification of a .less file breaks Flask app, resulting in Program file not found: lessc对 .less 文件的任何修改都会破坏 Flask 应用程序,导致找不到程序文件:lessc
【发布时间】:2020-05-21 18:41:56
【问题描述】:

我遇到的问题是,在修改某个 .less 文件后,使用 flask_assets 的 Flask 应用程序无法找到 lessc,即使将其更改回原始文件也无济于事。

我一直在尝试使用本教程来了解如何使用蓝图来组织 Flask 应用程序:https://hackersandslackers.com/flask-blueprints/

应用结构

├── application
│   ├── assets.py
│   ├── home
│   │   ├── home.py
│   │   ├── __pycache__
│   │   │   └── home.cpython-38.pyc
│   │   ├── static
│   │   │   └── less
│   │   │       ├── home.less
│   │   │       └── variables.less
│   │   └── templates
│   │       └── index.jinja2
│   ├── __init__.py
│   ├── __pycache__
│   │   ├── assets.cpython-38.pyc
│   │   └── __init__.cpython-38.pyc
│   ├── static
│   │   ├── dist
│   │   │   └── css
│   │   │       ├── home.css
│   │   │       ├── products.css
│   │   │       ├── profile.css
│   │   │       └── style.css
│   │   ├── img
│   │   │   ├── avatar.png
│   │   │   ├── favicon.png
│   │   │   └── logo.png
│   │   └── src
│   │       └── less
│   │           ├── nav.less
│   │           ├── style.less
│   │           └── variables.less
│   └── templates
│       ├── analytics.jinja2
│       ├── layout.jinja2
│       └── navigation.jinja2
└── wsgi.py

初始化.py

"""Initialize Flask app."""
from flask import Flask
from flask_assets import Environment


def create_app():
    """Create Flask application."""
    app = Flask(__name__, instance_relative_config=False)
    app.config.from_object('config.Config')
    assets = Environment()
    assets.init_app(app)

    with app.app_context():
        # Import parts of our application
        from .home import home
        from .assets import compile_static_assets

        # Register Blueprints
        app.register_blueprint(home.home_bp)

        # Compile static assets
        compile_static_assets(assets)

        return app
        ```



        assets.py
        ```
        from flask import current_app as app
from flask_assets import Bundle


def compile_static_assets(assets):
    assets.auto_build = True
    assets.debug = False
    common_less_bundle = Bundle('src/less/*.less',
                                filters='less,cssmin',
                                output='dist/css/style.css',
                                extra={'rel': 'stylesheet/less'})
    home_less_bundle = Bundle('home_bp/less/home.less',
                              filters='less,cssmin',
                              output='dist/css/home.css',
                              extra={'rel': 'stylesheet/less'})

    assets.register('common_less_bundle', common_less_bundle)
    assets.register('home_less_bundle', home_less_bundle)
    if app.config['ENV'] == 'development':  # Only rebuild bundles in development
        common_less_bundle.build()
        home_less_bundle.build()
    return assets

home.py

"""General page routes."""
from flask import Blueprint, render_template
from flask import current_app as app

# Blueprint Configuration
home_bp = Blueprint('home_bp', __name__,
                    template_folder='templates',
                    static_folder='static')


@home_bp.route('/', methods=['GET'])
def home():
    """Homepage."""
    products ="example"
    return render_template('index.jinja2',
                           title='Flask Blueprint Demo',
                           subtitle='Demonstration of Flask blueprints in action.',
                           template='home-template',
                           products=products)

还有问题文件home.less

@import 'variables.less';

.home-template {

  &.page {
    .products {
      display: none !important;
    }
  }

  .container {
    .resource-links {
      margin-top: 10px;

      .resource-link {
        margin: 4px 0;
        color: #8a91a7;
        line-height: 1;
      }
    }

    .products {
      display: flex;
      justify-content: space-between;
      flex-wrap: wrap;
      margin-top: 30px;

      .product-preview {
        padding: 2%;
        box-shadow: 0 0 5px rgba(65, 67, 144, 0.15);
        max-width: 28%;
        width: 30%;
        background: white;
        margin-bottom: 20px;
        display: block;
        text-align: center;
        transition: @transition;

        &:hover {
          background: #5dbad7;
          color: white !important;
          opacity: 1;

          * {
            color: white !important;
          }
        }

        .product-image {
          height: 110px;
          margin: 0 auto 20px;
          display: block;
          @media (max-width: 600px) {
            width: 90%;
            height: unset;
          }
        }

        .name {
          -webkit-line-clamp: 2;
          -webkit-box-orient: vertical;
          display: -webkit-box;
          width: -webkit-fill-available;
          width: -moz-available;
          width: stretch;
          overflow: hidden;
          text-overflow: ellipsis;
          font-weight: 500;
          font-size: .9em;
          height: 42px;
        }

        .price {
          color: #5f6988;
          margin-top: 5px;
          font-size: 1.1em;
          font-weight: 600;
        }
      }
    }
  }

  h2 {
    margin-bottom: 0 !important;
  }
}

home.less 从 git 下载新粘贴到我的简化版本时,应用程序按预期运行。

$ python3 wsgi.py
 * Serving Flask app "application" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: on
 * Running on http://0.0.0.0:5001/ (Press CTRL+C to quit)
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 213-702-582
127.0.0.1 - - [21/May/2020 14:26:01] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [21/May/2020 14:26:02] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [21/May/2020 14:26:02] "GET /static/dist/css/home.css?99706b81 HTTP/1.1" 304 -
127.0.0.1 - - [21/May/2020 14:26:02] "GET /static/img/logo.png HTTP/1.1" 304 -
127.0.0.1 - - [21/May/2020 14:26:02] "GET /favicon.ico HTTP/1.1" 404 -

现在,真正让我感到奇怪的是,如果我对home.less 进行任何 修改,即使只是添加一个空格、保存、删除空格,然后再次保存,@987654334找不到@过滤器:

 * Serving Flask app "application" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: on
 * Running on http://0.0.0.0:5001/ (Press CTRL+C to quit)
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 213-702-582
127.0.0.1 - - [21/May/2020 14:28:09] "GET / HTTP/1.1" 500 -
Traceback (most recent call last):
  File "/home/james/.local/lib/python3.8/site-packages/webassets/filter/__init__.py", line 510, in subprocess
    proc = subprocess.Popen(
  File "/usr/lib/python3.8/subprocess.py", line 854, in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
  File "/usr/lib/python3.8/subprocess.py", line 1702, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: 'lessc'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3.8/site-packages/flask/app.py", line 2464, in __call__
    return self.wsgi_app(environ, start_response)
  File "/usr/lib/python3.8/site-packages/flask/app.py", line 2450, in wsgi_app
    response = self.handle_exception(e)
  File "/usr/lib/python3.8/site-packages/flask/app.py", line 1867, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/lib/python3.8/site-packages/flask/_compat.py", line 39, in reraise
    raise value
  File "/usr/lib/python3.8/site-packages/flask/app.py", line 2447, in wsgi_app
    response = self.full_dispatch_request()
  File "/usr/lib/python3.8/site-packages/flask/app.py", line 1952, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/usr/lib/python3.8/site-packages/flask/app.py", line 1821, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/lib/python3.8/site-packages/flask/_compat.py", line 39, in reraise
    raise value
  File "/usr/lib/python3.8/site-packages/flask/app.py", line 1950, in full_dispatch_request
    rv = self.dispatch_request()
  File "/usr/lib/python3.8/site-packages/flask/app.py", line 1936, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/home/james/Downloads/flask-blueprint-tutorial-master_reduced/application/home/home.py", line 15, in home
    return render_template('index.jinja2',
  File "/usr/lib/python3.8/site-packages/flask/templating.py", line 137, in render_template
    return _render(
  File "/usr/lib/python3.8/site-packages/flask/templating.py", line 120, in _render
    rv = template.render(context)
  File "/usr/lib/python3.8/site-packages/jinja2/environment.py", line 1090, in render
    self.environment.handle_exception()
  File "/usr/lib/python3.8/site-packages/jinja2/environment.py", line 832, in handle_exception
    reraise(*rewrite_traceback_stack(source=source))
  File "/usr/lib/python3.8/site-packages/jinja2/_compat.py", line 28, in reraise
    raise value.with_traceback(tb)
  File "/home/james/Downloads/flask-blueprint-tutorial-master_reduced/application/home/templates/index.jinja2", line 1, in top-level template code
    {% extends "layout.jinja2" %}
  File "/home/james/Downloads/flask-blueprint-tutorial-master_reduced/application/templates/layout.jinja2", line 9, in top-level template code
    {% block pagestyles %}{% endblock %}
  File "/home/james/Downloads/flask-blueprint-tutorial-master_reduced/application/home/templates/index.jinja2", line 4, in block "pagestyles"
    {% assets "home_less_bundle" %}
  File "/home/james/.local/lib/python3.8/site-packages/webassets/ext/jinja2.py", line 187, in _render_assets
    urls = bundle.urls(calculate_sri=True)
  File "/home/james/.local/lib/python3.8/site-packages/webassets/bundle.py", line 833, in urls
    urls.extend(bundle._urls(new_ctx, extra_filters, *args, **kwargs))
  File "/home/james/.local/lib/python3.8/site-packages/webassets/bundle.py", line 767, in _urls
    self._build(ctx, extra_filters=extra_filters, force=False,
  File "/home/james/.local/lib/python3.8/site-packages/webassets/bundle.py", line 618, in _build
    hunk = self._merge_and_apply(
  File "/home/james/.local/lib/python3.8/site-packages/webassets/bundle.py", line 543, in _merge_and_apply
    hunk = filtertool.apply(hunk, filters_to_run, 'input',
  File "/home/james/.local/lib/python3.8/site-packages/webassets/merge.py", line 280, in apply
    return self._wrap_cache(key, func)
  File "/home/james/.local/lib/python3.8/site-packages/webassets/merge.py", line 222, in _wrap_cache
    content = func().getvalue()
  File "/home/james/.local/lib/python3.8/site-packages/webassets/merge.py", line 255, in func
    getattr(filter, type)(data, out, **kwargs_final)
  File "/home/james/.local/lib/python3.8/site-packages/webassets/filter/less.py", line 139, in input
    self._apply_less(_in, out, source_path)
  File "/home/james/.local/lib/python3.8/site-packages/webassets/filter/less.py", line 131, in _apply_less
    self.subprocess(args, out, in_)
  File "/home/james/.local/lib/python3.8/site-packages/webassets/filter/__init__.py", line 520, in subprocess
    raise FilterError('Program file not found: %s.' % argv[0])
webassets.exceptions.FilterError: Program file not found: lessc.
127.0.0.1 - - [21/May/2020 14:28:10] "GET / HTTP/1.1" 500 -
Traceback (most recent call last):
  File "/home/james/.local/lib/python3.8/site-packages/webassets/filter/__init__.py", line 510, in subprocess
    proc = subprocess.Popen(
  File "/usr/lib/python3.8/subprocess.py", line 854, in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
  File "/usr/lib/python3.8/subprocess.py", line 1702, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: 'lessc'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3.8/site-packages/flask/app.py", line 2464, in __call__
    return self.wsgi_app(environ, start_response)
  File "/usr/lib/python3.8/site-packages/flask/app.py", line 2450, in wsgi_app
    response = self.handle_exception(e)
  File "/usr/lib/python3.8/site-packages/flask/app.py", line 1867, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/lib/python3.8/site-packages/flask/_compat.py", line 39, in reraise
    raise value
  File "/usr/lib/python3.8/site-packages/flask/app.py", line 2447, in wsgi_app
    response = self.full_dispatch_request()
  File "/usr/lib/python3.8/site-packages/flask/app.py", line 1952, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/usr/lib/python3.8/site-packages/flask/app.py", line 1821, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/lib/python3.8/site-packages/flask/_compat.py", line 39, in reraise
    raise value
  File "/usr/lib/python3.8/site-packages/flask/app.py", line 1950, in full_dispatch_request
    rv = self.dispatch_request()
  File "/usr/lib/python3.8/site-packages/flask/app.py", line 1936, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/home/james/Downloads/flask-blueprint-tutorial-master_reduced/application/home/home.py", line 15, in home
    return render_template('index.jinja2',
  File "/usr/lib/python3.8/site-packages/flask/templating.py", line 137, in render_template
    return _render(
  File "/usr/lib/python3.8/site-packages/flask/templating.py", line 120, in _render
    rv = template.render(context)
  File "/usr/lib/python3.8/site-packages/jinja2/environment.py", line 1090, in render
    self.environment.handle_exception()
  File "/usr/lib/python3.8/site-packages/jinja2/environment.py", line 832, in handle_exception
    reraise(*rewrite_traceback_stack(source=source))
  File "/usr/lib/python3.8/site-packages/jinja2/_compat.py", line 28, in reraise
    raise value.with_traceback(tb)
  File "/home/james/Downloads/flask-blueprint-tutorial-master_reduced/application/home/templates/index.jinja2", line 1, in top-level template code
    {% extends "layout.jinja2" %}
  File "/home/james/Downloads/flask-blueprint-tutorial-master_reduced/application/templates/layout.jinja2", line 9, in top-level template code
    {% block pagestyles %}{% endblock %}
  File "/home/james/Downloads/flask-blueprint-tutorial-master_reduced/application/home/templates/index.jinja2", line 4, in block "pagestyles"
    {% assets "home_less_bundle" %}
  File "/home/james/.local/lib/python3.8/site-packages/webassets/ext/jinja2.py", line 187, in _render_assets
    urls = bundle.urls(calculate_sri=True)
  File "/home/james/.local/lib/python3.8/site-packages/webassets/bundle.py", line 833, in urls
    urls.extend(bundle._urls(new_ctx, extra_filters, *args, **kwargs))
  File "/home/james/.local/lib/python3.8/site-packages/webassets/bundle.py", line 767, in _urls
    self._build(ctx, extra_filters=extra_filters, force=False,
  File "/home/james/.local/lib/python3.8/site-packages/webassets/bundle.py", line 618, in _build
    hunk = self._merge_and_apply(
  File "/home/james/.local/lib/python3.8/site-packages/webassets/bundle.py", line 543, in _merge_and_apply
    hunk = filtertool.apply(hunk, filters_to_run, 'input',
  File "/home/james/.local/lib/python3.8/site-packages/webassets/merge.py", line 280, in apply
    return self._wrap_cache(key, func)
  File "/home/james/.local/lib/python3.8/site-packages/webassets/merge.py", line 222, in _wrap_cache
    content = func().getvalue()
  File "/home/james/.local/lib/python3.8/site-packages/webassets/merge.py", line 255, in func
    getattr(filter, type)(data, out, **kwargs_final)
  File "/home/james/.local/lib/python3.8/site-packages/webassets/filter/less.py", line 139, in input
    self._apply_less(_in, out, source_path)
  File "/home/james/.local/lib/python3.8/site-packages/webassets/filter/less.py", line 131, in _apply_less
    self.subprocess(args, out, in_)
  File "/home/james/.local/lib/python3.8/site-packages/webassets/filter/__init__.py", line 520, in subprocess
    raise FilterError('Program file not found: %s.' % argv[0])
webassets.exceptions.FilterError: Program file not found: lessc.

这里会发生什么? 起初我认为这可能是缓存问题,但删除 __pycache__ 并没有帮助。

【问题讨论】:

  • 你需要安装lessc,这样你就可以编译你的less文件了
  • 那为什么它第一次会奏效呢?为什么在 .less 文件中添加然后删除空格会导致找不到lessc(或者为什么之前没有lessc 可以工作)?
  • 我没有这些答案......也许最初它使用不同的方法来构建更少 -> css,或者最初 css 确实存在(但你的 ide 或其他东西隐藏了它并且仅向您显示 less 文件)...您是否使用 babel 直接在 html 中将 less 转换为 css?或者你是否包括css文件?但是错误消息清楚地表明它找不到lessc(它用来编译less -> css)
  • 我建议阅读webassets.readthedocs.io/en/latest 的文档,因为这看起来像是在尝试编译更少的文件
  • 但是,无论我如何处理 python 和 css 文件,这都不应该改变,对吧?我不明白为什么重新保存文件会影响 lessc 是否被发现。是否有可能在它起作用的情况下,甚至没有调用lessc?

标签: python python-3.x flask flask-assets lessc


【解决方案1】:

好的,好吧,我找到了一个解决方案,但我真的不明白它为什么会起作用。

如果我更改 assets.py 以显式创建环境,对 home.less 的细微修改将不再导致无法找到 lessc。

新资产.py

from flask import Flask, current_app as app
from flask_assets import Environment, Bundle


def compile_static_assets(assets):
    app = Flask(__name__)
    assets = Environment(app)
    assets.auto_build = True
    assets.debug = False
    common_less_bundle = Bundle('src/less/*.less',
                                filters='less,cssmin',
                                output='dist/css/style.css',
                                extra={'rel': 'stylesheet/less'})
    home_less_bundle = Bundle('home_bp/less/home.less',
                              filters='less,cssmin',
                              output='dist/css/home.css',
                              extra={'rel': 'stylesheet/less'})

    assets.register('common_less_bundle', common_less_bundle)
    assets.register('home_less_bundle', home_less_bundle)
    if app.config['ENV'] == 'development':  # Only rebuild bundles in development
        common_less_bundle.build()
        home_less_bundle.build()
    return assets

对我来说,使用加载正确的包来实例化环境对于less 过滤器的工作是必要的。但我仍然感到困惑的是,这只是在从 less.css 添加(然后删除)一个空格后才成为问题。

我想我一定不明白 flask_assets 如何应用过滤器的管道。我看过文档,但对我来说并不明显。

【讨论】:

    猜你喜欢
    • 2018-07-17
    • 1970-01-01
    • 2012-04-05
    • 1970-01-01
    • 1970-01-01
    • 2019-07-20
    • 2014-10-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多