1

I'm trying to follow http://gregblogs.com/how-django-reactjs-and-browserify/. I went through some hoops to get collectstatic working but it runs without error now. However when I try to load the page which contains my react component, another compilation process kicks in (I thought collectstatic will pre-process everything and nothing will have to compile run-time). It requires some hack to make it work right now (https://github.com/j0hnsmith/django-pipeline-browserify/issues/14). But even after that patch, unfortunately this compilation errors out. Although the command seems OK now: if I execute

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

it runs without an error and produces a dependency JSON. When the same command is executed as a sub-process by Django/Pipeline, it errors out saying

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

How to overcome that?

packages.json snippet

"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"
}

requirements snippet:

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

Some settings (BTW 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"]

(last one was needed for compilers!) My system: Win 10, Python 2.7, Django 1.8

Tell me what else should I specify


Update: the error message comes from Node itself. See the call stack below. Note, that here I tried to explicitly specify the transformation JS file instead of a module name (this also works well from the command line but not well in the app):

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)

This advises me that maybe the problem is that Node itself captures the t parameter and doesn't pass it to browserify. For sure this issue might be crucial: https://github.com/j0hnsmith/django-pipeline-browserify/issues/14

I overrode the 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),
    )

with

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

'cause the pipeline compiler code expects tuples. By he original code it received one complete string, but then it dissected it to individual characters, thinking that all of them are arguments, see 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)

This would lead to a disaster later:

CompilerError: [Error 87] The parameter is incorrect
Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
Csaba Toth
  • 10,021
  • 5
  • 75
  • 121

1 Answers1

0

My co-worker tried to get it working on OSX too, but we gave up. We just short-circuited the is_outdated to always return true. The is_outdated contains some info in the comments about that anyway (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."

The way to shortcircuit is to define your own compiler and register that one.

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

Where

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

Last comment and the sheer fact that noone complained about this before makes me wonder about the state of the project...

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

Csaba Toth
  • 10,021
  • 5
  • 75
  • 121
  • I am following the same tutorial and cannot seem to get the collectstatic working. I am getting the following error: "django/contrib/staticfiles/management/commands/collectstatic.py", line 122, in collect for original_path, processed_path, processed in processor: File "pipeline/storage.py", line 24, in post_process output_file = package.output_filename File "pipeline/packager.py", line 44, in output_filename return self.config.get('output_filename') AttributeError: 'tuple' object has no attribute 'get'. Wondering if you got a similar error? – Rads Jul 26 '16 at 07:35
  • @Rads that doesn't ring a bell. I suspect that your pipeline configuration is faulty. This (when you supply a tuple or don't get a tuple when expected) can be cause even by a missing comma or extra comma. This rather looks like an extra comma somewhere. Post your configuration in a question and put the link here so I can follow it. Or just put it into a Gist and tell the link. – Csaba Toth Jul 28 '16 at 19:10
  • @Rads Is `browserify` involved in your case or you only have `pipeline`? I already have a working pipeline configuration when I introduced `browserify` into the equation. – Csaba Toth Jul 28 '16 at 19:11