npm打包svg成vue组件

目录:(packages里是对应的所有源svg文件,lib里是所有svg对应的Vue组件。通过loaders 里的svgToComponents.js对应的node方法给每一个svg文件在lib下生成对应格式的vue文件以及index.js文件。)


svgToComponents.js:

                var fs = require('fs');

var path = require('path');

var util = require('util');

var filePath = path.resolve('./packages/icons');

var template = require('lodash');

var fileList = [];

//调用文件遍历方法

fileDisplay(filePath);

// 生成index.js文件

var indexContent = fileList.map(function(d) {

  return `import ${d} from './${d}.vue';\n`

}).join('')+"\n const components = ["+ fileList.join(',\n')+"];\n const install = function(Vue){components.forEach(component => {Vue.component(component.name, component);});}\n"+

"export default {install,"+ fileList.join(',\n')+"}"

fs.writeFileSync(path.resolve(__dirname, `../lib/index.js`), indexContent);

//examples中本地页面显示所有图标

var svgVue = "<template>\n<div class='container'>\n"+fileList.map(function(d) {

  return `<div class="master-icon"><${d}/><aside>${d}</aside></div>\n`

}).join('')+"\n</div>\n</template>\n<script>"+fileList.map(function(d) {

  return `import ${d} from '../../lib/${d}.vue';\n`

}).join('')+"export default {components: {"+fileList.map(function(d) {

  return `${d},\n`

}).join('')+"}\n}\n</script>" +

`

<style>

body{margin: 0;width: 100%;}

.container{

  flex-wrap: wrap;

  display: flex;

}

.master-icon {width: 140px; height: 120px; color: #666; font-size: 24px;

  display: flex;

  align-items: center;

  flex-direction: column;

}

.master-icon aside {text-align: center; font-size: 12px; color: #99a9bf;margin-top: 30px;}

</style>

`;

fs.writeFileSync(path.resolve(__dirname, `../examples/components/svgDemo.vue`), svgVue);

//文件遍历方法

function fileDisplay(filePath) {


  //根据文件路径读取文件,返回文件列表

  let files = fs.readdirSync(filePath);

    //遍历读取到的文件列表

    files.forEach(function (filename) {

    //获取当前文件的绝对路径

    var filedir = path.join(filePath, filename);

    //根据文件路径获取文件信息,返回一个fs.Stats对象

    var stats = fs.statSync(filedir);

    var isFile = stats.isFile();//是文件

    var isDir = stats.isDirectory();//是文件夹

    if (isFile) {

      var fileName = filedir.match(/([^\/\.]*)\..*$/)[1];

      var pattern = /-([a-z0-9])/g;

      fileName = fileName.replace(pattern,function(all,letter){

          return letter.toUpperCase();

      });

      fileName = fileName.charAt(0).toUpperCase() + fileName.slice(1);

      if(fileName){

              // 读取文件内容

      var svgContent = fs.readFileSync(filedir, 'utf-8');

      var render = template(`

<template>

  ${svgContent

    .replace(/<g[^>]*>((?:\n.*)*)<\/g>/, '$1')

    .replace(/<defs>(\n.*)*<\/defs>/, '')

    .replace('<svg','<svg :style="{fontSize:size,color: fill,transform:`rotate(${rotate}deg)`}"')

    .replace('width="14"','width="1em"')

    .replace('height="14"','height="1em"')

    .replace(/(fill|stroke)=[\'\"](?!none)[^\'\"]*[\'\"]/g,'$1="currentcolor"')

  }


</template>

<script>

export default {

  name:"${fileName}Icon",

  props:{

    size: {

      type: String,

      default: 'inherit'

    },

    rotate: {

      type: String,

      default: '0'

    },

    fill: {

      type: String,

      default: 'none'

    }

  }

};

</script>`);

      fs.writeFileSync(path.resolve(__dirname, `../lib/${fileName}Icon.vue`), render)

      fileList.push(fileName+'Icon');

      }

    }

    if (isDir) {

      fileDisplay(filedir);//递归,如果是文件夹,就继续遍历该文件夹下面的文件

    }

  });

}


package.json:(main里是组件库的入口文件, 也就是别人安装该组件库后首要加载的文件)

need-to-insert-img

vue.config.js:

                const path = require('path');

module.exports = {

  lintOnSave: false,

  // 修改 src 目录 为 examples 目录

  publicPath: '/',

  pages: {

    index: {

      entry: 'examples/main.js',

      template: 'public/index.html',

      filename: 'index.html',

    },

  },

  configureWebpack: {

    resolveLoader: {

      modules: ['node_modules', './loaders'],

    },

  },

  // 扩展 webpack 配置,使 packages 加入编译

  chainWebpack: (config) => {

    config.module

      .rule('svg')

      .test(/\.svg$/)

      .include

      .add(path.resolve(__dirname + './packages/icons'))

      .end()

      .use('svgToComponent')

      .loader('svgToComponent');

  },

};


命令行中登陆npm 账号、发布:

npm login

然后在package.json的目录下,然后运行npm publish 即发布成功。

lib/index.js里const install = function(Vue){components.forEach(component => {Vue.component(component.name, component);});}

所以别的项目用的时候只需要use一下即可注册所有库里的组件。

vue插件,Vue.use()会优先查找install(),这个方法里可以对所有组件注册到Vue上,Vue.component(name,component)全局注册组件

局部注册是在组件的export default{components:{}}里注册

添加组件名就可以直接渲染该组件

component是一个占位符,:is属性可以用来指定要展示的组件名称

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容