{"id":20610,"date":"2017-12-12T09:13:50","date_gmt":"2017-12-12T14:13:50","guid":{"rendered":"https:\/\/www.bloomberg.com\/company\/stories\/wsk-straightforward-maintainable-build-system-bloomberg-graphics-team\/"},"modified":"2022-03-04T23:11:40","modified_gmt":"2022-03-05T04:11:40","slug":"wsk-straightforward-maintainable-build-system-bloomberg-graphics-team","status":"publish","type":"post","link":"https:\/\/www.bloomberg.com\/company\/stories\/wsk-straightforward-maintainable-build-system-bloomberg-graphics-team\/","title":{"rendered":"wsk: A Straightforward and Maintainable Build System from the Bloomberg Graphics Team"},"content":{"rendered":"<div class='bbg-row bbg-bg--white  bbg-row--margin-top-none bbg-row--margin-bottom-none' data-anchor='row-6a04ccd486cf3'>\n  \n\t\n\t\n\t<div class=\"bbg-row--content\">\n\t\t\n\t\t\t<div class='bbg-column bbg-column--width-8 bbg-column--offset-2'>\n\t<div class='bb-wysiwyg'>\n    \n    <h2><em>An introduction to wsk, a\u00a0straightforward and maintainable build system, by one of its contributors, data journalist Michael Keller of the\u00a0<\/em><em>Bloomberg Graphics team<\/em><\/h2>\n\n<\/div>\n<div class=\"bb-separator\" data-color=\"\">\n\t<hr class=\"bb-separator__rule\">\n<\/div>\n<div class='bb-wysiwyg'>\n    \n    <p>At the start of 2016, we on the <a href=\"https:\/\/bloomberg.com\/graphics\" target=\"_blank\" rel=\"noopener noreferrer\">Bloomberg News Graphics<\/a> team were looking to build a new project creation system. Our setup at the time largely left it up to the project creator to manage how files were built. While this gave creators flexibility, we thought a little more structure and common ground would be helpful.<\/p>\n<h2>Our goals<\/h2>\n<p>Flexibility was an important element to preserve because our team is composed of journalists, designers and developers who create visual news stories on deadline. Each project might be different and need modifications to react to an unfolding news event.<\/p>\n<p>Our build system would have to meet the following requirements (in no particular order):<\/p>\n<ul>\n<li>Be flexible and extensible for people on our team unfamiliar with the latest build system frameworks.<\/li>\n<li>Provide rich feedback so that if the user did something wrong, it would try to help them correct it.<\/li>\n<li>Make clear what was a problem with <strong>the project<\/strong> versus a problem with <strong>the build system<\/strong>. This was critical during the adoption phase.<\/li>\n<li>Not close off possibilities or lock us into one way of doing things.<\/li>\n<li>Each of our projects is a custom design. We didn&#8217;t want a system that constrained creativity or had an architecture that slowed down implementation of new features (such as waiting for dependencies to exist or be updated).<\/li>\n<\/ul>\n<h2>What was out there<\/h2>\n<p>The most common choices, at the time, were <a href=\"mailto:https:\/\/gulpjs.com\/\" target=\"_blank\" rel=\"noopener noreferrer\">Gulp<\/a> and <a href=\"https:\/\/webpack.js.org\/\" target=\"_blank\" rel=\"noopener noreferrer\">Webpack<\/a>. We ended up not choosing either of them because each had elements that went against at least one of our goals.<\/p>\n<ul>\n<li>Writing a Gulp plugin, for example, requires knowledge of streams, which is a barrier to entry.<\/li>\n<li>Console feedback tells you that a task happened and how long it took but not what it did, specifically.<\/li>\n<li>Gulp requires an ecosystem of plugins. If you want to use <a href=\"https:\/\/sass-lang.com\/\" target=\"_blank\" rel=\"noopener noreferrer\">Sass<\/a>, you rely on <code>gulp-sass<\/code>, which <a href=\"https:\/\/github.com\/dlmanning\/gulp-sass\/issues\/621\" target=\"_blank\" rel=\"noopener noreferrer\">might not be up to date<\/a> or it might introduce its own bugs.<\/li>\n<li>Webpack tends to take full ownership over the whole process; breaking off pieces of it or adding to it can be difficult. This might close off possibilities or require us to find &#8220;the Webpack way&#8221; of doing a given transformation if a project creator wanted it done.<\/li>\n<\/ul>\n<h2>Where we started<\/h2>\n<p>Our first approach in service of these goals was to use vanilla npm scripts and the command-line interfaces for the libraries we wanted to use. We used <a href=\"https:\/\/github.com\/kimmobrunfeldt\/chokidar-cli\" target=\"_blank\" rel=\"noopener noreferrer\">chokidar-cli<\/a> to trigger actions when files changed. Our <code>package.json<\/code> looked like this:<br \/>\n<a href=\"https:\/\/assets.bbhub.io\/company\/sites\/51\/2017\/12\/npm-scripts-v1.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/assets.bbhub.io\/company\/sites\/51\/2017\/12\/npm-scripts-v1-1024x584.png\" alt=\"\" width=\"1024\" height=\"584\" class=\"alignnone size-large wp-image-36301\" \/><\/a><\/p>\n<p>The functionality was okay, but we saw very inconsistent console output.<br \/>\n<a href=\"https:\/\/assets.bbhub.io\/company\/sites\/51\/2017\/12\/npm-scripts-v1-output.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/assets.bbhub.io\/company\/sites\/51\/2017\/12\/npm-scripts-v1-output-1024x630.png\" alt=\"\" width=\"1024\" height=\"630\" class=\"alignnone size-large wp-image-36302\" \/><\/a><\/p>\n<p>This concern goes beyond aesthetics. If the console is sending differently-styled output on changes, the user has to interpret multiple signals. This is distracting and makes it harder to recognize actionable feedback.<\/p>\n<p>It would be better if normal compile messages were in a consistent format. Errors should appear in a different color and with a stack trace, if possible, to break up the formatting. The user can detect these changes more easily and attend to them.<\/p>\n<p>Cognitively, the eye is better at noticing movement in the periphery of vision than it is at catching detail. If the build console is in the corner of the screen monitor, it&#8217;s easier to notice a disruption if there&#8217;s a break in consistency than if you have a number of variable-length messages printing all the time.<\/p>\n<p>Since we were implementing a build system where one previously did not exist, clear notifications were important to separate system errors from project errors. It&#8217;s very easy to blame the new, unknown thing when there&#8217;s an error. Descriptive build notifications can help the user diagnose a problem with the project more quickly.<\/p>\n<h2>Improving console outputs<\/h2>\n<p>The first attempt at trying to make console outputs more consistent was piping them to a script that would standardize them. Here&#8217;s the new output:<br \/>\n<a href=\"https:\/\/assets.bbhub.io\/company\/sites\/51\/2017\/12\/npm-scripts-v2-output.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/assets.bbhub.io\/company\/sites\/51\/2017\/12\/npm-scripts-v2-output-1024x660.png\" alt=\"\" width=\"1024\" height=\"660\" class=\"alignnone size-large wp-image-36304\" \/><\/a><\/p>\n<p>The problems:<\/p>\n<ol>\n<li>This was a lot of work that would likely need to be redone if a library modified its output style.<\/li>\n<li>It would require more work if we changed libraries, in opposition to our first goal.<\/li>\n<li>It made our <code>package.json<\/code> very difficult to read, also in opposition to that goal for anyone who wanted to edit their npm scripts. Here&#8217;s what that looked like:<\/li>\n<\/ol>\n<p><a href=\"https:\/\/assets.bbhub.io\/company\/sites\/51\/2017\/12\/npm-scripts-v2.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/assets.bbhub.io\/company\/sites\/51\/2017\/12\/npm-scripts-v2-1024x164.png\" alt=\"\" width=\"1024\" height=\"164\" class=\"alignnone size-large wp-image-36303\" \/><\/a><\/p>\n<p>Because each of these scripts handles its output differently, we had to pipe console messages all over the place. Some went to <code>\/dev\/null<\/code>; others used <code>2&gt;&amp;1<\/code> to redirect stderr to stdout. It was a mess.<\/p>\n<h2>A better setup<\/h2>\n<p>These experiments led us to create <a href=\"https:\/\/github.com\/bloomberg\/wsk\" target=\"_blank\" rel=\"noopener noreferrer\">wsk<\/a> and <a href=\"https:\/\/github.com\/bloomberg\/wsk-notify\" target=\"_blank\" rel=\"noopener noreferrer\">wsk-notify<\/a>, which is our current setup. wsk is a watcher specification around <a href=\"https:\/\/github.com\/paulmillr\/chokidar\" target=\"_blank\" rel=\"noopener noreferrer\">chokidar<\/a> that makes it easier to declare a glob of files to watch and vanilla JavaScript modules to run when those files change. wsk-notify is a module for standardized console and desktop notifications.<\/p>\n<p>This setup works with our goals because:<\/p>\n<ol>\n<li>No special knowledge is required to write a task file (a &#8220;plugin&#8221; using Gulp vocabulary).<\/li>\n<li>By using chokidar to watch files, we get access to a diverse set of events. Our notifications can report exactly what events are happening and what tasks are being dispatched as a result.<\/li>\n<li>By using libraries directly, we avoid intermediate plugins as much as we can.<\/li>\n<\/ol>\n<p>Although we passed over using command-line APIs for other reasons, we found that using libraries directly via their JavaScript API also increased the number of options we had when using them. That makes intuitive sense, as you can only squeeze so much functionality into command-line flags.<\/p>\n<h2>Usage<\/h2>\n<p>An example wsk watcher file looks something like this:<\/p>\n<pre><code><span style=\"color: #6a737d\">\/\/ sass-watch.js<\/span>\r\n\r\n<span style=\"color: #d73a49\">var<\/span> watcher = <span style=\"color: #005cc5\">require<\/span>(<span style=\"color: #22863a\">'wsk'<\/span>).<span style=\"color: #005cc5\">watcher<\/span>;\r\n\r\n<span style=\"color: #d73a49\">var<\/span> watchGroup = {\r\n  serviceName: <span style=\"color: #22863a\">'sass'<\/span>,\r\n  path: <span style=\"color: #22863a\">'src\/css\/*.scss'<\/span>,\r\n  events: [\r\n    {\r\n      type: <span style=\"color: #22863a\">'change'<\/span>,\r\n      taskFiles: <span style=\"color: #22863a\">'build\/tasks\/sass\/onChange.js'<\/span>,\r\n      options: {\r\n        foo: <span style=\"color: #d73a49\">true<\/span>\r\n      }\r\n    },\r\n    {\r\n      type: <span style=\"color: #22863a\">'change'<\/span>,\r\n      taskFiles: <span style=\"color: #22863a\">'build\/tasks\/sass\/onAdd.js'<\/span>\r\n    },\r\n    {\r\n      type: <span style=\"color: #22863a\">'unlink'<\/span>,\r\n      taskFiles: <span style=\"color: #22863a\">'build\/tasks\/sass\/onUnlink.js'<\/span>\r\n    }\r\n  ]\r\n};\r\n\r\nwatcher.<span style=\"color: #005cc5\">add<\/span>(watchGroup);<\/code><\/pre>\n<p>The only requirement for a task file is that it export an <code>onEvent<\/code> function which takes the event type listed in <code>type<\/code> above, the path of the file that changed and any options specified. Anything you put in that function is up to you.<\/p>\n<pre><code><span style=\"color: #6a737d\">\/\/ onChange.js<\/span>\r\n<span style=\"color: #d73a49\">var<\/span> notify = <span style=\"color: #005cc5\">require<\/span>(<span style=\"color: #22863a\">'wsk'<\/span>).<span style=\"color: #005cc5\">notify<\/span>;\r\n\r\nmodule.<span style=\"color: #005cc5\">exports<\/span> = <span style=\"color: #d73a49\">function<\/span> (eventType, filePath, options) {\r\n  <span style=\"color: #6a737d\">\/\/ Put library transform here<\/span>\r\n  <span style=\"color: #6a737d\">\/\/ Write the transformed file with `fs.writeFile`, for example<\/span>\r\n  <span style=\"color: #6a737d\">\/\/ Notify user the file was written<\/span>\r\n  <span style=\"color: #005cc5\">notify<\/span>({\r\n    message: <span style=\"color: #22863a\">'Compiled CSS file...'<\/span>  ,\r\n    value: filePath.<span style=\"color: #005cc5\">replace<\/span>(<span style=\"color: #22863a\">'src'<\/span>, <span style=\"color: #22863a\">'public'<\/span>),\r\n    display: <span style=\"color: #22863a\">'compile'<\/span>\r\n  });\r\n};<\/code><\/pre>\n<h2>Conclusion<\/h2>\n<p>We built wsk to address our mix of skills and constraints. It might not be the right solution for everyone, but if you&#8217;ve run into issues with other plugins, been constrained by adding extra concepts into your pipeline (such as streams), or been frustrated when you want to use a new library and had to look for a &#8220;How to use with Webpack\/Gulp\/Grunt&#8221; section of the readme, wsk might be helpful for you.<\/p>\n<p>Over the last 18 months of usage, it&#8217;s proven to be a flexible and maintainable system. It has powered projects as simple as <a href=\"https:\/\/www.bloomberg.com\/graphics\/2016-takata-recall\/\" target=\"_blank\" rel=\"noopener noreferrer\">one-off graphics<\/a> to <a href=\"https:\/\/www.bloomberg.com\/politics\/graphics\/2016-bus-to-november\/\" target=\"_blank\" rel=\"noopener noreferrer\">multi-day<\/a> or <a href=\"https:\/\/www.bloomberg.com\/graphics\/2016-asia-space-race\/\" target=\"_blank\" rel=\"noopener noreferrer\">multi-page<\/a> <a href=\"https:\/\/www.bloomberg.com\/graphics\/2017-arctic\/\" target=\"_blank\" rel=\"noopener noreferrer\">series<\/a> that function more like static-site generators.<\/p>\n<p>You can find usage examples and more documentation on the <a href=\"https:\/\/bloomberg.github.io\/wsk\" target=\"_blank\" rel=\"noopener noreferrer\">wsk<\/a> and <a href=\"https:\/\/bloomberg.github.io\/wsk-notify\" target=\"_blank\" rel=\"noopener noreferrer\">wsk-notify<\/a> sites.<\/p>\n\n<\/div>\n<figure class=\"image-figure\" data-animation=\"\">\n    <img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"634\" src=\"https:\/\/assets.bbhub.io\/image\/v1\/resize?width=auto&amp;type=webp&amp;url=https:\/\/assets.bbhub.io\/company\/sites\/51\/2017\/12\/wsk-docs-screenshot.png\" class=\"attachment-large size-large image-figure__image image-figure__image--primary\" alt=\"\" srcset=\"https:\/\/assets.bbhub.io\/image\/v1\/resize?width=auto&amp;type=webp&amp;url=https:\/\/assets.bbhub.io\/company\/sites\/51\/2017\/12\/wsk-docs-screenshot.png 1024w, https:\/\/assets.bbhub.io\/image\/v1\/resize?width=auto&amp;type=webp&amp;url=https:\/\/assets.bbhub.io\/company\/sites\/51\/2017\/12\/wsk-docs-screenshot.png 300w, https:\/\/assets.bbhub.io\/image\/v1\/resize?width=auto&amp;type=webp&amp;url=https:\/\/assets.bbhub.io\/company\/sites\/51\/2017\/12\/wsk-docs-screenshot.png 768w, https:\/\/assets.bbhub.io\/image\/v1\/resize?width=auto&amp;type=webp&amp;url=https:\/\/assets.bbhub.io\/company\/sites\/51\/2017\/12\/wsk-docs-screenshot.png 170w, https:\/\/assets.bbhub.io\/image\/v1\/resize?width=auto&amp;type=webp&amp;url=https:\/\/assets.bbhub.io\/company\/sites\/51\/2017\/12\/wsk-docs-screenshot.png 140w, https:\/\/assets.bbhub.io\/image\/v1\/resize?width=auto&amp;type=webp&amp;url=https:\/\/assets.bbhub.io\/company\/sites\/51\/2017\/12\/wsk-docs-screenshot.png 1096w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/>\n    \n<\/figure>\n<\/p>\n\n<\/div>\n\n\n\t\t\n\t<\/div>\n<\/div>\n\n","protected":false},"excerpt":{"rendered":"<p>A new open source build system to help create Web projects<\/p>\n","protected":false},"author":313,"featured_media":19561,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1466],"tags":[1490,1464],"class_list":["post-20610","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-tech-at-bloomberg","tag-javascript","tag-open-source"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v19.11 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>wsk: A Straightforward and Maintainable Build System from the Bloomberg Graphics Team | Bloomberg LP<\/title>\n<meta name=\"description\" content=\"An introduction to wsk, a\u00a0straightforward and maintainable open source build system, built by Bloomberg&#039;s Graphics &amp; Data Journalism team to build projects.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.bloomberg.com\/company\/stories\/wsk-straightforward-maintainable-build-system-bloomberg-graphics-team\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"wsk: A Straightforward and Maintainable Build System from the Bloomberg Graphics Team | Bloomberg LP\" \/>\n<meta property=\"og:description\" content=\"An introduction to wsk, a\u00a0straightforward and maintainable open source build system, built by Bloomberg&#039;s Graphics &amp; Data Journalism team to build projects.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.bloomberg.com\/company\/stories\/wsk-straightforward-maintainable-build-system-bloomberg-graphics-team\/\" \/>\n<meta property=\"og:site_name\" content=\"Bloomberg L.P.\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/bloomberglp\/\" \/>\n<meta property=\"article:published_time\" content=\"2017-12-12T14:13:50+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2022-03-05T04:11:40+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/assets.bbhub.io\/company\/sites\/51\/2017\/12\/wsk-docs-screenshot.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1096\" \/>\n\t<meta property=\"og:image:height\" content=\"679\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"akelber5\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:image\" content=\"https:\/\/assets.bbhub.io\/company\/sites\/51\/2017\/12\/wsk-docs-screenshot.png\" \/>\n<meta name=\"twitter:creator\" content=\"@bloomberg\" \/>\n<meta name=\"twitter:site\" content=\"@bloomberg\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"akelber5\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"6 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.bloomberg.com\/company\/stories\/wsk-straightforward-maintainable-build-system-bloomberg-graphics-team\/\",\"url\":\"https:\/\/www.bloomberg.com\/company\/stories\/wsk-straightforward-maintainable-build-system-bloomberg-graphics-team\/\",\"name\":\"wsk: A Straightforward and Maintainable Build System from the Bloomberg Graphics Team | Bloomberg LP\",\"isPartOf\":{\"@id\":\"https:\/\/www.bloomberg.com\/company\/#website\"},\"datePublished\":\"2017-12-12T14:13:50+00:00\",\"dateModified\":\"2022-03-05T04:11:40+00:00\",\"author\":{\"@id\":\"https:\/\/www.bloomberg.com\/company\/#\/schema\/person\/09c9e1a38b7f345ce5c0b4bbde1656a6\"},\"description\":\"An introduction to wsk, a\u00a0straightforward and maintainable open source build system, built by Bloomberg's Graphics & Data Journalism team to build projects.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.bloomberg.com\/company\/stories\/wsk-straightforward-maintainable-build-system-bloomberg-graphics-team\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.bloomberg.com\/company\/stories\/wsk-straightforward-maintainable-build-system-bloomberg-graphics-team\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.bloomberg.com\/company\/stories\/wsk-straightforward-maintainable-build-system-bloomberg-graphics-team\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":\"1\",\"name\":\"Home\",\"item\":\"https:\/\/www.bloomberg.com\/company\/\"},{\"@type\":\"ListItem\",\"position\":\"2\",\"name\":\"wsk: A Straightforward and Maintainable Build System from the Bloomberg Graphics Team\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.bloomberg.com\/company\/#website\",\"url\":\"https:\/\/www.bloomberg.com\/company\/\",\"name\":\"Bloomberg L.P.\",\"description\":\"Bloomberg L.P. is the leader in global business and financial information, enabling customers to make smarter, faster, more informed business decisions.\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.bloomberg.com\/company\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.bloomberg.com\/company\/#\/schema\/person\/09c9e1a38b7f345ce5c0b4bbde1656a6\",\"name\":\"Bloomberg L.P.\",\"url\":\"https:\/\/www.bloomberg.com\/company\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"wsk: A Straightforward and Maintainable Build System from the Bloomberg Graphics Team | Bloomberg LP","description":"An introduction to wsk, a\u00a0straightforward and maintainable open source build system, built by Bloomberg's Graphics & Data Journalism team to build projects.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.bloomberg.com\/company\/stories\/wsk-straightforward-maintainable-build-system-bloomberg-graphics-team\/","og_locale":"en_US","og_type":"article","og_title":"wsk: A Straightforward and Maintainable Build System from the Bloomberg Graphics Team | Bloomberg LP","og_description":"An introduction to wsk, a\u00a0straightforward and maintainable open source build system, built by Bloomberg's Graphics & Data Journalism team to build projects.","og_url":"https:\/\/www.bloomberg.com\/company\/stories\/wsk-straightforward-maintainable-build-system-bloomberg-graphics-team\/","og_site_name":"Bloomberg L.P.","article_publisher":"https:\/\/www.facebook.com\/bloomberglp\/","article_published_time":"2017-12-12T14:13:50+00:00","article_modified_time":"2022-03-05T04:11:40+00:00","og_image":[{"width":1096,"height":679,"url":"https:\/\/assets.bbhub.io\/company\/sites\/51\/2017\/12\/wsk-docs-screenshot.png","type":"image\/png"}],"author":"akelber5","twitter_card":"summary_large_image","twitter_image":"https:\/\/assets.bbhub.io\/company\/sites\/51\/2017\/12\/wsk-docs-screenshot.png","twitter_creator":"@bloomberg","twitter_site":"@bloomberg","twitter_misc":{"Written by":"akelber5","Est. reading time":"6 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.bloomberg.com\/company\/stories\/wsk-straightforward-maintainable-build-system-bloomberg-graphics-team\/","url":"https:\/\/www.bloomberg.com\/company\/stories\/wsk-straightforward-maintainable-build-system-bloomberg-graphics-team\/","name":"wsk: A Straightforward and Maintainable Build System from the Bloomberg Graphics Team | Bloomberg LP","isPartOf":{"@id":"https:\/\/www.bloomberg.com\/company\/#website"},"datePublished":"2017-12-12T14:13:50+00:00","dateModified":"2022-03-05T04:11:40+00:00","author":{"@id":"https:\/\/www.bloomberg.com\/company\/#\/schema\/person\/09c9e1a38b7f345ce5c0b4bbde1656a6"},"description":"An introduction to wsk, a\u00a0straightforward and maintainable open source build system, built by Bloomberg's Graphics & Data Journalism team to build projects.","breadcrumb":{"@id":"https:\/\/www.bloomberg.com\/company\/stories\/wsk-straightforward-maintainable-build-system-bloomberg-graphics-team\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.bloomberg.com\/company\/stories\/wsk-straightforward-maintainable-build-system-bloomberg-graphics-team\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.bloomberg.com\/company\/stories\/wsk-straightforward-maintainable-build-system-bloomberg-graphics-team\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":"1","name":"Home","item":"https:\/\/www.bloomberg.com\/company\/"},{"@type":"ListItem","position":"2","name":"wsk: A Straightforward and Maintainable Build System from the Bloomberg Graphics Team"}]},{"@type":"WebSite","@id":"https:\/\/www.bloomberg.com\/company\/#website","url":"https:\/\/www.bloomberg.com\/company\/","name":"Bloomberg L.P.","description":"Bloomberg L.P. is the leader in global business and financial information, enabling customers to make smarter, faster, more informed business decisions.","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.bloomberg.com\/company\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.bloomberg.com\/company\/#\/schema\/person\/09c9e1a38b7f345ce5c0b4bbde1656a6","name":"Bloomberg L.P.","url":"https:\/\/www.bloomberg.com\/company"}]}},"featured_image_rendered":"<img srcset='https:\/\/assets.bbhub.io\/image\/v1\/resize?width=auto&type=webp&url=https:\/\/assets.bbhub.io\/company\/sites\/51\/2017\/12\/wsk-docs-screenshot.png 1096w, https:\/\/assets.bbhub.io\/image\/v1\/resize?width=auto&type=webp&url=https:\/\/assets.bbhub.io\/company\/sites\/51\/2017\/12\/wsk-docs-screenshot.png 300w, https:\/\/assets.bbhub.io\/image\/v1\/resize?width=auto&type=webp&url=https:\/\/assets.bbhub.io\/company\/sites\/51\/2017\/12\/wsk-docs-screenshot.png 768w, https:\/\/assets.bbhub.io\/image\/v1\/resize?width=auto&type=webp&url=https:\/\/assets.bbhub.io\/company\/sites\/51\/2017\/12\/wsk-docs-screenshot.png 1024w, https:\/\/assets.bbhub.io\/image\/v1\/resize?width=auto&type=webp&url=https:\/\/assets.bbhub.io\/company\/sites\/51\/2017\/12\/wsk-docs-screenshot.png 170w, https:\/\/assets.bbhub.io\/image\/v1\/resize?width=auto&type=webp&url=https:\/\/assets.bbhub.io\/company\/sites\/51\/2017\/12\/wsk-docs-screenshot.png 140w' src='https:\/\/assets.bbhub.io\/image\/v1\/resize?width=auto&type=webp&url=https:\/\/assets.bbhub.io\/company\/sites\/51\/2017\/12\/wsk-docs-screenshot.png' alt='' \/>","category_info":{"name":"Tech At Bloomberg","blog_landing_name":"Tech At Bloomberg"},"_links":{"self":[{"href":"https:\/\/www.bloomberg.com\/company\/wp-json\/wp\/v2\/posts\/20610","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.bloomberg.com\/company\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.bloomberg.com\/company\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.bloomberg.com\/company\/wp-json\/wp\/v2\/users\/313"}],"replies":[{"embeddable":true,"href":"https:\/\/www.bloomberg.com\/company\/wp-json\/wp\/v2\/comments?post=20610"}],"version-history":[{"count":1,"href":"https:\/\/www.bloomberg.com\/company\/wp-json\/wp\/v2\/posts\/20610\/revisions"}],"predecessor-version":[{"id":21789,"href":"https:\/\/www.bloomberg.com\/company\/wp-json\/wp\/v2\/posts\/20610\/revisions\/21789"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.bloomberg.com\/company\/wp-json\/wp\/v2\/media\/19561"}],"wp:attachment":[{"href":"https:\/\/www.bloomberg.com\/company\/wp-json\/wp\/v2\/media?parent=20610"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.bloomberg.com\/company\/wp-json\/wp\/v2\/categories?post=20610"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.bloomberg.com\/company\/wp-json\/wp\/v2\/tags?post=20610"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}