{"action":"created","comment":{"url":"https://api.github.com/repos/optimizely/marketing-website/pulls/comments/28307665","id":28307665,"diff_hunk":"@@ -0,0 +1,104 @@\n+var _ = require('lodash');\n+var webpack = require('webpack');\n+\n+module.exports = function(opts) {\n+  var jshintConfig = _.merge({}, {\n+    emitErrors: true,\n+    failOnHint: true,\n+  }, opts.jshintConfig);\n+\n+  var preloaders = [\n+    {\n+      test: /\\.js$/,\n+      exclude: [\n+        /node\\_modules/,\n+        /bower\\_components/,\n+        /libraries/,\n+        /form\\-filler/,","path":"grunt/webpack/make-webpack-config.js","position":17,"original_position":17,"commit_id":"d77fa62a338c9d7b6152771a505a0d48d7ccb3d3","original_commit_id":"d77fa62a338c9d7b6152771a505a0d48d7ccb3d3","user":{"login":"4vanger","id":596990,"avatar_url":"https://avatars.githubusercontent.com/u/596990?v=3","gravatar_id":"","url":"https://api.github.com/users/4vanger","html_url":"https://github.com/4vanger","followers_url":"https://api.github.com/users/4vanger/followers","following_url":"https://api.github.com/users/4vanger/following{/other_user}","gists_url":"https://api.github.com/users/4vanger/gists{/gist_id}","starred_url":"https://api.github.com/users/4vanger/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/4vanger/subscriptions","organizations_url":"https://api.github.com/users/4vanger/orgs","repos_url":"https://api.github.com/users/4vanger/repos","events_url":"https://api.github.com/users/4vanger/events{/privacy}","received_events_url":"https://api.github.com/users/4vanger/received_events","type":"User","site_admin":false},"body":"no need to escape minus as well","created_at":"2015-04-14T08:13:01Z","updated_at":"2015-04-14T08:13:01Z","html_url":"https://github.com/optimizely/marketing-website/pull/992#discussion_r28307665","pull_request_url":"https://api.github.com/repos/optimizely/marketing-website/pulls/992","_links":{"self":{"href":"https://api.github.com/repos/optimizely/marketing-website/pulls/comments/28307665"},"html":{"href":"https://github.com/optimizely/marketing-website/pull/992#discussion_r28307665"},"pull_request":{"href":"https://api.github.com/repos/optimizely/marketing-website/pulls/992"}}},"pull_request":{"url":"https://api.github.com/repos/optimizely/marketing-website/pulls/992","id":33113055,"html_url":"https://github.com/optimizely/marketing-website/pull/992","diff_url":"https://github.com/optimizely/marketing-website/pull/992.diff","patch_url":"https://github.com/optimizely/marketing-website/pull/992.patch","issue_url":"https://api.github.com/repos/optimizely/marketing-website/issues/992","number":992,"state":"open","locked":false,"title":"Add webpack","user":{"login":"dtothefp","id":4656726,"avatar_url":"https://avatars.githubusercontent.com/u/4656726?v=3","gravatar_id":"","url":"https://api.github.com/users/dtothefp","html_url":"https://github.com/dtothefp","followers_url":"https://api.github.com/users/dtothefp/followers","following_url":"https://api.github.com/users/dtothefp/following{/other_user}","gists_url":"https://api.github.com/users/dtothefp/gists{/gist_id}","starred_url":"https://api.github.com/users/dtothefp/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dtothefp/subscriptions","organizations_url":"https://api.github.com/users/dtothefp/orgs","repos_url":"https://api.github.com/users/dtothefp/repos","events_url":"https://api.github.com/users/dtothefp/events{/privacy}","received_events_url":"https://api.github.com/users/dtothefp/received_events","type":"User","site_admin":false},"body":"This PR addresses adding webpack module loader into the marketing repo.  I know this implementation isn't a very \"webpack\" way, but I'm first trying to mimic our build behavior that was happening with the `concat` task to get everything working, and then go back and refactor. \r\n\r\n#### Issues:\r\n- [x] Build does not use `grunt-webpack` but rather the webpack API within a `grunt.registerTask`. This was much more advantageous for usage of env configs appended on the grunt object that the webpack task depends upon.\r\n- [x] Add inline sourcemap support. Must add the `website-guts` directory to the [chrome dev tools workspace](https://developer.chrome.com/devtools/docs/workspaces).\r\n- [x] Dev and production config, in prod Uglify and Dedupe, in dev add the Hot Module Replacement plugin in preparation to convert to Webpack Dev Server for dev livereload.\r\n- [x] Bundling vendor files (along with global JS) into one file and making their globals available outside of the bundle.  Currently, I'm accomplishing this through the `script-loader`, which seems to concat all files into a string and call `eval` on it.  Libraries are required directly from Bower in `global.js` and bundles with all other global files.\r\n- [x] Mimicking `concat` behavior for the `namespacePages` target https://github.com/optimizely/marketing-website/blob/master/grunt/concat.js. i.e. separate bundles will be created for `page` and `layout` level JS and they will be output to `dist/assets/js` directory in the appropriate directory structure `layout/*.js` or `page/*.js`.  \r\n- [x] Create banner and footer wrapper using `inject-filename-loader` which injects a `targetName` variable for JS error logging of bundles in try/catch blocks in staging/prod.\r\n- [ ] Handlebars is being bundled more than once.  Once in global.js and additional times in page/layout js. Find a way to have handlebars only bundles once, or bundled globally and not included in the hbs-loader requires. Was recommended the [Common Chunks Plugin](https://github.com/webpack/docs/wiki/list-of-plugins#user-content-commonschunkplugin) ( not merge blocking )\r\n- [x] Move JSHint into webpack. All JSHint is happening through webpack except for the linting the test and server side files. JSHint config for all tasks is still necessary as it is `require`d in the `webpack` grunt task.\r\n- [x] Om (PPC) pages not using webpack, still using concat. This is because these must support very old browsers and must maintain their separate build environment.\r\n\r\n### To Test\r\n\r\nmake sure to `rm -rf node_modules && npm cache clear && npm i`\r\n`rm -rf bower_components && bower cache clean && bower i`\r\nrun `grunt server`\r\n- watch the build, that webpack compiles correctly. It will be halted on any JSHint errors.\r\n- inspect your console to make sure there are no JS errors\r\n- inspect the dist directory and see that all of the JS files have an associate inline source map and that individual modules are wrapped in the closure transforming window and document to `w` and `d`, respectively.\r\n- test a page like `/events` that uses a client side handlebars template. These are now being compiled with the webpack handlebars loader.\r\n- in the `grunt/webpack/index.js` file find the `opts` object.  Append a `console.log(targetName)` to the end of the query string \r\n```js\r\ninjectFileNameParams: [\r\n        'inject=' + encodeURIComponent('var targetName = __filename.replace(\"website-guts/assets/js/\", \"\");\\n\\nconsole.log(targetName);\\n\\n'),\r\n        '&banner=' + encodeURIComponent(banner),\r\n        '&footer=' + encodeURIComponent(footer)\r\n      ].join('')\r\n```\r\nrun the `grunt server` task again.  You will see all individual JS module file names logged.  This is what is used in error reporting to GA and debugging in production.\r\n\r\n- check [Staging](https://www.optimizelystaging.com/dfoxpowell/webpack-integration/pricing/)\r\n- look in `website-guts/assets/js/global.js` and see how the `require` functions bootstrap the JS in a particular order and omits certain files using a RegEx with `require.context`.  This order is important for internal dependencies\r\n- play around with some es6 if you want\r\n- throw an error in the JS and check that it maps back to the appropriate source file through the source map http://cl.ly/27173s2T3p00\r\n- run grunt build and inspect that inline source maps are not present and that individual modules are wrapped in try/catch blocks and that code has been uglified\r\n- run the tests: \r\n```\r\ngrunt server\r\ngrunt ui-test //in a separate tab\r\n\r\ngrunt test //run this instead of the two commands above\r\n```\r\n\r\n### Enhancements\r\n- we can now write es6\r\n- source maps for local JS debugging\r\n- JSHint inside webpack\r\n- elimination of handlebars task - handlebars compiled on the fly in webpack loader. Also webpack loader handlebars has the same syntax as Assemble v6 for handlebars helpers which will be helpful for @4vanger `tr` helper.\r\n- drastic reduction of code in concat, JSHint, and uglify task\r\n- Handlebars is no longer required in the vendor dependencies\r\n- future elimination of globals substituted by `require`s\r\n- JS files are watched by webpack which applies a cache. First build is slowish, but subsequent live changes with server running are fast.\r\n- probably lots of other stuff I'm not thinking of\r\n\r\n### Additional\r\n- removed `yepnope` from `bower.json`. We deprecated this a long time ago.  `moment` was also removed and is now being `require`d from NPM","created_at":"2015-04-12T01:20:11Z","updated_at":"2015-04-14T08:13:01Z","closed_at":null,"merged_at":null,"merge_commit_sha":"8f3dba8657bf45ca4fdc4bb08fc5127407dfe868","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/optimizely/marketing-website/pulls/992/commits","review_comments_url":"https://api.github.com/repos/optimizely/marketing-website/pulls/992/comments","review_comment_url":"https://api.github.com/repos/optimizely/marketing-website/pulls/comments{/number}","comments_url":"https://api.github.com/repos/optimizely/marketing-website/issues/992/comments","statuses_url":"https://api.github.com/repos/optimizely/marketing-website/statuses/d77fa62a338c9d7b6152771a505a0d48d7ccb3d3","head":{"label":"optimizely:dfoxpowell/webpack-integration","ref":"dfoxpowell/webpack-integration","sha":"d77fa62a338c9d7b6152771a505a0d48d7ccb3d3","user":{"login":"optimizely","id":1274132,"avatar_url":"https://avatars.githubusercontent.com/u/1274132?v=3","gravatar_id":"","url":"https://api.github.com/users/optimizely","html_url":"https://github.com/optimizely","followers_url":"https://api.github.com/users/optimizely/followers","following_url":"https://api.github.com/users/optimizely/following{/other_user}","gists_url":"https://api.github.com/users/optimizely/gists{/gist_id}","starred_url":"https://api.github.com/users/optimizely/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/optimizely/subscriptions","organizations_url":"https://api.github.com/users/optimizely/orgs","repos_url":"https://api.github.com/users/optimizely/repos","events_url":"https://api.github.com/users/optimizely/events{/privacy}","received_events_url":"https://api.github.com/users/optimizely/received_events","type":"Organization","site_admin":false},"repo":{"id":16794397,"name":"marketing-website","full_name":"optimizely/marketing-website","owner":{"login":"optimizely","id":1274132,"avatar_url":"https://avatars.githubusercontent.com/u/1274132?v=3","gravatar_id":"","url":"https://api.github.com/users/optimizely","html_url":"https://github.com/optimizely","followers_url":"https://api.github.com/users/optimizely/followers","following_url":"https://api.github.com/users/optimizely/following{/other_user}","gists_url":"https://api.github.com/users/optimizely/gists{/gist_id}","starred_url":"https://api.github.com/users/optimizely/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/optimizely/subscriptions","organizations_url":"https://api.github.com/users/optimizely/orgs","repos_url":"https://api.github.com/users/optimizely/repos","events_url":"https://api.github.com/users/optimizely/events{/privacy}","received_events_url":"https://api.github.com/users/optimizely/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/optimizely/marketing-website","description":"Optimizely's marketing website","fork":false,"url":"https://api.github.com/repos/optimizely/marketing-website","forks_url":"https://api.github.com/repos/optimizely/marketing-website/forks","keys_url":"https://api.github.com/repos/optimizely/marketing-website/keys{/key_id}","collaborators_url":"https://api.github.com/repos/optimizely/marketing-website/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/optimizely/marketing-website/teams","hooks_url":"https://api.github.com/repos/optimizely/marketing-website/hooks","issue_events_url":"https://api.github.com/repos/optimizely/marketing-website/issues/events{/number}","events_url":"https://api.github.com/repos/optimizely/marketing-website/events","assignees_url":"https://api.github.com/repos/optimizely/marketing-website/assignees{/user}","branches_url":"https://api.github.com/repos/optimizely/marketing-website/branches{/branch}","tags_url":"https://api.github.com/repos/optimizely/marketing-website/tags","blobs_url":"https://api.github.com/repos/optimizely/marketing-website/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/optimizely/marketing-website/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/optimizely/marketing-website/git/refs{/sha}","trees_url":"https://api.github.com/repos/optimizely/marketing-website/git/trees{/sha}","statuses_url":"https://api.github.com/repos/optimizely/marketing-website/statuses/{sha}","languages_url":"https://api.github.com/repos/optimizely/marketing-website/languages","stargazers_url":"https://api.github.com/repos/optimizely/marketing-website/stargazers","contributors_url":"https://api.github.com/repos/optimizely/marketing-website/contributors","subscribers_url":"https://api.github.com/repos/optimizely/marketing-website/subscribers","subscription_url":"https://api.github.com/repos/optimizely/marketing-website/subscription","commits_url":"https://api.github.com/repos/optimizely/marketing-website/commits{/sha}","git_commits_url":"https://api.github.com/repos/optimizely/marketing-website/git/commits{/sha}","comments_url":"https://api.github.com/repos/optimizely/marketing-website/comments{/number}","issue_comment_url":"https://api.github.com/repos/optimizely/marketing-website/issues/comments{/number}","contents_url":"https://api.github.com/repos/optimizely/marketing-website/contents/{+path}","compare_url":"https://api.github.com/repos/optimizely/marketing-website/compare/{base}...{head}","merges_url":"https://api.github.com/repos/optimizely/marketing-website/merges","archive_url":"https://api.github.com/repos/optimizely/marketing-website/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/optimizely/marketing-website/downloads","issues_url":"https://api.github.com/repos/optimizely/marketing-website/issues{/number}","pulls_url":"https://api.github.com/repos/optimizely/marketing-website/pulls{/number}","milestones_url":"https://api.github.com/repos/optimizely/marketing-website/milestones{/number}","notifications_url":"https://api.github.com/repos/optimizely/marketing-website/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/optimizely/marketing-website/labels{/name}","releases_url":"https://api.github.com/repos/optimizely/marketing-website/releases{/id}","created_at":"2014-02-13T06:45:06Z","updated_at":"2015-04-10T21:40:24Z","pushed_at":"2015-04-13T16:29:52Z","git_url":"git://github.com/optimizely/marketing-website.git","ssh_url":"git@github.com:optimizely/marketing-website.git","clone_url":"https://github.com/optimizely/marketing-website.git","svn_url":"https://github.com/optimizely/marketing-website","homepage":"https://www.optimizely.com","size":392230,"stargazers_count":17,"watchers_count":17,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":14,"mirror_url":null,"open_issues_count":30,"forks":14,"open_issues":30,"watchers":17,"default_branch":"master"}},"base":{"label":"optimizely:master","ref":"master","sha":"c7b1b6c1720776000b01e784d91513458e1ace75","user":{"login":"optimizely","id":1274132,"avatar_url":"https://avatars.githubusercontent.com/u/1274132?v=3","gravatar_id":"","url":"https://api.github.com/users/optimizely","html_url":"https://github.com/optimizely","followers_url":"https://api.github.com/users/optimizely/followers","following_url":"https://api.github.com/users/optimizely/following{/other_user}","gists_url":"https://api.github.com/users/optimizely/gists{/gist_id}","starred_url":"https://api.github.com/users/optimizely/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/optimizely/subscriptions","organizations_url":"https://api.github.com/users/optimizely/orgs","repos_url":"https://api.github.com/users/optimizely/repos","events_url":"https://api.github.com/users/optimizely/events{/privacy}","received_events_url":"https://api.github.com/users/optimizely/received_events","type":"Organization","site_admin":false},"repo":{"id":16794397,"name":"marketing-website","full_name":"optimizely/marketing-website","owner":{"login":"optimizely","id":1274132,"avatar_url":"https://avatars.githubusercontent.com/u/1274132?v=3","gravatar_id":"","url":"https://api.github.com/users/optimizely","html_url":"https://github.com/optimizely","followers_url":"https://api.github.com/users/optimizely/followers","following_url":"https://api.github.com/users/optimizely/following{/other_user}","gists_url":"https://api.github.com/users/optimizely/gists{/gist_id}","starred_url":"https://api.github.com/users/optimizely/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/optimizely/subscriptions","organizations_url":"https://api.github.com/users/optimizely/orgs","repos_url":"https://api.github.com/users/optimizely/repos","events_url":"https://api.github.com/users/optimizely/events{/privacy}","received_events_url":"https://api.github.com/users/optimizely/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/optimizely/marketing-website","description":"Optimizely's marketing website","fork":false,"url":"https://api.github.com/repos/optimizely/marketing-website","forks_url":"https://api.github.com/repos/optimizely/marketing-website/forks","keys_url":"https://api.github.com/repos/optimizely/marketing-website/keys{/key_id}","collaborators_url":"https://api.github.com/repos/optimizely/marketing-website/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/optimizely/marketing-website/teams","hooks_url":"https://api.github.com/repos/optimizely/marketing-website/hooks","issue_events_url":"https://api.github.com/repos/optimizely/marketing-website/issues/events{/number}","events_url":"https://api.github.com/repos/optimizely/marketing-website/events","assignees_url":"https://api.github.com/repos/optimizely/marketing-website/assignees{/user}","branches_url":"https://api.github.com/repos/optimizely/marketing-website/branches{/branch}","tags_url":"https://api.github.com/repos/optimizely/marketing-website/tags","blobs_url":"https://api.github.com/repos/optimizely/marketing-website/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/optimizely/marketing-website/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/optimizely/marketing-website/git/refs{/sha}","trees_url":"https://api.github.com/repos/optimizely/marketing-website/git/trees{/sha}","statuses_url":"https://api.github.com/repos/optimizely/marketing-website/statuses/{sha}","languages_url":"https://api.github.com/repos/optimizely/marketing-website/languages","stargazers_url":"https://api.github.com/repos/optimizely/marketing-website/stargazers","contributors_url":"https://api.github.com/repos/optimizely/marketing-website/contributors","subscribers_url":"https://api.github.com/repos/optimizely/marketing-website/subscribers","subscription_url":"https://api.github.com/repos/optimizely/marketing-website/subscription","commits_url":"https://api.github.com/repos/optimizely/marketing-website/commits{/sha}","git_commits_url":"https://api.github.com/repos/optimizely/marketing-website/git/commits{/sha}","comments_url":"https://api.github.com/repos/optimizely/marketing-website/comments{/number}","issue_comment_url":"https://api.github.com/repos/optimizely/marketing-website/issues/comments{/number}","contents_url":"https://api.github.com/repos/optimizely/marketing-website/contents/{+path}","compare_url":"https://api.github.com/repos/optimizely/marketing-website/compare/{base}...{head}","merges_url":"https://api.github.com/repos/optimizely/marketing-website/merges","archive_url":"https://api.github.com/repos/optimizely/marketing-website/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/optimizely/marketing-website/downloads","issues_url":"https://api.github.com/repos/optimizely/marketing-website/issues{/number}","pulls_url":"https://api.github.com/repos/optimizely/marketing-website/pulls{/number}","milestones_url":"https://api.github.com/repos/optimizely/marketing-website/milestones{/number}","notifications_url":"https://api.github.com/repos/optimizely/marketing-website/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/optimizely/marketing-website/labels{/name}","releases_url":"https://api.github.com/repos/optimizely/marketing-website/releases{/id}","created_at":"2014-02-13T06:45:06Z","updated_at":"2015-04-10T21:40:24Z","pushed_at":"2015-04-13T16:29:52Z","git_url":"git://github.com/optimizely/marketing-website.git","ssh_url":"git@github.com:optimizely/marketing-website.git","clone_url":"https://github.com/optimizely/marketing-website.git","svn_url":"https://github.com/optimizely/marketing-website","homepage":"https://www.optimizely.com","size":392230,"stargazers_count":17,"watchers_count":17,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":14,"mirror_url":null,"open_issues_count":30,"forks":14,"open_issues":30,"watchers":17,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/optimizely/marketing-website/pulls/992"},"html":{"href":"https://github.com/optimizely/marketing-website/pull/992"},"issue":{"href":"https://api.github.com/repos/optimizely/marketing-website/issues/992"},"comments":{"href":"https://api.github.com/repos/optimizely/marketing-website/issues/992/comments"},"review_comments":{"href":"https://api.github.com/repos/optimizely/marketing-website/pulls/992/comments"},"review_comment":{"href":"https://api.github.com/repos/optimizely/marketing-website/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/optimizely/marketing-website/pulls/992/commits"},"statuses":{"href":"https://api.github.com/repos/optimizely/marketing-website/statuses/d77fa62a338c9d7b6152771a505a0d48d7ccb3d3"}}}}