在 Windows 上使用 Django 管道 browserify

Using Django pipeline browserify on Windows

我正在尝试关注 http://gregblogs.com/how-django-reactjs-and-browserify/。 我经历了一些困难才让 collectstatic 正常工作,但现在 运行 没有错误。然而,当我尝试加载包含我的反应组件的页面时,另一个编译过程开始(我认为 collectstatic 将预处理所有内容并且不需要编译 运行-time)。它需要一些 hack 才能使其立即运行 (https://github.com/j0hnsmith/django-pipeline-browserify/issues/14)。但即使在那个补丁之后,不幸的是这个编译错误。尽管命令现在看起来没问题:如果我执行

C:\Users\JohnSmith\node_modules\.bin\browserify.cmd -t babelify --deps C:\Users\JohnSmith\Documents\test\company\static\dashboard\js\react_test_dashboard_widget.browserify.js

它 运行 没有错误并产生依赖性 JSON。当 Django/Pipeline 作为子进程执行相同的命令时,它会出错说

Error: Cannot find module ' babelify' from 'C:\Users\JohnSmith\Documents\test\company

如何克服?

packages.json 片段

"dependencies": {
  "babel-cli": "^6.6.5",
  "babel-preset-es2015": "^6.6.0",
  "yuglify": "^0.1.4",
  "babelify": "^7.3.0",
  "browserify": "^13.0.1",
  "jquery": "^2.2.0",
  "react": "^15.2.0"
},
"devDependencies": {
  "babel-plugin-transform-class-properties": "^6.10.2",
  "babel-plugin-transform-react-jsx": "^6.8.0",
  "babel-preset-es2016": "^6.11.0",
  "babel-preset-react": "^6.11.1"
}

需求片段:

...
django-pipeline==1.6.6
django-pipeline-browserify==0.4.1
futures==3.0.5
...

一些设置(顺便说一句https://github.com/j0hnsmith/django-pipeline-browserify/issues/15):

PIPELINE["CSS_COMPRESSOR"] = "pipeline.compressors.NoopCompressor"
PIPELINE["JS_COMPRESSOR"] = "pipeline.compressors.NoopCompressor"
PIPELINE['SASS_BINARY'] = 'C:\Ruby22-x64\bin\sass.bat'
PIPELINE['BABEL_BINARY'] = 'c:\Users\JohnSmith\node_modules\.bin\babel.cmd'
PIPELINE['BROWSERIFY_BINARY'] = 'c:\Users\JohnSmith\node_modules\.bin\browserify.cmd'
PIPELINE_BROWSERIFY_BINARY = PIPELINE['BROWSERIFY_BINARY']

if DEBUG:
    PIPELINE["BROWSERIFY_ARGUMENTS"] = '-t babelify'
    PIPELINE_BROWSERIFY_ARGUMENTS = PIPELINE["BROWSERIFY_ARGUMENTS"]

(编译器需要最后一个!) 我的系统:Win 10,Python 2.7,Django 1.8

告诉我我还应该指定什么


更新:错误信息来自Node本身。请参阅下面的调用堆栈。请注意,我在这里尝试明确指定转换 JS 文件而不是模块名称(这在命令行中也适用,但在应用程序中效果不佳):

CompilerError: ['c:\Users\JohnSmith\node_modules\.bin\browserify.cmd', '-t  c:\Users\JohnSmith\Documents\test\node_modules\babelify\index.js', u'--deps C:\Users\JohnSmith\Documents\test\company\static\dashboard\js\react_test_dashboard_widget.browserify.js'] exit code 1
Error: Cannot find module '  c:\Users\JohnSmith\Documents\test\node_modules\babelify\index.js' from 'C:\Users\JohnSmith\Documents\test\company'
    at c:\Users\JohnSmith\node_modules\resolve\lib\async.js:46:17
    at process (c:\Users\JohnSmith\node_modules\resolve\lib\async.js:173:43)
    at ondir (c:\Users\JohnSmith\node_modules\resolve\lib\async.js:188:17)
    at load (c:\Users\JohnSmith\node_modules\resolve\lib\async.js:69:43)
    at onex (c:\Users\JohnSmith\node_modules\resolve\lib\async.js:92:31)
    at c:\Users\JohnSmith\node_modules\resolve\lib\async.js:22:47
    at FSReqWrap.oncomplete (fs.js:82:15)

这告诉我,问题可能是 Node 本身捕获了 t 参数,但没有将其传递给 browserify。这个问题肯定很重要:https://github.com/j0hnsmith/django-pipeline-browserify/issues/14

我覆盖了 https://github.com/j0hnsmith/django-pipeline-browserify/blob/master/pipeline_browserify/compiler.py#L55

    command = "%s %s %s --deps %s" % (
        getattr(settings, 'PIPELINE_BROWSERIFY_VARS', ''),
        getattr(settings, 'PIPELINE_BROWSERIFY_BINARY', '/usr/bin/env browserify'),
        getattr(settings, 'PIPELINE_BROWSERIFY_ARGUMENTS', ''),
        self.storage.path(infile),
    )

    command = (
        getattr(settings, 'PIPELINE_BROWSERIFY_BINARY', '/usr/bin/env browserify'),
        getattr(settings, 'PIPELINE_BROWSERIFY_ARGUMENTS', ''),
        "--deps %s" % self.storage.path(infile),
    )

'因为管道编译器代码需要元组。原代码接收到一个完整的字符串,然后把它分解成单个字符,认为它们都是参数,见https://github.com/jazzband/django-pipeline/blob/master/pipeline/compilers/init.py#L108

    argument_list = []
    for flattening_arg in command:
        if isinstance(flattening_arg, string_types):
            argument_list.append(flattening_arg)
        else:
            argument_list.extend(flattening_arg)

这会导致以后的灾难:

CompilerError: [Error 87] The parameter is incorrect

我的同事也试图让它在 OSX 上运行,但我们放弃了。我们只是将 is_outdated 短路为始终 return true。 is_outdated 无论如何在评论中包含一些信息 (https://github.com/j0hnsmith/django-pipeline-browserify/blob/master/pipeline_browserify/compiler.py#L41):

"WARNING: It seems to me that just generating the dependencies may take just as long as actually compiling, which would mean we would be better off just forcing a compile every time."

短路的方法是定义自己的编译器并注册那个。

PIPELINE['COMPILERS'] = (
'pipeline.compilers.sass.SASSCompiler',
# 'pipeline_browserify.compiler.BrowserifyCompiler',
'company.utils.compilers.BrowserifyCompiler',
...
)

在哪里

class BrowserifyCompiler(BrowserifyCompiler):
    def is_outdated(self, infile, outfile):
        return True

最后的评论和之前没有人抱怨过这个的纯粹事实让我想知道项目的状态...

https://github.com/j0hnsmith/django-pipeline-browserify/issues/14