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 = [];

//調(diào)用文件遍歷方法

fileDisplay(filePath);

// 生成index.js文件

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

? return `import $bswhesx from './$iftdzef.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"><$dmzekpb/><aside>$ud7rq9f</aside></div>\n`

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

? return `import $uz6j9bp from '../../lib/$vfbxydl.vue';\n`

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

? return `$aekylrx,\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) {


? //根據(jù)文件路徑讀取文件,返回文件列表

? let files = fs.readdirSync(filePath);

? ? //遍歷讀取到的文件列表

? ? files.forEach(function (filename) {

? ? //獲取當前文件的絕對路徑

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

? ? //根據(jù)文件路徑獲取文件信息,返回一個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){

? ? ? ? ? ? ? // 讀取文件內(nèi)容

? ? ? 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);//遞歸,如果是文件夾,就繼續(xù)遍歷該文件夾下面的文件

? ? }

? });

}


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 賬號、發(fā)布:

npm login

然后在package.json的目錄下,然后運行npm publish 即發(fā)布成功。

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

所以別的項目用的時候只需要use一下即可注冊所有庫里的組件。

vue插件,Vue.use()會優(yōu)先查找install(),這個方法里可以對所有組件注冊到Vue上,Vue.component(name,component)全局注冊組件

局部注冊是在組件的export default{components:{}}里注冊

添加組件名就可以直接渲染該組件

component是一個占位符,:is屬性可以用來指定要展示的組件名稱

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內(nèi)容