Skip to content

Instantly share code, notes, and snippets.

@domenic
Created May 25, 2012 21:03

Revisions

  1. domenic revised this gist Oct 2, 2012. 1 changed file with 7 additions and 12 deletions.
    19 changes: 7 additions & 12 deletions portable-node.md
    Original file line number Diff line number Diff line change
    @@ -1,8 +1,3 @@
    Title: How to Write Portable Node.js Code
    Author: Domenic Denicola
    Date: 2012-10-02T18:00:00Z
    Node: v0.8.11

    Node.js core does its best to treat every platform equally. Even if most Node developers use OS X day to day, some use
    Windows, and most everyone deploys to Linux or Solaris. So it's important to keep your code portable between platforms,
    whether you're writing a library or an application.
    @@ -41,14 +36,14 @@ program on Windows. Always [guard such calls][winston] with a conditional.
    The [`fs.watchFile`][watchFile] API is not sufficiently cross-platform, and is recommended against in the docs because
    of it. You [should][codex-watch] use [`fs.watch`][watch] instead.

    The [child_process][] module requires care cross-platform. In particular, `spawn` and `execFile` do not execute in a
    The [child_process module][] requires care cross-platform. In particular, `spawn` and `execFile` do not execute in a
    shell, which means that on Windows only `.exe` files will run. This is rather problematic, as many cross-platform
    binaries are included on Windows as `.cmd` or `.bat` files, [among them Git][npm-git], [CouchDB][npm-www-couchdb], and
    many others. So if you're using these APIs, things will likely work great on other platforms. But when you tell your
    many others. So if you're using these APIs, things will likely work great on OS X, Linux, etc. But when you tell your
    users “just install the Git build for Windows, and make sure it's in your path!” that ends up not being sufficient.
    There is [talk][node-bug] of fixing this behavior in libuv, but that's still tentative. In the meantime, if you don't
    need to stream your output, `exec` works great. Otherwise you'll need [branching logic][npm-www-couchdb] to take care
    of the Windows case.
    need to stream your output, `exec` works well. Otherwise you'll need [branching logic][npm-www-couchdb] to take care
    of Windows.

    A final edge-case comes when using named sockets, e.g. with `net.connect`. On Unix, simple filenames suffice, but on
    Windows, they must conform to a [bizarre syntax][pipe-names]. There's not really a better solution for this than
    @@ -59,7 +54,7 @@ Windows, they must conform to a [bizarre syntax][pipe-names]. There's not really
    [watchFile]: http://nodejs.org/docs/latest/api/fs.html#fs_fs_watchfile_filename_options_listener
    [codex-watch]: https://github.com/logicalparadox/codex/commit/be2fe18f5561f7bbd3bd0099bb47f7e58c23638d
    [watch]: http://nodejs.org/docs/latest/api/fs.html#fs_fs_watch_filename_options_listener
    [child_process]: http://nodejs.org/api/child_process.html
    [child_process module]: http://nodejs.org/api/child_process.html
    [npm-git]: https://github.com/isaacs/npm/issues/2333
    [npm-www-couchdb]: https://github.com/isaacs/npm-www/blob/fd3a96e861989338676937736599598f7c0fde8f/dev/go.js#L22-27
    [node-bug]: https://github.com/joyent/node/issues/2318
    @@ -68,15 +63,15 @@ Windows, they must conform to a [bizarre syntax][pipe-names]. There's not really

    ## Being Windows-Developer Friendly

    One of the most egregious problems with many projects is their excessive use of Unix Makefiles. Windows does not have a
    One of the most egregious problems with many projects is their unnecessary use of Unix Makefiles. Windows does not have a
    `make` command, so the tasks stored in these files are entirely inaccessible to Windows users who might try to
    contribute to your project. This is especially egregious if you put your test command in there!

    Fortunately, we have a solution: npm comes with a [scripts feature][npm-scripts] where you can include commands to be
    run for testing (`test`), installation (`install`), building (`prepublish`), and starting your app (`start`), among many
    others. You can also create custom scripts, which are then run with `npm run <script-name>`; I often use this for
    [lint steps][linting]. Also of note, you can reference any commands your app depends on by their short names here: for
    example, `"mocha"` instead of `"./node_modules/.bin/mocha". So, please use these! If you must have a Makefile for
    example, `"mocha"` instead of `"./node_modules/.bin/mocha"`. So, please use these! If you must have a Makefile for
    whatever reason, just have it [delegate to an npm script][knox-test].

    Another crucially important step is not using Unix shell scripts as part of your development process. Windows doesn't
  2. domenic revised this gist Oct 2, 2012. 1 changed file with 96 additions and 24 deletions.
    120 changes: 96 additions & 24 deletions portable-node.md
    Original file line number Diff line number Diff line change
    @@ -1,35 +1,107 @@
    # Tips for Writing Portable Node.js Code
    Title: How to Write Portable Node.js Code
    Author: Domenic Denicola
    Date: 2012-10-02T18:00:00Z
    Node: v0.8.11

    (This is the kind of thing I should put on my hypothetical blog.)
    Node.js core does its best to treat every platform equally. Even if most Node developers use OS X day to day, some use
    Windows, and most everyone deploys to Linux or Solaris. So it's important to keep your code portable between platforms,
    whether you're writing a library or an application.

    I'm a Node.js user... on Windows. (Gasp!) And here are some of the issues I face every day:
    Predictably, most cross-platform issues come from Windows. Things just work differently there! But if you're careful,
    and follow some simple best practices, your code can run just as well on Windows systems.

    ## Easy to Fix
    ## Paths and URLs

    In order of most-violated to least-violated:
    On Windows, paths are constructed with backslashes instead of forward slashes. So if you do your directory manipulation
    by splitting on `"/"` and playing with the resulting array, [your code will fail dramatically on Windows][codex].

    1. Don't manually construct paths. Use the `path` module.
    1. Bad: `x + "/" + y`. Good: `path.join(x, y)`. (Most likely better: `path.resolve(x, y)`.) [logicalparadox/codex@7f91b45](https://github.com/logicalparadox/codex/commit/7f91b451e7cdc9d794f30bd026029aea797bb1e0)
    2. Bad: `y.replace(/^parent\/dirs\//, "")`. Good: `path.relative("/parent/dirs", y)`. [ryanmcgrath/wrench-js#26](https://github.com/ryanmcgrath/wrench-js/issues/26) ([fix](https://github.com/ryanmcgrath/wrench-js/commit/01190602dac64924fca2dae11912ffb560e636a0))
    3. Be careful with module IDs versus paths; module IDs always have forward slashes. Don't conflate module IDs and filenames. [substack/node-browserify#144](https://github.com/substack/node-browserify/pull/144) ([fix](https://github.com/domenic/node-browserify/compare/88080dcd0de48eff7cdc1164e25ef73971bdbf6c...e6fffde08d19720a65f520e2bf76e989acc540ea))
    4. Ditto for URLs: don't use `path` methods on them. [LearnBoost/knox#56](https://github.com/LearnBoost/knox/issues/56) ([fix](https://github.com/domenic/knox/compare/eabef00df9bf79085229f4ed39b2679eb579ea20...9b1a4e9f644ababd5d9ced227de44709e1fccf4b)) [isaacs/npm-www#88](https://github.com/isaacs/npm-www/pull/88)
    2. Don't use `process.(get|set)(gid|uid)`. Windows doesn't have them. (Surround with conditionals if you must use them.) [flatiron/winston#126](https://github.com/flatiron/winston/pull/126) ([fix](https://github.com/domenic/winston/commit/a32d92ba1be3c21859d8c1c9e8e0e701846fcaf4))
    3. Don't use `fs.watchFile`. Use `fs.watch` instead. [logicalparadox/codex@be2fe18](https://github.com/logicalparadox/codex/commit/be2fe18f5561f7bbd3bd0099bb47f7e58c23638d)
    4. Treat module IDs/package names as case-sensitive, even though they aren't on Windows. Doing `require("Q")` for the `q` package will break for POSIX users.
    5. Be careful with the `child_process` methods. See [joyent/node#2318](https://github.com/joyent/node/issues/2318) for some of the confusion. (TODO: research exactly what the best practice would be to recommend here.) [sourcemint/sm-npm#6](https://github.com/sourcemint/sm-npm/issues/6)
    Instead, you should be using the [path module][path]. So instead of resolving paths with string contatenation, e.g.
    `x + "/" + y`, you should instead do `path.resolve(x, y)`. Similarly, instead of relativizing paths with string
    replacement, e.g. `x.replace(/^parent\/dirs\//, "")`, you [should][wrench] do `path.relative("/parent/dirs", y)`.

    ## Harder to Fix
    Another area of concern is that, when writing portable code, you cannot count on URLs and module IDs having the same
    separators as paths. If you use something like `path.join` [on a URL][knox], Windows users will get URLs containing
    backslashes! [Similarly][npm-www] for `path.normalize`, or in general any path methods. All this applies if you're
    [working with module IDs][browserify], too: they are forward-slash delimited, so you shouldn't use path functions with
    them either.

    6. Don't depend on `Makefile`s for development. Windows doesn't come with `make`. Use `package.json`'s `scripts` section instead, at the very least for `test` so that we Windows developers can run your tests. If you need a build solution I hear Jake and Grunt are pretty cool. You can always write a Makefile to delegate to these.
    7. Don't use shell scripts or other Unix-isms as part of your install process. Write them in JavaScript instead. See [gist:2238951](https://gist.github.com/2238951) for an example of writing a script to set up your git hooks, as well as the hooks themselves, in Node.
    1. Don't call shebang'ed files, e.g. from your build scripts or with `child_process`, without prefixing them with `node`. Windows doesn't understand that.
    2. Exception: git hooks (see above) seem to work, because Git for Windows understands shebangs, I guess.
    8. Don't barf on UTF-8 BOMs at the beginning of files. They are (very unfortunately) encouraged by Microsoft; all JavaScript files used in writing Windows 8 Metro apps must start with one, and every text file created by Visual Studio has one by default. Node itself handles them fine, so why can't you? (Projects that choke on them that have bitten me, so far: CoffeeScript and Jade.) [jashkenas/coffee-script#2284](https://github.com/jashkenas/coffee-script/issues/2284)

    ## Finally
    [codex]: https://github.com/logicalparadox/codex/commit/7f91b451e7cdc9d794f30bd026029aea797bb1e0
    [path]: http://nodejs.org/docs/latest/api/path.html
    [wrench]: https://github.com/ryanmcgrath/wrench-js/commit/01190602dac64924fca2dae11912ffb560e636a0
    [knox]: https://github.com/domenic/knox/compare/eabef00df9bf79085229f4ed39b2679eb579ea20...9b1a4e9f644ababd5d9ced227de44709e1fccf4b
    [npm-www]: https://github.com/isaacs/npm-www/pull/88
    [browserify]: https://github.com/substack/node-browserify/pull/158

    I end with two things: a thank you, and a plea.
    ## Non-portable APIs

    First, thank you to @ry for making Windows a part of your Node.js efforts. I hope we Windows developers can make you proud.
    Windows is completely missing the `process.(get|set)(gid|uid)` methods, so calling them will instantly crash your
    program on Windows. Always [guard such calls][winston] with a conditional.

    Second, to everyone else: please accept pull requests! As you can see from the linked issues, many pull requests for Windows support languished for a long time, especially on the bigger projects. Thanks to everyone for accepting them so far, though.
    The [`fs.watchFile`][watchFile] API is not sufficiently cross-platform, and is recommended against in the docs because
    of it. You [should][codex-watch] use [`fs.watch`][watch] instead.

    The [child_process][] module requires care cross-platform. In particular, `spawn` and `execFile` do not execute in a
    shell, which means that on Windows only `.exe` files will run. This is rather problematic, as many cross-platform
    binaries are included on Windows as `.cmd` or `.bat` files, [among them Git][npm-git], [CouchDB][npm-www-couchdb], and
    many others. So if you're using these APIs, things will likely work great on other platforms. But when you tell your
    users “just install the Git build for Windows, and make sure it's in your path!” that ends up not being sufficient.
    There is [talk][node-bug] of fixing this behavior in libuv, but that's still tentative. In the meantime, if you don't
    need to stream your output, `exec` works great. Otherwise you'll need [branching logic][npm-www-couchdb] to take care
    of the Windows case.

    A final edge-case comes when using named sockets, e.g. with `net.connect`. On Unix, simple filenames suffice, but on
    Windows, they must conform to a [bizarre syntax][pipe-names]. There's not really a better solution for this than
    [branching per-platform][cleanPipeName].


    [winston]: https://github.com/flatiron/winston/commit/a32d92ba1be3c21859d8c1c9e8e0e701846fcaf4
    [watchFile]: http://nodejs.org/docs/latest/api/fs.html#fs_fs_watchfile_filename_options_listener
    [codex-watch]: https://github.com/logicalparadox/codex/commit/be2fe18f5561f7bbd3bd0099bb47f7e58c23638d
    [watch]: http://nodejs.org/docs/latest/api/fs.html#fs_fs_watch_filename_options_listener
    [child_process]: http://nodejs.org/api/child_process.html
    [npm-git]: https://github.com/isaacs/npm/issues/2333
    [npm-www-couchdb]: https://github.com/isaacs/npm-www/blob/fd3a96e861989338676937736599598f7c0fde8f/dev/go.js#L22-27
    [node-bug]: https://github.com/joyent/node/issues/2318
    [pipe-names]: http://msdn.microsoft.com/en-us/library/windows/desktop/aa365783%28v=vs.85%29.aspx
    [cleanPipeName]: https://gist.github.com/2790533#gistcomment-331356

    ## Being Windows-Developer Friendly

    One of the most egregious problems with many projects is their excessive use of Unix Makefiles. Windows does not have a
    `make` command, so the tasks stored in these files are entirely inaccessible to Windows users who might try to
    contribute to your project. This is especially egregious if you put your test command in there!

    Fortunately, we have a solution: npm comes with a [scripts feature][npm-scripts] where you can include commands to be
    run for testing (`test`), installation (`install`), building (`prepublish`), and starting your app (`start`), among many
    others. You can also create custom scripts, which are then run with `npm run <script-name>`; I often use this for
    [lint steps][linting]. Also of note, you can reference any commands your app depends on by their short names here: for
    example, `"mocha"` instead of `"./node_modules/.bin/mocha". So, please use these! If you must have a Makefile for
    whatever reason, just have it [delegate to an npm script][knox-test].

    Another crucially important step is not using Unix shell scripts as part of your development process. Windows doesn't
    have bash, or `ls`, or `mv`, or any of those other commands you might use. Instead, write your shell scripts
    [in JavaScript][shell-scripts], using a tool like [Grunt][] if you'd like.


    [npm-scripts]: https://npmjs.org/doc/scripts.html
    [linting]: https://github.com/domenic/sinon-chai/blob/baf878ee7ba98bae507ac8bc91c94ea1fe287964/package.json#L28
    [knox-test]: https://github.com/LearnBoost/knox/blob/c1b680c80b7a4493970e3e9a92305387ef96c1eb/Makefile#L2-3
    [shell-scripts]: http://www.2ality.com/2011/12/nodejs-shell-scripting.html
    [Grunt]: http://gruntjs.com/

    ## Bonus: Something that Breaks on Linux and Solaris!

    Both Windows and, by default, OS X, use case-insensitive file systems. That means if you install a package named foo,
    any of `require("foo")` or `require("FOO")` or `require("fOo")` will work—on Windows and OS X. But then when you go to
    deploy your code, out of your development environment and into your Linux or Solaris production system, the latter two
    will *not* work! So it's a little thing, but make sure you always get your module and package name casing right.

    ## Conclusion

    As you can see, writing cross-platform code is sometimes painful. Usually, it's just a matter of best practices, like
    using the path module or remembering that URLs are different from filesystem paths. But sometimes there are APIs that
    just don't work cross-platform, or have annoying quirks that necessitate branching code.

    Nevertheless, it's worth it. Node.js is the most exciting software development platform in recent memory, and one of its
    greatest strengths is its portable nature. Try your best to uphold that!
  3. domenic revised this gist Aug 4, 2012. 1 changed file with 6 additions and 6 deletions.
    12 changes: 6 additions & 6 deletions portable-node.md
    Original file line number Diff line number Diff line change
    @@ -9,10 +9,10 @@ I'm a Node.js user... on Windows. (Gasp!) And here are some of the issues I face
    In order of most-violated to least-violated:

    1. Don't manually construct paths. Use the `path` module.
    a. Bad: `x + "/" + y`. Good: `path.join(x, y)`. (Most likely better: `path.resolve(x, y)`.) [logicalparadox/codex@7f91b45](https://github.com/logicalparadox/codex/commit/7f91b451e7cdc9d794f30bd026029aea797bb1e0)
    b. Bad: `y.replace(/^parent\/dirs\//, "")`. Good: `path.relative("/parent/dirs", y)`. [ryanmcgrath/wrench-js#26](https://github.com/ryanmcgrath/wrench-js/issues/26) ([fix](https://github.com/ryanmcgrath/wrench-js/commit/01190602dac64924fca2dae11912ffb560e636a0))
    c. Be careful with module IDs versus paths; module IDs always have forward slashes. Don't conflate module IDs and filenames. [substack/node-browserify#144](https://github.com/substack/node-browserify/pull/144) ([fix](https://github.com/domenic/node-browserify/compare/88080dcd0de48eff7cdc1164e25ef73971bdbf6c...e6fffde08d19720a65f520e2bf76e989acc540ea))
    d. Ditto for URLs: don't use `path` methods on them. [LearnBoost/knox#56](https://github.com/LearnBoost/knox/issues/56) ([fix](https://github.com/domenic/knox/compare/eabef00df9bf79085229f4ed39b2679eb579ea20...9b1a4e9f644ababd5d9ced227de44709e1fccf4b)) [isaacs/npm-www#88](https://github.com/isaacs/npm-www/pull/88)
    1. Bad: `x + "/" + y`. Good: `path.join(x, y)`. (Most likely better: `path.resolve(x, y)`.) [logicalparadox/codex@7f91b45](https://github.com/logicalparadox/codex/commit/7f91b451e7cdc9d794f30bd026029aea797bb1e0)
    2. Bad: `y.replace(/^parent\/dirs\//, "")`. Good: `path.relative("/parent/dirs", y)`. [ryanmcgrath/wrench-js#26](https://github.com/ryanmcgrath/wrench-js/issues/26) ([fix](https://github.com/ryanmcgrath/wrench-js/commit/01190602dac64924fca2dae11912ffb560e636a0))
    3. Be careful with module IDs versus paths; module IDs always have forward slashes. Don't conflate module IDs and filenames. [substack/node-browserify#144](https://github.com/substack/node-browserify/pull/144) ([fix](https://github.com/domenic/node-browserify/compare/88080dcd0de48eff7cdc1164e25ef73971bdbf6c...e6fffde08d19720a65f520e2bf76e989acc540ea))
    4. Ditto for URLs: don't use `path` methods on them. [LearnBoost/knox#56](https://github.com/LearnBoost/knox/issues/56) ([fix](https://github.com/domenic/knox/compare/eabef00df9bf79085229f4ed39b2679eb579ea20...9b1a4e9f644ababd5d9ced227de44709e1fccf4b)) [isaacs/npm-www#88](https://github.com/isaacs/npm-www/pull/88)
    2. Don't use `process.(get|set)(gid|uid)`. Windows doesn't have them. (Surround with conditionals if you must use them.) [flatiron/winston#126](https://github.com/flatiron/winston/pull/126) ([fix](https://github.com/domenic/winston/commit/a32d92ba1be3c21859d8c1c9e8e0e701846fcaf4))
    3. Don't use `fs.watchFile`. Use `fs.watch` instead. [logicalparadox/codex@be2fe18](https://github.com/logicalparadox/codex/commit/be2fe18f5561f7bbd3bd0099bb47f7e58c23638d)
    4. Treat module IDs/package names as case-sensitive, even though they aren't on Windows. Doing `require("Q")` for the `q` package will break for POSIX users.
    @@ -22,8 +22,8 @@ In order of most-violated to least-violated:

    6. Don't depend on `Makefile`s for development. Windows doesn't come with `make`. Use `package.json`'s `scripts` section instead, at the very least for `test` so that we Windows developers can run your tests. If you need a build solution I hear Jake and Grunt are pretty cool. You can always write a Makefile to delegate to these.
    7. Don't use shell scripts or other Unix-isms as part of your install process. Write them in JavaScript instead. See [gist:2238951](https://gist.github.com/2238951) for an example of writing a script to set up your git hooks, as well as the hooks themselves, in Node.
    a. Don't call shebang'ed files, e.g. from your build scripts or with `child_process`, without prefixing them with `node`. Windows doesn't understand that.
    b. Exception: git hooks (see above) seem to work, because Git for Windows understands shebangs, I guess.
    1. Don't call shebang'ed files, e.g. from your build scripts or with `child_process`, without prefixing them with `node`. Windows doesn't understand that.
    2. Exception: git hooks (see above) seem to work, because Git for Windows understands shebangs, I guess.
    8. Don't barf on UTF-8 BOMs at the beginning of files. They are (very unfortunately) encouraged by Microsoft; all JavaScript files used in writing Windows 8 Metro apps must start with one, and every text file created by Visual Studio has one by default. Node itself handles them fine, so why can't you? (Projects that choke on them that have bitten me, so far: CoffeeScript and Jade.) [jashkenas/coffee-script#2284](https://github.com/jashkenas/coffee-script/issues/2284)

    ## Finally
  4. domenic revised this gist Aug 4, 2012. 1 changed file with 15 additions and 15 deletions.
    30 changes: 15 additions & 15 deletions portable-node.md
    Original file line number Diff line number Diff line change
    @@ -8,28 +8,28 @@ I'm a Node.js user... on Windows. (Gasp!) And here are some of the issues I face

    In order of most-violated to least-violated:

    * Don't manually construct paths. Use the `path` module.
    * Bad: `x + "/" + y`. Good: `path.join(x, y)`. (Most likely better: `path.resolve(x, y)`.) [logicalparadox/codex@7f91b45](https://github.com/logicalparadox/codex/commit/7f91b451e7cdc9d794f30bd026029aea797bb1e0)
    * Bad: `y.replace(/^parent\/dirs\//, "")`. Good: `path.relative("/parent/dirs", y)`. [ryanmcgrath/wrench-js#26](https://github.com/ryanmcgrath/wrench-js/issues/26) ([fix](https://github.com/ryanmcgrath/wrench-js/commit/01190602dac64924fca2dae11912ffb560e636a0))
    * Be careful with module IDs versus paths; module IDs always have forward slashes. Don't conflate module IDs and filenames. [substack/node-browserify#144](https://github.com/substack/node-browserify/pull/144) ([fix](https://github.com/domenic/node-browserify/compare/88080dcd0de48eff7cdc1164e25ef73971bdbf6c...e6fffde08d19720a65f520e2bf76e989acc540ea))
    * Ditto for URLs: don't use `path` methods on them. [LearnBoost/knox#56](https://github.com/LearnBoost/knox/issues/56) ([fix](https://github.com/domenic/knox/compare/eabef00df9bf79085229f4ed39b2679eb579ea20...9b1a4e9f644ababd5d9ced227de44709e1fccf4b))
    * Don't use `process.(get|set)(gid|uid)`. Windows doesn't have them. (Surround with conditionals if you must use them.) [flatiron/winston#126](https://github.com/flatiron/winston/pull/126) ([fix](https://github.com/domenic/winston/commit/a32d92ba1be3c21859d8c1c9e8e0e701846fcaf4))
    * Don't use `fs.watchFile`. Use `fs.watch` instead. [logicalparadox/codex@be2fe18](https://github.com/logicalparadox/codex/commit/be2fe18f5561f7bbd3bd0099bb47f7e58c23638d)
    * Treat module IDs/package names as case-sensitive, even though they aren't on Windows. Doing `require("Q")` for the `q` package will break for POSIX users.
    * Be careful with the `child_process` methods. See [joyent/node#2318](https://github.com/joyent/node/issues/2318) for some of the confusion. (TODO: research exactly what the best practice would be to recommend here.) [sourcemint/sm-npm#6](https://github.com/sourcemint/sm-npm/issues/6)
    1. Don't manually construct paths. Use the `path` module.
    a. Bad: `x + "/" + y`. Good: `path.join(x, y)`. (Most likely better: `path.resolve(x, y)`.) [logicalparadox/codex@7f91b45](https://github.com/logicalparadox/codex/commit/7f91b451e7cdc9d794f30bd026029aea797bb1e0)
    b. Bad: `y.replace(/^parent\/dirs\//, "")`. Good: `path.relative("/parent/dirs", y)`. [ryanmcgrath/wrench-js#26](https://github.com/ryanmcgrath/wrench-js/issues/26) ([fix](https://github.com/ryanmcgrath/wrench-js/commit/01190602dac64924fca2dae11912ffb560e636a0))
    c. Be careful with module IDs versus paths; module IDs always have forward slashes. Don't conflate module IDs and filenames. [substack/node-browserify#144](https://github.com/substack/node-browserify/pull/144) ([fix](https://github.com/domenic/node-browserify/compare/88080dcd0de48eff7cdc1164e25ef73971bdbf6c...e6fffde08d19720a65f520e2bf76e989acc540ea))
    d. Ditto for URLs: don't use `path` methods on them. [LearnBoost/knox#56](https://github.com/LearnBoost/knox/issues/56) ([fix](https://github.com/domenic/knox/compare/eabef00df9bf79085229f4ed39b2679eb579ea20...9b1a4e9f644ababd5d9ced227de44709e1fccf4b)) [isaacs/npm-www#88](https://github.com/isaacs/npm-www/pull/88)
    2. Don't use `process.(get|set)(gid|uid)`. Windows doesn't have them. (Surround with conditionals if you must use them.) [flatiron/winston#126](https://github.com/flatiron/winston/pull/126) ([fix](https://github.com/domenic/winston/commit/a32d92ba1be3c21859d8c1c9e8e0e701846fcaf4))
    3. Don't use `fs.watchFile`. Use `fs.watch` instead. [logicalparadox/codex@be2fe18](https://github.com/logicalparadox/codex/commit/be2fe18f5561f7bbd3bd0099bb47f7e58c23638d)
    4. Treat module IDs/package names as case-sensitive, even though they aren't on Windows. Doing `require("Q")` for the `q` package will break for POSIX users.
    5. Be careful with the `child_process` methods. See [joyent/node#2318](https://github.com/joyent/node/issues/2318) for some of the confusion. (TODO: research exactly what the best practice would be to recommend here.) [sourcemint/sm-npm#6](https://github.com/sourcemint/sm-npm/issues/6)

    ## Harder to Fix

    * Don't depend on `Makefile`s for development. Windows doesn't come with `make`. Use `package.json`'s `scripts` section instead, at the very least for `test` so that we Windows developers can run your tests. If you need a build solution I hear Jake and Grunt are pretty cool. You can always write a Makefile to delegate to these.
    * Don't use shell scripts or other Unix-isms as part of your install process. Write them in JavaScript instead. See [gist:2238951](https://gist.github.com/2238951) for an example of writing a script to set up your git hooks, as well as the hooks themselves, in Node.
    * Don't call shebang'ed files, e.g. from your build scripts or with `child_process`, without prefixing them with `node`. Windows doesn't understand that.
    * Exception: git hooks (see above) seem to work, because Git for Windows understands shebangs, I guess.
    * Don't barf on UTF-8 BOMs at the beginning of files. They are (very unfortunately) encouraged by Microsoft; all JavaScript files used in writing Windows 8 Metro apps must start with one, and every text file created by Visual Studio has one by default. Node itself handles them fine, so why can't you? (Projects that choke on them that have bitten me, so far: CoffeeScript and Jade.) [jashkenas/coffee-script#2284](https://github.com/jashkenas/coffee-script/issues/2284)
    6. Don't depend on `Makefile`s for development. Windows doesn't come with `make`. Use `package.json`'s `scripts` section instead, at the very least for `test` so that we Windows developers can run your tests. If you need a build solution I hear Jake and Grunt are pretty cool. You can always write a Makefile to delegate to these.
    7. Don't use shell scripts or other Unix-isms as part of your install process. Write them in JavaScript instead. See [gist:2238951](https://gist.github.com/2238951) for an example of writing a script to set up your git hooks, as well as the hooks themselves, in Node.
    a. Don't call shebang'ed files, e.g. from your build scripts or with `child_process`, without prefixing them with `node`. Windows doesn't understand that.
    b. Exception: git hooks (see above) seem to work, because Git for Windows understands shebangs, I guess.
    8. Don't barf on UTF-8 BOMs at the beginning of files. They are (very unfortunately) encouraged by Microsoft; all JavaScript files used in writing Windows 8 Metro apps must start with one, and every text file created by Visual Studio has one by default. Node itself handles them fine, so why can't you? (Projects that choke on them that have bitten me, so far: CoffeeScript and Jade.) [jashkenas/coffee-script#2284](https://github.com/jashkenas/coffee-script/issues/2284)

    ## Finally

    I end with two things: a thank you, and a plea.

    First, thank you to @ry for making Windows a part of your Node.js efforts. I hope we Windows developers can make you proud.

    Second, to everyone else: please accept pull requests! As you can see from the linked issues, many pull requests for Windows support languish, especially on the bigger projects. @substack (browserify), @indexzero (winston), and @guille (knox), I know you guys are busy, but the small-and-growing Windows community would really appreciate your support. @logicalparadox (codex) and @ryanmcgrath (wrench), thank you for working with us!
    Second, to everyone else: please accept pull requests! As you can see from the linked issues, many pull requests for Windows support languished for a long time, especially on the bigger projects. Thanks to everyone for accepting them so far, though.
  5. domenic revised this gist May 25, 2012. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion portable-node.md
    Original file line number Diff line number Diff line change
    @@ -20,7 +20,7 @@ In order of most-violated to least-violated:

    ## Harder to Fix

    * Don't use Makefiles. Windows doesn't come with make. Use `package.json`'s `scripts` section instead, at the very least for `test` so that we Windows developers can run your tests. If you need a build solution I hear Jake and Grunt are pretty cool. You can always write a Makefile to delegate to these.
    * Don't depend on `Makefile`s for development. Windows doesn't come with `make`. Use `package.json`'s `scripts` section instead, at the very least for `test` so that we Windows developers can run your tests. If you need a build solution I hear Jake and Grunt are pretty cool. You can always write a Makefile to delegate to these.
    * Don't use shell scripts or other Unix-isms as part of your install process. Write them in JavaScript instead. See [gist:2238951](https://gist.github.com/2238951) for an example of writing a script to set up your git hooks, as well as the hooks themselves, in Node.
    * Don't call shebang'ed files, e.g. from your build scripts or with `child_process`, without prefixing them with `node`. Windows doesn't understand that.
    * Exception: git hooks (see above) seem to work, because Git for Windows understands shebangs, I guess.
  6. domenic revised this gist May 25, 2012. 1 changed file with 5 additions and 1 deletion.
    6 changes: 5 additions & 1 deletion portable-node.md
    Original file line number Diff line number Diff line change
    @@ -28,4 +28,8 @@ In order of most-violated to least-violated:

    ## Finally

    Please accept pull requests from me, and others like me! As you can see from the linked issues, many pull requests languish, especially on the bigger projects. @substack (browserify), @indexzero (winston), and @guille (knox), I know you guys are busy, but the small-and-growing Windows community would really appreciate your support. @logicalparadox and @ryanmcgrath, thank you for working with us!
    I end with two things: a thank you, and a plea.

    First, thank you to @ry for making Windows a part of your Node.js efforts. I hope we Windows developers can make you proud.

    Second, to everyone else: please accept pull requests! As you can see from the linked issues, many pull requests for Windows support languish, especially on the bigger projects. @substack (browserify), @indexzero (winston), and @guille (knox), I know you guys are busy, but the small-and-growing Windows community would really appreciate your support. @logicalparadox (codex) and @ryanmcgrath (wrench), thank you for working with us!
  7. domenic revised this gist May 25, 2012. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion portable-node.md
    Original file line number Diff line number Diff line change
    @@ -28,4 +28,4 @@ In order of most-violated to least-violated:

    ## Finally

    Please accept pull requests from me, and others like me! As you can see from the linked issues, many pull requests languish, especially on the bigger projects. @substack (browserify), @indexzero (winston), and @guille (knox), I know you guys are busy, but the small-and-growing Windows community would really appreciate your support. @logicalparadox, @ryanmcgrath, and
    Please accept pull requests from me, and others like me! As you can see from the linked issues, many pull requests languish, especially on the bigger projects. @substack (browserify), @indexzero (winston), and @guille (knox), I know you guys are busy, but the small-and-growing Windows community would really appreciate your support. @logicalparadox and @ryanmcgrath, thank you for working with us!
  8. domenic revised this gist May 25, 2012. 1 changed file with 7 additions and 2 deletions.
    9 changes: 7 additions & 2 deletions portable-node.md
    Original file line number Diff line number Diff line change
    @@ -9,11 +9,12 @@ I'm a Node.js user... on Windows. (Gasp!) And here are some of the issues I face
    In order of most-violated to least-violated:

    * Don't manually construct paths. Use the `path` module.
    * Bad: `x + "/" + y`. Good: `path.join(x, y)`. (Most likely better: `path.resolve(x, y)`.)
    * Bad: `x + "/" + y`. Good: `path.join(x, y)`. (Most likely better: `path.resolve(x, y)`.) [logicalparadox/codex@7f91b45](https://github.com/logicalparadox/codex/commit/7f91b451e7cdc9d794f30bd026029aea797bb1e0)
    * Bad: `y.replace(/^parent\/dirs\//, "")`. Good: `path.relative("/parent/dirs", y)`. [ryanmcgrath/wrench-js#26](https://github.com/ryanmcgrath/wrench-js/issues/26) ([fix](https://github.com/ryanmcgrath/wrench-js/commit/01190602dac64924fca2dae11912ffb560e636a0))
    * Be careful with module IDs versus paths; module IDs always have forward slashes. Don't conflate module IDs and filenames. [substack/node-browserify#144](https://github.com/substack/node-browserify/pull/144) ([fix](https://github.com/domenic/node-browserify/compare/88080dcd0de48eff7cdc1164e25ef73971bdbf6c...e6fffde08d19720a65f520e2bf76e989acc540ea))
    * Ditto for URLs: don't use `path` methods on them. [LearnBoost/knox#56](https://github.com/LearnBoost/knox/issues/56) ([fix](https://github.com/domenic/knox/compare/eabef00df9bf79085229f4ed39b2679eb579ea20...9b1a4e9f644ababd5d9ced227de44709e1fccf4b))
    * Don't use `process.(get|set)(gid|uid)`. Windows doesn't have them. (Surround with conditionals if you must use them.) [flatiron/winston#126](https://github.com/flatiron/winston/pull/126) ([fix](https://github.com/domenic/winston/commit/a32d92ba1be3c21859d8c1c9e8e0e701846fcaf4))
    * Don't use `fs.watchFile`. Use `fs.watch` instead. [logicalparadox/codex@be2fe18](https://github.com/logicalparadox/codex/commit/be2fe18f5561f7bbd3bd0099bb47f7e58c23638d)
    * Treat module IDs/package names as case-sensitive, even though they aren't on Windows. Doing `require("Q")` for the `q` package will break for POSIX users.
    * Be careful with the `child_process` methods. See [joyent/node#2318](https://github.com/joyent/node/issues/2318) for some of the confusion. (TODO: research exactly what the best practice would be to recommend here.) [sourcemint/sm-npm#6](https://github.com/sourcemint/sm-npm/issues/6)

    @@ -23,4 +24,8 @@ In order of most-violated to least-violated:
    * Don't use shell scripts or other Unix-isms as part of your install process. Write them in JavaScript instead. See [gist:2238951](https://gist.github.com/2238951) for an example of writing a script to set up your git hooks, as well as the hooks themselves, in Node.
    * Don't call shebang'ed files, e.g. from your build scripts or with `child_process`, without prefixing them with `node`. Windows doesn't understand that.
    * Exception: git hooks (see above) seem to work, because Git for Windows understands shebangs, I guess.
    * Don't barf on UTF-8 BOMs at the beginning of files. They are (very unfortunately) encouraged by Microsoft; all JavaScript files used in writing Windows 8 Metro apps must start with one, and every text file created by Visual Studio has one by default. Node itself handles them fine, so why can't you? (Projects that choke on them that have bitten me, so far: CoffeeScript and Jade.)
    * Don't barf on UTF-8 BOMs at the beginning of files. They are (very unfortunately) encouraged by Microsoft; all JavaScript files used in writing Windows 8 Metro apps must start with one, and every text file created by Visual Studio has one by default. Node itself handles them fine, so why can't you? (Projects that choke on them that have bitten me, so far: CoffeeScript and Jade.) [jashkenas/coffee-script#2284](https://github.com/jashkenas/coffee-script/issues/2284)

    ## Finally

    Please accept pull requests from me, and others like me! As you can see from the linked issues, many pull requests languish, especially on the bigger projects. @substack (browserify), @indexzero (winston), and @guille (knox), I know you guys are busy, but the small-and-growing Windows community would really appreciate your support. @logicalparadox, @ryanmcgrath, and
  9. domenic revised this gist May 25, 2012. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion portable-node.md
    Original file line number Diff line number Diff line change
    @@ -15,7 +15,7 @@ In order of most-violated to least-violated:
    * Ditto for URLs: don't use `path` methods on them. [LearnBoost/knox#56](https://github.com/LearnBoost/knox/issues/56) ([fix](https://github.com/domenic/knox/compare/eabef00df9bf79085229f4ed39b2679eb579ea20...9b1a4e9f644ababd5d9ced227de44709e1fccf4b))
    * Don't use `process.(get|set)(gid|uid)`. Windows doesn't have them. (Surround with conditionals if you must use them.) [flatiron/winston#126](https://github.com/flatiron/winston/pull/126) ([fix](https://github.com/domenic/winston/commit/a32d92ba1be3c21859d8c1c9e8e0e701846fcaf4))
    * Treat module IDs/package names as case-sensitive, even though they aren't on Windows. Doing `require("Q")` for the `q` package will break for POSIX users.
    * Be careful with the `child_process` methods. See joyent/node#2318 for some of the confusion. (TODO: research exactly what the best practice would be to recommend here.)
    * Be careful with the `child_process` methods. See [joyent/node#2318](https://github.com/joyent/node/issues/2318) for some of the confusion. (TODO: research exactly what the best practice would be to recommend here.) [sourcemint/sm-npm#6](https://github.com/sourcemint/sm-npm/issues/6)

    ## Harder to Fix

  10. domenic revised this gist May 25, 2012. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion portable-node.md
    Original file line number Diff line number Diff line change
    @@ -10,7 +10,7 @@ In order of most-violated to least-violated:

    * Don't manually construct paths. Use the `path` module.
    * Bad: `x + "/" + y`. Good: `path.join(x, y)`. (Most likely better: `path.resolve(x, y)`.)
    * Bad: `y.replace(/^parent\/dirs\//, "")`. Good: `path.relative("/parent/dirs", y)`.
    * Bad: `y.replace(/^parent\/dirs\//, "")`. Good: `path.relative("/parent/dirs", y)`. [ryanmcgrath/wrench-js#26](https://github.com/ryanmcgrath/wrench-js/issues/26) ([fix](https://github.com/ryanmcgrath/wrench-js/commit/01190602dac64924fca2dae11912ffb560e636a0))
    * Be careful with module IDs versus paths; module IDs always have forward slashes. Don't conflate module IDs and filenames. [substack/node-browserify#144](https://github.com/substack/node-browserify/pull/144) ([fix](https://github.com/domenic/node-browserify/compare/88080dcd0de48eff7cdc1164e25ef73971bdbf6c...e6fffde08d19720a65f520e2bf76e989acc540ea))
    * Ditto for URLs: don't use `path` methods on them. [LearnBoost/knox#56](https://github.com/LearnBoost/knox/issues/56) ([fix](https://github.com/domenic/knox/compare/eabef00df9bf79085229f4ed39b2679eb579ea20...9b1a4e9f644ababd5d9ced227de44709e1fccf4b))
    * Don't use `process.(get|set)(gid|uid)`. Windows doesn't have them. (Surround with conditionals if you must use them.) [flatiron/winston#126](https://github.com/flatiron/winston/pull/126) ([fix](https://github.com/domenic/winston/commit/a32d92ba1be3c21859d8c1c9e8e0e701846fcaf4))
  11. domenic revised this gist May 25, 2012. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion portable-node.md
    Original file line number Diff line number Diff line change
    @@ -13,7 +13,7 @@ In order of most-violated to least-violated:
    * Bad: `y.replace(/^parent\/dirs\//, "")`. Good: `path.relative("/parent/dirs", y)`.
    * Be careful with module IDs versus paths; module IDs always have forward slashes. Don't conflate module IDs and filenames. [substack/node-browserify#144](https://github.com/substack/node-browserify/pull/144) ([fix](https://github.com/domenic/node-browserify/compare/88080dcd0de48eff7cdc1164e25ef73971bdbf6c...e6fffde08d19720a65f520e2bf76e989acc540ea))
    * Ditto for URLs: don't use `path` methods on them. [LearnBoost/knox#56](https://github.com/LearnBoost/knox/issues/56) ([fix](https://github.com/domenic/knox/compare/eabef00df9bf79085229f4ed39b2679eb579ea20...9b1a4e9f644ababd5d9ced227de44709e1fccf4b))
    * Don't use `process.(get|set)(gid|uid)`. Windows doesn't have them. (Surround with conditionals if you must use them.) [flatiron/winston#126](https://github.com/flatiron/winston/pull/126)
    * Don't use `process.(get|set)(gid|uid)`. Windows doesn't have them. (Surround with conditionals if you must use them.) [flatiron/winston#126](https://github.com/flatiron/winston/pull/126) ([fix](https://github.com/domenic/winston/commit/a32d92ba1be3c21859d8c1c9e8e0e701846fcaf4))
    * Treat module IDs/package names as case-sensitive, even though they aren't on Windows. Doing `require("Q")` for the `q` package will break for POSIX users.
    * Be careful with the `child_process` methods. See joyent/node#2318 for some of the confusion. (TODO: research exactly what the best practice would be to recommend here.)

  12. domenic revised this gist May 25, 2012. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion portable-node.md
    Original file line number Diff line number Diff line change
    @@ -12,7 +12,7 @@ In order of most-violated to least-violated:
    * Bad: `x + "/" + y`. Good: `path.join(x, y)`. (Most likely better: `path.resolve(x, y)`.)
    * Bad: `y.replace(/^parent\/dirs\//, "")`. Good: `path.relative("/parent/dirs", y)`.
    * Be careful with module IDs versus paths; module IDs always have forward slashes. Don't conflate module IDs and filenames. [substack/node-browserify#144](https://github.com/substack/node-browserify/pull/144) ([fix](https://github.com/domenic/node-browserify/compare/88080dcd0de48eff7cdc1164e25ef73971bdbf6c...e6fffde08d19720a65f520e2bf76e989acc540ea))
    * Ditto for URLs: don't use `path` methods on them. [LearnBoost/knox#56](https://github.com/LearnBoost/knox/issues/56)
    * Ditto for URLs: don't use `path` methods on them. [LearnBoost/knox#56](https://github.com/LearnBoost/knox/issues/56) ([fix](https://github.com/domenic/knox/compare/eabef00df9bf79085229f4ed39b2679eb579ea20...9b1a4e9f644ababd5d9ced227de44709e1fccf4b))
    * Don't use `process.(get|set)(gid|uid)`. Windows doesn't have them. (Surround with conditionals if you must use them.) [flatiron/winston#126](https://github.com/flatiron/winston/pull/126)
    * Treat module IDs/package names as case-sensitive, even though they aren't on Windows. Doing `require("Q")` for the `q` package will break for POSIX users.
    * Be careful with the `child_process` methods. See joyent/node#2318 for some of the confusion. (TODO: research exactly what the best practice would be to recommend here.)
  13. domenic revised this gist May 25, 2012. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions portable-node.md
    Original file line number Diff line number Diff line change
    @@ -11,8 +11,8 @@ In order of most-violated to least-violated:
    * Don't manually construct paths. Use the `path` module.
    * Bad: `x + "/" + y`. Good: `path.join(x, y)`. (Most likely better: `path.resolve(x, y)`.)
    * Bad: `y.replace(/^parent\/dirs\//, "")`. Good: `path.relative("/parent/dirs", y)`.
    * Be careful with module IDs versus paths; module IDs always have forward slashes. Don't conflate module IDs and filenames.
    * Ditto for URLs: don't use `path` methods on them.
    * Be careful with module IDs versus paths; module IDs always have forward slashes. Don't conflate module IDs and filenames. [substack/node-browserify#144](https://github.com/substack/node-browserify/pull/144) ([fix](https://github.com/domenic/node-browserify/compare/88080dcd0de48eff7cdc1164e25ef73971bdbf6c...e6fffde08d19720a65f520e2bf76e989acc540ea))
    * Ditto for URLs: don't use `path` methods on them. [LearnBoost/knox#56](https://github.com/LearnBoost/knox/issues/56)
    * Don't use `process.(get|set)(gid|uid)`. Windows doesn't have them. (Surround with conditionals if you must use them.) [flatiron/winston#126](https://github.com/flatiron/winston/pull/126)
    * Treat module IDs/package names as case-sensitive, even though they aren't on Windows. Doing `require("Q")` for the `q` package will break for POSIX users.
    * Be careful with the `child_process` methods. See joyent/node#2318 for some of the confusion. (TODO: research exactly what the best practice would be to recommend here.)
  14. domenic revised this gist May 25, 2012. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion portable-node.md
    Original file line number Diff line number Diff line change
    @@ -13,7 +13,7 @@ In order of most-violated to least-violated:
    * Bad: `y.replace(/^parent\/dirs\//, "")`. Good: `path.relative("/parent/dirs", y)`.
    * Be careful with module IDs versus paths; module IDs always have forward slashes. Don't conflate module IDs and filenames.
    * Ditto for URLs: don't use `path` methods on them.
    * Don't use `process.(get|set)(gid|uid)`. Windows doesn't have them. (Surround with conditionals if you must use them.) flatiron/winston#126
    * Don't use `process.(get|set)(gid|uid)`. Windows doesn't have them. (Surround with conditionals if you must use them.) [flatiron/winston#126](https://github.com/flatiron/winston/pull/126)
    * Treat module IDs/package names as case-sensitive, even though they aren't on Windows. Doing `require("Q")` for the `q` package will break for POSIX users.
    * Be careful with the `child_process` methods. See joyent/node#2318 for some of the confusion. (TODO: research exactly what the best practice would be to recommend here.)

  15. domenic revised this gist May 25, 2012. 1 changed file with 2 additions and 1 deletion.
    3 changes: 2 additions & 1 deletion portable-node.md
    Original file line number Diff line number Diff line change
    @@ -16,10 +16,11 @@ In order of most-violated to least-violated:
    * Don't use `process.(get|set)(gid|uid)`. Windows doesn't have them. (Surround with conditionals if you must use them.) flatiron/winston#126
    * Treat module IDs/package names as case-sensitive, even though they aren't on Windows. Doing `require("Q")` for the `q` package will break for POSIX users.
    * Be careful with the `child_process` methods. See joyent/node#2318 for some of the confusion. (TODO: research exactly what the best practice would be to recommend here.)
    * Don't use shebangs. Windows doesn't understand them. Exception: git hooks (see below) seem to work, because Git for Windows understands shebangs.

    ## Harder to Fix

    * Don't use Makefiles. Windows doesn't come with make. Use `package.json`'s `scripts` section instead, at the very least for `test` so that we Windows developers can run your tests. If you need a build solution I hear Jake and Grunt are pretty cool. You can always write a Makefile to delegate to these.
    * Don't use shell scripts or other Unix-isms as part of your install process. Write them in JavaScript instead. See [gist:2238951](https://gist.github.com/2238951) for an example of writing a script to set up your git hooks, as well as the hooks themselves, in Node.
    * Don't call shebang'ed files, e.g. from your build scripts or with `child_process`, without prefixing them with `node`. Windows doesn't understand that.
    * Exception: git hooks (see above) seem to work, because Git for Windows understands shebangs, I guess.
    * Don't barf on UTF-8 BOMs at the beginning of files. They are (very unfortunately) encouraged by Microsoft; all JavaScript files used in writing Windows 8 Metro apps must start with one, and every text file created by Visual Studio has one by default. Node itself handles them fine, so why can't you? (Projects that choke on them that have bitten me, so far: CoffeeScript and Jade.)
  16. domenic revised this gist May 25, 2012. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion portable-node.md
    Original file line number Diff line number Diff line change
    @@ -13,7 +13,7 @@ In order of most-violated to least-violated:
    * Bad: `y.replace(/^parent\/dirs\//, "")`. Good: `path.relative("/parent/dirs", y)`.
    * Be careful with module IDs versus paths; module IDs always have forward slashes. Don't conflate module IDs and filenames.
    * Ditto for URLs: don't use `path` methods on them.
    * Don't use `process.(get|set)(gid|uid)`. Windows doesn't have them. (Surround with conditionals if you must use them.)
    * Don't use `process.(get|set)(gid|uid)`. Windows doesn't have them. (Surround with conditionals if you must use them.) flatiron/winston#126
    * Treat module IDs/package names as case-sensitive, even though they aren't on Windows. Doing `require("Q")` for the `q` package will break for POSIX users.
    * Be careful with the `child_process` methods. See joyent/node#2318 for some of the confusion. (TODO: research exactly what the best practice would be to recommend here.)
    * Don't use shebangs. Windows doesn't understand them. Exception: git hooks (see below) seem to work, because Git for Windows understands shebangs.
  17. domenic revised this gist May 25, 2012. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions portable-node.md
    Original file line number Diff line number Diff line change
    @@ -4,7 +4,7 @@

    I'm a Node.js user... on Windows. (Gasp!) And here are some of the issues I face every day:

    ## Easy
    ## Easy to Fix

    In order of most-violated to least-violated:

    @@ -18,7 +18,7 @@ In order of most-violated to least-violated:
    * Be careful with the `child_process` methods. See joyent/node#2318 for some of the confusion. (TODO: research exactly what the best practice would be to recommend here.)
    * Don't use shebangs. Windows doesn't understand them. Exception: git hooks (see below) seem to work, because Git for Windows understands shebangs.

    ## Harder
    ## Harder to Fix

    * Don't use Makefiles. Windows doesn't come with make. Use `package.json`'s `scripts` section instead, at the very least for `test` so that we Windows developers can run your tests. If you need a build solution I hear Jake and Grunt are pretty cool. You can always write a Makefile to delegate to these.
    * Don't use shell scripts or other Unix-isms as part of your install process. Write them in JavaScript instead. See [gist:2238951](https://gist.github.com/2238951) for an example of writing a script to set up your git hooks, as well as the hooks themselves, in Node.
  18. domenic revised this gist May 25, 2012. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion portable-node.md
    Original file line number Diff line number Diff line change
    @@ -21,5 +21,5 @@ In order of most-violated to least-violated:
    ## Harder

    * Don't use Makefiles. Windows doesn't come with make. Use `package.json`'s `scripts` section instead, at the very least for `test` so that we Windows developers can run your tests. If you need a build solution I hear Jake and Grunt are pretty cool. You can always write a Makefile to delegate to these.
    * Don't use shell scripts or other Unix-isms as part of your install process. Write them in JavaScript instead. See gist:2238951 for an example of writing a script to set up your git hooks, as well as the hooks themselves, in Node.
    * Don't use shell scripts or other Unix-isms as part of your install process. Write them in JavaScript instead. See [gist:2238951](https://gist.github.com/2238951) for an example of writing a script to set up your git hooks, as well as the hooks themselves, in Node.
    * Don't barf on UTF-8 BOMs at the beginning of files. They are (very unfortunately) encouraged by Microsoft; all JavaScript files used in writing Windows 8 Metro apps must start with one, and every text file created by Visual Studio has one by default. Node itself handles them fine, so why can't you? (Projects that choke on them that have bitten me, so far: CoffeeScript and Jade.)
  19. domenic revised this gist May 25, 2012. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion portable-node.md
    Original file line number Diff line number Diff line change
    @@ -20,6 +20,6 @@ In order of most-violated to least-violated:

    ## Harder

    * Don't use Makefiles. Windows doesn't come with make. Use `package.json`'s `scripts` section instead, at the very least for `test` so that we Windows developers can run them. If you need a build solution I hear Jake and Grunt are pretty cool.
    * Don't use Makefiles. Windows doesn't come with make. Use `package.json`'s `scripts` section instead, at the very least for `test` so that we Windows developers can run your tests. If you need a build solution I hear Jake and Grunt are pretty cool. You can always write a Makefile to delegate to these.
    * Don't use shell scripts or other Unix-isms as part of your install process. Write them in JavaScript instead. See gist:2238951 for an example of writing a script to set up your git hooks, as well as the hooks themselves, in Node.
    * Don't barf on UTF-8 BOMs at the beginning of files. They are (very unfortunately) encouraged by Microsoft; all JavaScript files used in writing Windows 8 Metro apps must start with one, and every text file created by Visual Studio has one by default. Node itself handles them fine, so why can't you? (Projects that choke on them that have bitten me, so far: CoffeeScript and Jade.)
  20. domenic revised this gist May 25, 2012. 1 changed file with 6 additions and 2 deletions.
    8 changes: 6 additions & 2 deletions portable-node.md
    Original file line number Diff line number Diff line change
    @@ -2,13 +2,17 @@

    (This is the kind of thing I should put on my hypothetical blog.)

    I'm a Node.js user... on Windows. (Gasp!) And here are some of the issues I face every day:

    ## Easy

    In order of most-violated to least-violated:

    * Don't manually construct paths. Use the `path` module. Bad: `x + '/' + y`. Good: `path.join(x, y)`. Bad: `y.replace(/^parent\/dirs\//, "")`. Good: `path.relative("/parent/dirs", y)`.
    * Don't manually construct paths. Use the `path` module.
    * Bad: `x + "/" + y`. Good: `path.join(x, y)`. (Most likely better: `path.resolve(x, y)`.)
    * Bad: `y.replace(/^parent\/dirs\//, "")`. Good: `path.relative("/parent/dirs", y)`.
    * Be careful with module IDs versus paths; module IDs always have forward slashes. Don't conflate module IDs and filenames.
    * Ditto for URLs.
    * Ditto for URLs: don't use `path` methods on them.
    * Don't use `process.(get|set)(gid|uid)`. Windows doesn't have them. (Surround with conditionals if you must use them.)
    * Treat module IDs/package names as case-sensitive, even though they aren't on Windows. Doing `require("Q")` for the `q` package will break for POSIX users.
    * Be careful with the `child_process` methods. See joyent/node#2318 for some of the confusion. (TODO: research exactly what the best practice would be to recommend here.)
  21. domenic revised this gist May 25, 2012. 1 changed file with 7 additions and 6 deletions.
    13 changes: 7 additions & 6 deletions portable-node.md
    Original file line number Diff line number Diff line change
    @@ -1,20 +1,21 @@
    # Tips for Writing Portable Node.js Code

    (This is the kind of thing I should put on my hypothetical blog.)

    Easy things to fix, in order of most-violated to least-violated:
    ## Easy

    In order of most-violated to least-violated:

    * Don't manually construct paths. Use the `path` module. Bad: `x + '/' + y`. Good: `path.join(x, y)`. Bad: `y.replace(/^parent\/dirs\//, "")`. Good: `path.relative("/parent/dirs", y)`.
    * Be careful with module IDs versus paths; module IDs always have forward slashes. Don't conflate module IDs and filenames.
    * Similarly URLs.
    * Ditto for URLs.
    * Don't use `process.(get|set)(gid|uid)`. Windows doesn't have them. (Surround with conditionals if you must use them.)
    * Treat module IDs/package names as case-sensitive, even though they aren't on Windows. Doing `require("Q")` for the `q` package will break for POSIX users.
    * Be careful with the `child_process` methods. See joyent/node#2318 for some of the confusion. (TODO: research exactly what the best practice would be to recommend here.)
    * Don't use shebangs. Windows doesn't understand them. Exception: git hooks (see below) seem to work, because Git for Windows understands shebangs.

    Harder:
    ## Harder

    * Don't use Makefiles. Windows doesn't come with make. Use `package.json`'s `scripts` section instead, at the very least for `test` so that we Windows developers can run them. If you need a build solution I hear Jake and Grunt are pretty cool.
    * Don't use shell scripts or other Unix-isms as part of your install process. Write them in JavaScript instead. See gist:2238951 for an example of writing a script to set up your git hooks, as well as the hooks themselves, in Node.

    Dubious:

    * Don't barf on UTF-8 BOMs at the beginning of files. They are (very unfortunately) encouraged by Microsoft; all JavaScript files used in writing Windows 8 Metro apps must start with one, and every text file created by Visual Studio has one by default. Node itself handles them fine, so why can't you? (Projects that choke on them that have bitten me, so far: CoffeeScript and Jade.)
  22. domenic created this gist May 25, 2012.
    20 changes: 20 additions & 0 deletions portable-node.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,20 @@
    (This is the kind of thing I should put on my hypothetical blog.)

    Easy things to fix, in order of most-violated to least-violated:

    * Don't manually construct paths. Use the `path` module. Bad: `x + '/' + y`. Good: `path.join(x, y)`. Bad: `y.replace(/^parent\/dirs\//, "")`. Good: `path.relative("/parent/dirs", y)`.
    * Be careful with module IDs versus paths; module IDs always have forward slashes. Don't conflate module IDs and filenames.
    * Similarly URLs.
    * Don't use `process.(get|set)(gid|uid)`. Windows doesn't have them. (Surround with conditionals if you must use them.)
    * Treat module IDs/package names as case-sensitive, even though they aren't on Windows. Doing `require("Q")` for the `q` package will break for POSIX users.
    * Be careful with the `child_process` methods. See joyent/node#2318 for some of the confusion. (TODO: research exactly what the best practice would be to recommend here.)
    * Don't use shebangs. Windows doesn't understand them. Exception: git hooks (see below) seem to work, because Git for Windows understands shebangs.

    Harder:

    * Don't use Makefiles. Windows doesn't come with make. Use `package.json`'s `scripts` section instead, at the very least for `test` so that we Windows developers can run them. If you need a build solution I hear Jake and Grunt are pretty cool.
    * Don't use shell scripts or other Unix-isms as part of your install process. Write them in JavaScript instead. See gist:2238951 for an example of writing a script to set up your git hooks, as well as the hooks themselves, in Node.

    Dubious:

    * Don't barf on UTF-8 BOMs at the beginning of files. They are (very unfortunately) encouraged by Microsoft; all JavaScript files used in writing Windows 8 Metro apps must start with one, and every text file created by Visual Studio has one by default. Node itself handles them fine, so why can't you? (Projects that choke on them that have bitten me, so far: CoffeeScript and Jade.)