{"id":4345,"date":"2018-05-26T11:05:28","date_gmt":"2018-05-26T09:05:28","guid":{"rendered":"https:\/\/monodes.com\/predaelli\/?p=4345"},"modified":"2018-05-26T11:05:28","modified_gmt":"2018-05-26T09:05:28","slug":"adding-snap-svg-to-vue-js-and-nuxt-js-projects","status":"publish","type":"post","link":"https:\/\/monodes.com\/predaelli\/2018\/05\/26\/adding-snap-svg-to-vue-js-and-nuxt-js-projects\/","title":{"rendered":"Adding Snap.svg to Vue.js and Nuxt.js Projects"},"content":{"rendered":"<p><em><a href=\"https:\/\/jamesscheller.com\/adding-snap-svg-to-vue-js-and-nuxt-js-projects\/\">Adding Snap.svg to Vue.js and Nuxt.js Projects | James Scheller<\/a><\/em><\/p>\n<p><!--more--><!--nextpage--><\/p>\n<blockquote>\n<h4>Getting Snap.svg Working with Vue.js<\/h4>\n<p>Out of the gate, there\u2019s some hurdles because Snap mounts itself on the browser\u2019s window object, so if you\u2019re trying to load Snap through WebPack (as opposed to just including it in a project using a conventional script tag), you need to do some gymnastics to get WebPack\u2019s JavaScript loader to feed the window object into Snap\u2019s initialization logic. You can find an overview of the problem in this <a href=\"https:\/\/github.com\/adobe-webplatform\/Snap.svg\/issues\/341\" target=\"_blank\" rel=\"noopener\">GitHub issue<\/a> which illustrates the obstacles in the context of using React, but the issues as they relate to Vue.js are the same.<\/p>\n<p>I\u2019m assuming you have a Vue.js webpack project that you started with vue-cli or from a template that has everything basically running okay, so you\u2019ve already got Node and webpack and all your other infrastructure in place.<\/p>\n<p>For starters, you\u2019ll want to install Snap.svg and add it to your project dependencies, so from a terminal window open and sitting in the directory where your project\u2019s package.json\/package-lock.json sit\u2026<\/p>\n<pre>npm install --save snapsvg<\/pre>\n<p>That will download and install a copy of the Snap.svg source into your node_modules directory and you\u2019ll have it available for WebPack to grab.<\/p>\n<p>Normally you\u2019d be able to use a package installed like this by using an import statement somewhere, and you\u2019d think you could do this in your Vue project\u2019s main.js file, if you start down this path you\u2019ll get the window undefined issue described in that GitHub link above.<\/p>\n<p>The tricky bit though is getting WebPack to load the Snap properly, and to do that we\u2019ll need a WebPack plugin that lets us load as a JavaScript dependency and pass some bindings to it. So, in that same directory install the WebPack imports-loader plugin\u2026<\/p>\n<pre>npm install --savedev imports-loader<\/pre>\n<p>To tell the imports-loader when it needs to do its magic, we have to add it to the WebPack configuration. I changed my webpack.base.conf.js file to include the following inside the array of rules inside the module object\u2026<\/p>\n<pre> module: {\n   rules: [\n      ...\n      <strong> {<\/strong>\n<strong>       test: require.resolve('snapsvg'),<\/strong>\n<strong>       use: 'imports-loader?this=&gt;window,fix=&gt;module.exports=0',<\/strong>\n<strong>       },<\/strong>\n      ...\n     ]\n   },<\/pre>\n<p>Now we can load Snap.svg in our JavaScript, but imports-loader uses the node require syntax to load the file. So in our main.js, we can attach Snap.svg by telling WebPack to invoke the exports loader like this\u2026<\/p>\n<pre>const snap = require(`imports-loader?this=&gt;window,fix=&gt;module.exports=0!snapsvg\/dist\/snap.svg.js`);<\/pre>\n<p>\u2026and then attach it to our root Vue instance, still in main.js, something like this\u2026<\/p>\n<pre>const vueInstance = new Vue( {\n el: '#app',\n<strong> snap,<\/strong>\n router,\n axios,\n store,\n template: '&lt;App\/&gt;',\n components: { App }\n} );\n\nexport { vueInstance };<\/pre>\n<p>There is some redundancy in that require() call and the way we setup the module resolution in the WebPack configuration. I\u2019m fuzzy about why I seemed to need this in both spots, but it works so I\u2019m running with it. If you have insights they\u2019d be appreciated; let me know in the comments.<\/p><\/blockquote>\n","protected":false},"excerpt":{"rendered":"<p class=\"excerpt\">Adding Snap.svg to Vue.js and Nuxt.js Projects | James Scheller<\/p>\n<p class=\"more-link-p\"><a class=\"more-link\" href=\"https:\/\/monodes.com\/predaelli\/2018\/05\/26\/adding-snap-svg-to-vue-js-and-nuxt-js-projects\/\">Read more &rarr;<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"activitypub_content_warning":"","activitypub_content_visibility":"","activitypub_max_image_attachments":4,"activitypub_interaction_policy_quote":"anyone","activitypub_status":"","footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[50],"tags":[208,207],"class_list":["post-4345","post","type-post","status-publish","format-standard","hentry","category-javascript","tag-snap-svg","tag-vue-js"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p6daft-185","jetpack-related-posts":[{"id":5214,"url":"https:\/\/monodes.com\/predaelli\/2019\/02\/12\/vue-js-app-performance-optimization-part-1%e2%80%8a-%e2%80%8aintroduction-to-performance-optimization-and-lazy\/","url_meta":{"origin":4345,"position":0},"title":"Vue.js App Performance Optimization: part 1\u200a\u2014\u200aIntroduction to performance optimization and lazy\u2026","author":"Paolo Redaelli","date":"2019-02-12","format":false,"excerpt":"For the series, I will never stop learning While mobile-first approach becomes a standard and uncertain network conditions are something we should always take into consideration\u2026 Vue.js App Performance Optimization: part 1\u200a\u2014\u200aIntroduction to performance optimization and lazy\u2026 Vue.js App Performance Optimization: part 1\u200a\u2014\u200aIntroduction to performance optimization and lazy\u00a0loading. by Filip\u2026","rel":"","context":"In &quot;Documentations&quot;","block_context":{"text":"Documentations","link":"https:\/\/monodes.com\/predaelli\/category\/documentations\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":6562,"url":"https:\/\/monodes.com\/predaelli\/2020\/01\/29\/9-vue-js-libraries-that-will-make-your-life-easier-better-programming-medium\/","url_meta":{"origin":4345,"position":1},"title":"9 Vue.js Libraries That Will Make Your Life Easier &#8211; Better Programming &#8211; Medium","author":"Paolo Redaelli","date":"2020-01-29","format":"link","excerpt":"9 Vue.js Libraries That Will Make Your Life Easier - Better Programming - Medium\u00a0 Vue-Lazyload is a great library for lazy loading of not only images but also components. vue-head library makes manipulating the information in the head tag a piece of cake. BootstrapVue: Bootstrap components built with Vue. Vue-multiselect\u2026","rel":"","context":"In &quot;Javascript&quot;","block_context":{"text":"Javascript","link":"https:\/\/monodes.com\/predaelli\/category\/javascript\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":4422,"url":"https:\/\/monodes.com\/predaelli\/2018\/07\/04\/4422\/","url_meta":{"origin":4345,"position":2},"title":"VueI18n is internationalization plugin for\u2026","author":"Paolo Redaelli","date":"2018-07-04","format":"link","excerpt":"VueI18n is internationalization plugin for Vue.js","rel":"","context":"In &quot;Javascript&quot;","block_context":{"text":"Javascript","link":"https:\/\/monodes.com\/predaelli\/category\/javascript\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/monodes.com\/predaelli\/wp-content\/uploads\/sites\/4\/2018\/07\/vue-i18n-logo-1.png?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":2143,"url":"https:\/\/monodes.com\/predaelli\/2017\/02\/04\/2143\/","url_meta":{"origin":4345,"position":3},"title":"I'm still a dummy newbie\u2026","author":"Paolo Redaelli","date":"2017-02-04","format":"status","excerpt":"I'm still a dummy newbie in the wildernesses of JavaScript development, so let's try https:\/\/github.com\/react-webpack-generators\/generator-react-webpack","rel":"","context":"In &quot;Javascript&quot;","block_context":{"text":"Javascript","link":"https:\/\/monodes.com\/predaelli\/category\/javascript\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":6263,"url":"https:\/\/monodes.com\/predaelli\/2019\/11\/18\/cell-editable-vue-table\/","url_meta":{"origin":4345,"position":4},"title":"cell-editable vue table","author":"Paolo Redaelli","date":"2019-11-18","format":false,"excerpt":"It seems time has come for me to learn Chinese or to heavily rely on translators: vue table \u7ec4\u4ef6 \u5f3a\u5927\u3001\u7075\u6d3b\uff0c\u652f\u6301 \u5355\u5143\u683c\u5408\u5e76\u3001\u5355\u5143\u683c\u7f16\u8f91\u3001\u591a\u8868\u5934\u56fa\u5b9a\u3001\u591a\u5217\u56fa\u5b9a\u3001\u5217\u62d6\u52a8\u3001\u6392\u5e8f\u3001\u81ea\u5b9a\u4e49\u5217\u3001\u5206\u9875\u3001\u5355\u5143\u683c\u7f16\u8f91\u3001\u5168\u9009\u3001\u884c\u5c55\u5f00\u3001\u6761\u4ef6\u8fc7\u6ee4\u3001footer \u6c47\u603b\u3001\u5bfc\u51faexcel\u3001\u6c47\u603b Vue2.x flexible table components, support for cell edit,multi-head fixed, multi-column fixed, clumn drag, sort, custom column,Cell Editing, Support cell merge (colSpan and rowSpan),Support checkbox selection Source: vue table\u2026","rel":"","context":"In &quot;Javascript&quot;","block_context":{"text":"Javascript","link":"https:\/\/monodes.com\/predaelli\/category\/javascript\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":2140,"url":"https:\/\/monodes.com\/predaelli\/2017\/02\/03\/2140\/","url_meta":{"origin":4345,"position":5},"title":"http:\/\/jamesknelson.com\/using-es6-in-the-browser-with-babel-6-and-webpack\/","author":"Paolo Redaelli","date":"2017-02-03","format":false,"excerpt":"http:\/\/jamesknelson.com\/using-es6-in-the-browser-with-babel-6-and-webpack\/","rel":"","context":"In &quot;Documentations&quot;","block_context":{"text":"Documentations","link":"https:\/\/monodes.com\/predaelli\/category\/documentations\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"jetpack_likes_enabled":true,"_links":{"self":[{"href":"https:\/\/monodes.com\/predaelli\/wp-json\/wp\/v2\/posts\/4345","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/monodes.com\/predaelli\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/monodes.com\/predaelli\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/monodes.com\/predaelli\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/monodes.com\/predaelli\/wp-json\/wp\/v2\/comments?post=4345"}],"version-history":[{"count":0,"href":"https:\/\/monodes.com\/predaelli\/wp-json\/wp\/v2\/posts\/4345\/revisions"}],"wp:attachment":[{"href":"https:\/\/monodes.com\/predaelli\/wp-json\/wp\/v2\/media?parent=4345"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/monodes.com\/predaelli\/wp-json\/wp\/v2\/categories?post=4345"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/monodes.com\/predaelli\/wp-json\/wp\/v2\/tags?post=4345"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}