{"action":"created","issue":{"url":"https://api.github.com/repos/tivac/modular-css/issues/226","repository_url":"https://api.github.com/repos/tivac/modular-css","labels_url":"https://api.github.com/repos/tivac/modular-css/issues/226/labels{/name}","comments_url":"https://api.github.com/repos/tivac/modular-css/issues/226/comments","events_url":"https://api.github.com/repos/tivac/modular-css/issues/226/events","html_url":"https://github.com/tivac/modular-css/issues/226","id":197725934,"number":226,"title":"Non-watchify file watchers put you in cache hell","user":{"login":"Morklympious","id":5068257,"avatar_url":"https://avatars.githubusercontent.com/u/5068257?v=3","gravatar_id":"","url":"https://api.github.com/users/Morklympious","html_url":"https://github.com/Morklympious","followers_url":"https://api.github.com/users/Morklympious/followers","following_url":"https://api.github.com/users/Morklympious/following{/other_user}","gists_url":"https://api.github.com/users/Morklympious/gists{/gist_id}","starred_url":"https://api.github.com/users/Morklympious/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Morklympious/subscriptions","organizations_url":"https://api.github.com/users/Morklympious/orgs","repos_url":"https://api.github.com/users/Morklympious/repos","events_url":"https://api.github.com/users/Morklympious/events{/privacy}","received_events_url":"https://api.github.com/users/Morklympious/received_events","type":"User","site_admin":false},"labels":[{"id":279359498,"url":"https://api.github.com/repos/tivac/modular-css/labels/feature","name":"feature","color":"84b6eb","default":false},{"id":279359501,"url":"https://api.github.com/repos/tivac/modular-css/labels/question","name":"question","color":"cc317c","default":true}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":2,"created_at":"2016-12-27T16:25:34Z","updated_at":"2016-12-30T19:41:05Z","closed_at":null,"body":"Hey Pat! \r\n\r\nRan into an issue with Modular-CSS processing CSS dependencies when coding up something recently. \r\nI'm using [Browser-sync](https://www.browsersync.io/), which has it's own standalone file watching system (pretty fun if you haven't checked it already), so I end up glob matching on the `src/` directory and listen for any changes, like so:\r\n\r\n```js\r\n/**\r\n * Initializing over the dist directory, with a delay that will allow for rapid\r\n * src directory file changes in case some smoking gun can't keep their fingers\r\n * off of the ctrl+s combo\r\n *\r\n * ... I'm talking of course, about myself.\r\n */\r\nsync.init({\r\n  server: \"./dist\",\r\n  reloadDelay: 1500\r\n});\r\n\r\n/**\r\n * Let's go ahead and just watch the entirety of the source directory\r\n * (Thanks for standalone file watching, browser-sync!)\r\n *\r\n * If there are any changes on our non-entry.js files, we'll hot reload.\r\n * Browserify will handle entry.js and tell Browser-sync to reload whenever\r\n * Browserify bundles.\r\n */\r\nsync.watch(\"./src/**/*.*\").on(\"change\", () => {\r\n  build.copy(); // Copy non-build related files\r\n  build.bundle(); // Browserify and output CSS + JS\r\n});\r\n```\r\n\r\nIn pretty much every case, I rebundle my browserify bundle, and since I'm using Modular-CSS as a plugin, I'm expecting that running the bundle function will give me an updated CSS file in `./dist/css/site.css`:\r\n\r\n```js\r\n// . . .\r\n\r\nbuilder.plugin(\"modular-css/browserify\", {\r\n  css : \"./dist/css/site.css\",\r\n\r\n  after: [\r\n    require(\"postcss-import\")\r\n  ]\r\n});\r\n\r\n// . . . \r\n\r\n\r\nfunction _bundle() {\r\n    var write = fs.writeFileSync;\r\n\r\n    builder.bundle(function(err, output) {\r\n      if(err) {\r\n        console.log(err);\r\n        return;\r\n      }\r\n\r\n      write(\"./dist/js/bundle.js\", output);\r\n    });\r\n\r\n}\r\n\r\n// . . . \r\n\r\nmodule.exports = {\r\n  bundle: _bundle\r\n  // . . .\r\n}\r\n```\r\n\r\nHowever, it looks like using a file watcher that _isn't_ `Watchify` causes the Modular-CSS plugin to not purge its file cache. For the life of my Browser-sync watcher, any file modification and subsequent rebundle would output the same global CSS file (despite containing changes in src). Looks like the plugin runs but it doesn't remove existing files unless the events that Watchify fired are... fired. After some debugging, I found The offending block of code:\r\n\r\n```js \r\n// Watchify fires update events when files change, this tells the processor\r\n// to remove the changed files from its cache so they will be re-processed\r\nbrowserify.on(\"update\", function(files) {\r\n    processor.remove(files);\r\n});\r\n```\r\nThis was essentially solved after I re-included `watchify` into my single-build file, but it seems like redundancy especially if I don't necessarily want to be tied to watchify and want to use some other file watcher less specific to Browserify. \r\n\r\nI'm wondering if there's a way to just fire off, refactor, or spoof this workflow because you get stuck in cache hell if you don't use watchify.  Or maybe the solution is to pass in an option that disables the cache. \r\n\r\nI'm pretty sure this doesn't affect a majority of users, but it's a fun edge case. \r\n\r\n"},"comment":{"url":"https://api.github.com/repos/tivac/modular-css/issues/comments/269813442","html_url":"https://github.com/tivac/modular-css/issues/226#issuecomment-269813442","issue_url":"https://api.github.com/repos/tivac/modular-css/issues/226","id":269813442,"user":{"login":"Morklympious","id":5068257,"avatar_url":"https://avatars.githubusercontent.com/u/5068257?v=3","gravatar_id":"","url":"https://api.github.com/users/Morklympious","html_url":"https://github.com/Morklympious","followers_url":"https://api.github.com/users/Morklympious/followers","following_url":"https://api.github.com/users/Morklympious/following{/other_user}","gists_url":"https://api.github.com/users/Morklympious/gists{/gist_id}","starred_url":"https://api.github.com/users/Morklympious/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Morklympious/subscriptions","organizations_url":"https://api.github.com/users/Morklympious/orgs","repos_url":"https://api.github.com/users/Morklympious/repos","events_url":"https://api.github.com/users/Morklympious/events{/privacy}","received_events_url":"https://api.github.com/users/Morklympious/received_events","type":"User","site_admin":false},"created_at":"2016-12-30T19:41:05Z","updated_at":"2016-12-30T19:41:05Z","body":"In the meantime, I've found a workaround which is basically separating single-build vs. watch-then-build logic. \r\n\r\nIn the single build, attaching the `modular-css/browserify` plugin so it can output hashed CSS on bundle is fine, since it's not a polling or watching process. \r\n\r\n```js\r\nvar fs          = require('fs'),\r\n    shell       = require('shelljs'),\r\n    browserify  = require('browserify'),\r\n    watchify    = require(\"watchify\");\r\n\r\nvar builder = browserify(\"./src/js/entry.js\", {\r\n  debug: false\r\n});\r\n\r\nbuilder.plugin(\"modular-css/browserify\", {\r\n  css: \"./dist/css/site.css\",\r\n\r\n  after: [\r\n    require(\"postcss-import\")\r\n  ]\r\n});\r\n\r\n// ...\r\n\r\n```\r\n\r\nIn the watching file (again, using Browser-sync), Setting the plugin to watchify is fine enough so that it can emit the `update` event. \r\n\r\n```js\r\nvar fs     = require(\"fs\"),\r\n    path   = require(\"path\"),\r\n    shell  = require(\"shelljs\"),\r\n    sync   = require(\"browser-sync\").create(),\r\n    build  = require(\"./build-default.js\"),\r\n\r\n    // Including debounce so we don't refresh 15000 times whenever the\r\n    // dist directory changes\r\n    debounce = require(\"lodash.debounce\");\r\n\r\nbuild.builder.plugin(\"watchify\");\r\nbuild.builder.on(\"update\", build.bundle);\r\n\r\n// . . . \r\n\r\nsync.watch(\"./src/**/*.*\").on(\"change\", () => {\r\n  build.copy();\r\n});\r\n\r\nsync.watch(\"./src/js/**/*.js\").on(\"change\", () => {\r\n  build.bundle();\r\n});\r\n\r\nsync.watch(\"./src/css/**/*.css\").on(\"change\", () => {\r\n  build.bundle();\r\n});\r\n\r\n/**\r\n * In the event that anything in dist changes (by some third party build magic)\r\n * then we'll just refresh the whole shebang.\r\n */\r\nsync.watch(\"./dist/**/*.*\").on(\"change\", debounce(sync.reload, 750));\r\n\r\n```\r\n\r\nIt looks like as long as bundle is a one-time op you can call it with abandon. The only real overhead is that I have duplicate file watchers that essentially perform the same thing. It's a race condition, but in this case it doesn't matter which goes first since they both bundle the same thing. \r\n\r\nNot elegant, but better than reinitializing the plugin / removing and re-adding every single time. This is also known as the \"IT LOOKS LIKE IT WORKS OH GOD I'LL TAKE IT. I'LL TAKE IT TO THE BANK\" principle. "}}
{"actor":{"display_login":"Morklympious"}}