brunch / brunch-with-chaplin

Boilerplate application for Brunch with Chaplin framework included.
paulmillr.com
280 stars 68 forks source link

can't load core nodejs modules #71

Closed reubano closed 11 years ago

reubano commented 11 years ago

When I try the following code in a my app as nodify.coffee...

vm = require 'vm'
fs = require 'fs'

module.exports = (path, context) ->
  data = fs.readFileSync(path)
  vm.runInNewContext(data, context, path)

I get an error Error: Cannot find module "vm"

$ echo $NODE_PATH
/opt/local/lib:/opt/local/lib/node_modules:

$ npm ls -g
/opt/local/lib

$ npm ls
brunch-with-chaplin-todomvc@0.0.1

$ coffee
coffee> vm = require 'vm'
{ [Function: Script]
  Script: [Circular],
  createScript: [Function],
  createContext: [Function],
  runInContext: [Function],
  runInThisContext: [Function],
  runInNewContext: [Function] }
coffee> 

$ node -pe "var vm = require('vm');"
undefined

mac osx 10.7.5 brunch 1.5.3 node v0.8.9 npm 1.1.61

Any idea what im doing wrong??

paulmillr commented 11 years ago

what is nodify.coffee? what exactly are you doing here? are you putting this code in app directory?

reubano commented 11 years ago

I wan't to load nvd3.js but since it isn't in npm I searched on stackoverflow and came up with the code you see above. Yes, the nodify.coffee file is in the app dir. Here is my current solution...

app
|--assets
|    `--nvd3
|--nodify.coffee
|--nvd3.coffee
|--nvd3util.coffee
|--views
|    `--graph-view.coffee
|--other-todo-mvc-folders...
|--other-todo-mvc-files...

nodify.coffee

vm = require 'vm'
fs = require 'fs'

module.exports = (path, context) ->
  data = fs.readFileSync(path)
  vm.runInNewContext(data, context, path)

nvd3.coffee

nodify = require 'nodify'

module.exports = ->
    nodify('nvd3/lib/d3.v2.js')
    nodify('nvd3/lib/d3.v2.js')
    nodify('nvd3/nv.d3.js')
    nodify('nvd3/src/utils.js')
    nodify('nvd3/src/tooltip.js')
    nodify('nvd3/src/models/legend.js')
    nodify('nvd3/src/models/axis.js')
    nodify('nvd3/src/models/multiBarHorizontal.js')
    nodify('nvd3/src/models/multiBarHorizontalChart.js')

nvd3util.coffee

nvd3 = require 'nvd3'
moment = require 'moment'
_ = require 'underscore'

myFormat = nvd3.d3.time.format("%b %d, %Y %X %p")
dateFormat = nvd3.d3.time.format("%m/%d/%y")
minTime = 7.5
maxTime = 18.5
maxDur = 4 * 60
chartRange = [minTime * 60, maxTime * 60]
retLab = (d) -> d.label
retVal = (d) -> d.value
dispatchCB = (e) -> nvd3.nv.log('New State:', JSON.stringify(e))

formatMinutes = (d) ->
    time = nvd3.d3.time.format("%I:%M %p")(new Date(2013, 0, 1, 0, d))
    if time.substr(0,1) == '0' then time.substr(1) else time

dateRange = (startDate, endDate) ->
    newDate = moment(startDate)
    newDate.add('d', 1) while newDate <= endDate

loadCSV = ->
    alert 'loading...'
    grouped = nvd3.d3.csv("db/sales.csv", groupData(data))
    formatted = (formatGrouped(obj, i) for i, obj of grouped)
    res = (loadData(f.i, f.obj, f.missing) for f in formatted)
    chart = makeChart(res.title, res.data)
    nvd3.nv.addGraph(chart)

formatData = (d) ->
    startDate = nvd3.d3.time.format("%m/%d/%y")(myFormat.parse(d.start))
    dur = (myFormat.parse(d.end) - myFormat.parse(d.start)) / (1000 * 60)
    start = (myFormat.parse(d.start) - dateFormat.parse(startDate)) / (1000 * 60)
    duration = if (dur > 0 && dur < maxDur) then dur else 0
    date: startDate, employee: d.employee_id, start: start, duration: duration

formatGrouped = (obj, i) ->
    string = 'MM/DD/YY'
    date = moment(obj[0].date, string)
    month = date.month()
    year = date.year()
    startDate = moment([year, month, 1])
    endDate = moment([year, month, 0]).add('M', 1)
    formatAllDates = (d) -> d.format(string)

    allDates = _.map(dateRange(startDate, endDate), formatAllDates(d))
    myDates = _.pluck(obj, 'date')
    missing = _.difference(allDates, myDates)
    i: i, obj: obj, missing: missing

groupData = (data) ->
    rows = data.map(formatData)
    grouped = _.groupBy(rows, 'employee')

loadData = (title, rows, missing) ->
    endValues = (label: obj.date, value: obj.start for obj in rows)
    durValues = (label: obj.date, value: obj.duration for obj in rows)
    endValues = (label: obj, value: 0 for obj in missing)
    durValues = (label: obj, value: 0 for obj in missing)
    endValues = _.sortBy(endValues, 'label')
    durValues = _.sortBy(durValues, 'label')
    data[0] = key: 'End', values: endValues
    data[1] = key: 'Duration', values: durValues
    title: title, data: data

makeChart = (title, data) ->
    selection = '#' + title +'.view .chart svg'

    chart = nvd3.nv.models.multiBarHorizontalChart()
        .x(retLab)
        .y(retVal)
        .forceY(chartRange)
        .yDomain(chartRange)
        .margin({top: 0, right: 110, bottom: 30, left: 80})
        .stacked(true)
        .showLegend(false)
        .barColor([nvd3.d3.rgb('steelblue')])
        .showControls(false)

    i = maxTime - 1
    tickInterval = while i -= 1
        (minTime + i + 1) * 60

    chart.yAxis
        .tickValues(tickInterval)
        .tickFormat(formatMinutes)

    nvd3.d3.select(selection)
        .datum(data)
        .transition().duration(0)
        .call(chart)

    nvd3.nv.utils.windowResize(chart.update)
    chart.dispatch.on('stateChange', dispatchCB(e))
    chart.multibar.yScale().clamp(true)
    chart

module.exports = loadCSV

graph-view.coffee

nvd3util = require '../nvd3util'
View = require 'views/base/view'
template = require 'views/templates/graph'

module.exports = class GraphView extends View
  template: template

  initialize: ->
    super
    @modelBind 'change', @render
    @delegate 'click', '.icon-remove-sign', @destroy
    @delegate 'dblclick', 'label', @edit
    @delegate 'keypress', '.edit', @save
    @delegate 'blur', '.edit', @save

  render: =>
    super
    nvd3util.loadCSV()

  destroy: =>
    @model.destroy()

  edit: =>
    @$el.addClass 'editing'
    @$('.edit').focus()

  save: (event) =>
    ENTER_KEY = 13
    title = $(event.currentTarget).val().trim()
    return @model.destroy() unless title
    return if event.type is 'keypress' and event.keyCode isnt ENTER_KEY
    @model.save {title}
    @$el.removeClass 'editing'
paulmillr commented 11 years ago

You’re probably expecting that brunch interoperates with node in apps. It don’t. Brunch is not supposed to run node modules, yep — it’s HTML5 app builder without any ties to node.

You can still launch custom node.js servers with brunch watch -s, though.

reubano commented 11 years ago

Hmm, that sucks.... so is my best option to rewrite nvd3 as a node module so I can import it via package.json or is there something else brunch like that will let me load core node modules??

reubano commented 11 years ago

Or pick a d3 alternative that is in npm?

paulmillr commented 11 years ago

I suggest you to look at browserify, it allows packing node modules as browser modules.

reubano commented 11 years ago

awesome! thanks, I'll give it a try.

On Tue, Apr 30, 2013 at 11:28 PM, Paul Miller notifications@github.comwrote:

I suggest you to look at browserify, it allows packing node modules as browser modules.

— Reply to this email directly or view it on GitHubhttps://github.com/paulmillr/brunch-with-chaplin/issues/71#issuecomment-17252014 .


Reuben Cummings Arusha, Tanzania reubano@gmail.com

+255 756 477 319 (vodacom) +255 789 477 319 (airtel) +1 (234) 738-2266 (u.s.)

skype/twitter/linkedin - reubano

reubano commented 11 years ago

I been reading quite a bit and like what browserify has to offer. I'm a little confused though about how to implement it. Can I add it to my brunch app like their examples or do I have to find a new framework to use it in/with? All of what I've read about browserify, brunch, ender, hem... makes it seem like it is a mutually exclusive choice.

paulmillr commented 11 years ago

they’re mutually exclusive, that’s right.

it depends on what you need from application. there are a lot of tools that has nice compat with each other

reubano commented 11 years ago

In case anyone is wondering, here is what I wound up doing. You can't access node modules from the client so that made the above coffee-script files moot. I put the nvd3 source files in the app/assets folder and modified index.html as so

    .......
        <footer>
            <script src="nvd3/lib/d3.v2.js"></script>
            <script src="nvd3/nv.d3.js"></script>
            <script src="nvd3/src/utils.js"></script>
            <script src="nvd3/src/tooltip.js"></script>
            <script src="nvd3/src/models/legend.js"></script>
            <script src="nvd3/src/models/axis.js"></script>
            <script src="nvd3/src/models/multiBarHorizontal.js"></script>
            <script src="nvd3/src/models/multiBarHorizontalChart.js"></script>
            <script src="nvd3/stream_layers.js"></script>
            <script src="nvd3/gen-chart.js"></script>
        </footer>
    .......

gen-chart.js is the code that renders the chart via nvd3 and is equivalent to nvd3util.coffee.

The reason I didn't put nvd3 in the vendors folder is because the loadCSV function of gen-chart.js doesn't load that way. And if I move all of the other nvd3 files except gen-chart.js into the vendors folder, it errors about not being able to find nvd3 functions. Oddly enough it has no problem finding underscore and moment so those remained in the vendors folder.

See my other issue for bootstrapping the collection on initial page load.