I'm the maintainer of the following library on github: https://github.com/edi9999/docxtemplater/blob/master/coffee/docxgen.coffee

I want to maintain a library that works on node and in the browser, however I don't want to have to update two separate repositories.

The ugliest code looks like this:

root= global ? window
env= if global? then 'node' else 'browser'

if env=='node'
    global.http= require('http')
    global.https= require('https')
    global.fs= require('fs')
    global.vm = require('vm')
    global.DOMParser = require('xmldom').DOMParser
    global.XMLSerializer= require('xmldom').XMLSerializer
    global.PNG= require('../vendor/pngjs/png-node')
    global.url= require('url')

    ["grid.js","version.js","detector.js","formatinf.js","errorlevel.js","bitmat.js","datablock.js","bmparser.js","datamask.js","rsdecoder.js","gf256poly.js","gf256.js","decoder.js","qrcode.js","findpat.js","alignpat.js","databr.js"].forEach (file) ->
        vm.runInThisContext(global.fs.readFileSync(__dirname + '/../vendor/jsqrcode/' + file), file)
    ['jszip.js'].forEach (file) ->
        vm.runInThisContext(global.fs.readFileSync(__dirname + '/../vendor/jszip2.0/dist/' + file), file)

output: (options={}) ->
        if !options.download? then options.download=true
        if !options.name? then options.name="output.docx"
        if !options.type? then options.type="base64"
        result= @zip.generate({type:options.type})
        if options.download
            if env=='node'
                fs.writeFile process.cwd()+'/'+options.name, result, 'base64', (err) ->
                    if err then throw err
                #Be aware that data-uri doesn't work for too big files: More Info http://stackoverflow.com/questions/17082286/getting-max-data-uri-size-in-javascript
                document.location.href= "data:application/vnd.openxmlformats-officedocument.wordprocessingml.document;base64,#{result}"

As you can see, they is a lot of specific node/browser js code, and I would like to remove that from the main code, however, I can't find an easy way to do this.

Any idea ?



Are you against maintaining 2 repositories or maintaining 2 main files? Honestly I would have 2 main files with a third file ( or more ) containing routines that are host agnostic.

docxgen_node.coffee , docxgen_www.coffee and docxgen_common.coffee

It sounds uncool, but I think in the end, this should be easiest on the eyes.

Other, than that, I would take the opportunity to use that massive ( ugly ) string array to document why you need each library and maybe which versions are usable for your repository:

var requiredLibraries = [
  "grid.js",     //Use xyz version, uses abc features
  "version.js",  //...
  "detector.js", //..

requiredLibraries.forEach (file) ->
    vm.runInThisContext(global.fs.readFileSync(__dirname + '/../vendor/jsqrcode/' + file), file)
  • \$\begingroup\$ Maintaning two specific files and one host agnostic is ok I think \$\endgroup\$ – edi9999 Mar 27 '14 at 15:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.