BrianSipple / ember-cli-svgstore

Ember addon to combine SVGs as symbols in a spritesheet.
MIT License
20 stars 8 forks source link

How to use this from another addon? #5

Open tomwayson opened 8 years ago

tomwayson commented 8 years ago

I'd like to use this addon as a dependency of my own addon, however, I'm unsure where to place the source files and config. I suspect that I'd need to somehow include the configuration in theincluded hook in my addon's index.js file, but I'm not sure what that would look like. Also, don't know if I'd have to change up the paths to the image files (i.e. to something like "assets/my-addon-name/incons.svg").

Would greatly appreciate any guidance.

dfreeman commented 8 years ago

Currently this addon only works for apps — I believe the hook it relies on (postprocessTree('all')) isn't invoked for addons that are dependencies of other addons.

It's likely there's a way to refactor to use hooks that are available for addons as well. I'm not sure off the top of my head what that would look like, but I'd be happy to accept a PR adding that functionality.

tomwayson commented 7 years ago

FWIW I ended up just using broccoli-svgstore directly from my addon:

// index.js
/* eslint-env node */
'use strict';

var svgstore = require('broccoli-svgstore');
var mergeTrees = require('broccoli-merge-trees');
var Funnel = require('broccoli-funnel');
var path = require('path');

module.exports = {
  name: 'ember-arcgis-layout-components',
  isDevelopingAddon: function () {
    return true;
  },

  treeForPublic: function () {
    // output public files as normal
    var tree = this._super.treeForPublic.apply(this, arguments);
    // build the svgstore sprite
    var inputNodes = new Funnel(path.join(__dirname, 'public/assets/images/card-icons'));
    var svgstoreTree = svgstore(inputNodes, {
      outputFile: 'ember-arcgis-layout-components/assets/images/card-icons.svg'
    });
    // return the merged trees
    return mergeTrees([tree, svgstoreTree], {
      overwrite: true
    });
  }
};
notmessenger commented 6 years ago

https://github.com/BrianSipple/ember-cli-svgstore/pull/20 and https://github.com/BrianSipple/ember-cli-svgstore/pull/21 are required to be able to support consuming this addon in other addons.

Additionally, addressing the original comment, we are then able to use this code in our addons to configure each one so that consuming applications don't have to provide any configuration:

// index.js
const setSvgOptions = require('<some-other-repo>/utils/svg')

module.exports = {
  included: function () {
    this._findHost.call(this)

    // Set ember-cli-svgstore options so that consuming applications don't have to
    setSvgOptions.call(this, 'name-want-iconpack-to-be')

    this._super.included.apply(this, arguments)
  }
}

// <some-other-repo>/utils/svg.js

'use strict'

const path = require('path')
const resolve = require('resolve')

/**
 * Get source directory for SVGs
 *
 * @param {String} svgSourceDir Source directory of SVG files
 * @returns {String}
 */
const getSourceDirectory = function(svgSourceDir) {
    // can use this if are a top-level addon...
    let sourcePath = svgSourceDir

    // ...otherwise need to find correct node_modules location when are...
    if (
        !this.project.isEmberCLIAddon() // ...in an app
        || this.project.pkg.name !== this.moduleName() // ...in a nested addon
    )
    {
        let packagePath = resolve.sync(this.moduleName(), {baseDir: this.project.root})
        sourcePath = path.join(packagePath.substring(0, packagePath.lastIndexOf('/')), svgSourceDir)
    }

    return sourcePath
}

/**
 * Set configuration options for ember-cli-svgstore addon
 *
 * @param {String} iconPack Name of the master SVG
 * @param {String} [frost-icon-svgs] svgSourceDir Source directory of SVG files
 * @returns {undefined}
 */
const setSvgConfiguration = function (iconPack, svgSourceDir = 'svgs') {
    if(!iconPack) {
        throw new Error(`"iconPack" must be set when configuring SVGs in ${this.name}`)
    }

    this.app.options.svgstore = this.app.options.svgstore || {}
    this.app.options.svgstore.files = this.app.options.svgstore.files || []

    this.app.options.svgstore.files.push({
        sourceDirs: getSourceDirectory.call(this, svgSourceDir),
        outputFile: `/assets/icon-packs/${iconPack}.svg`
    })
}

If a consuming application also has its own SVGs that it wants to flatten it will need to install ember-cli-svgstore as a dependency and configure its ember-cli-build.js file but MUST set the files key to be an array.

This is the PR where we have implemented this: https://github.com/ciena-frost/ember-frost-core/pull/558