说明:
ant从全局引用,改造成按需引用,需要在每个页面中,单独引用具体的组件:
import Vue from 'vue'
import { Button } from 'ant-design-vue'
Vue.use(Button)
费时费力,都是重复性工作。
于是写成一个脚本,一键全局扫描替换。
let fs = require('fs')
// ant modules的目录
let antFrameworkPath = 'D:/proj/node_modules/ant-design-vue/es'
//
let project = 'D:/proj/src/views'
// 读取ant所有组件列表
function getAnt(path) {
let list = fs.readdirSync(path).filter(item => {
return !/(^(_|vc-))|(\.js$)|version/.test(item)
})
return list
}
// 扫描项目组件中的所有vue文件
function scannerVueFile(filePath, list) {
let pathList = fs.readdirSync(filePath).map(item => filePath + '/' + item);
pathList.forEach(item => {
if (fs.statSync(item).isDirectory()) {
scannerVueFile(item, list)
} else if (fs.statSync(item).isFile()) {
if (/\.vue$/i.test(item)) {
list.push(item)
}
}
});
return list
}
// 从vue文件中的template代码中识别不重复的组件名称列表
function scannerComponentInTemplate(file) {
let componentMaps = {}
let template = file.match(/^\s*<template[^>]*>([\s\S]+?)<\/template>[\s\r\n]*<script>/i)
template = template ? template[1] : '';
if (template) {
let antComponentList = template.match(/<a-([^\s>]+)/ig)
antComponentList = antComponentList ? antComponentList : [];
if (antComponentList.length > 0) {
antComponentList.forEach(item => {
item = item.replace(/<a-/i, '')
item = item.toLowerCase();
if (!componentMaps[item] && vueComponentNameList.includes(item)) {
item = item.replace(/^(\S)/i, ($0, $1) => {
return $1.toUpperCase()
})
.replace(/-([\S])/i, ($0, $1) => {
return $1.toUpperCase()
})
componentMaps[item] = 1
}
})
}
}
return componentMaps
}
function scannerImported(file) {
let script = file.match(/import\s+\{([^\}]+)\} from ['"]ant-design-vue['"]/i)
script = script ? script[1] : '';
if (script) {
return script.split(',').map(item => item.trim())
}
return []
}
function getNewFile(filePath) {
let testFile = fs.readFileSync(filePath, { encoding: 'utf-8' })
let needImportMap = scannerComponentInTemplate(testFile)
let needImportMapCopy = { ...needImportMap }
let imporedList = scannerImported(testFile)
imporedList.forEach(item => {
delete needImportMap[item]
})
let needImportList = Object.keys(needImportMap);
let importStr = ''
if (needImportList.length > 0) {
// 全新引入
let useStr = needImportList.map(item => 'Vue.use(' + item + ')\n');
let components = needImportList.join(',\n ');
let newFile = '';
// 如果已经引入了部分组件,则进行追加剩余的组件
if (/from [\'\"]ant-design-vue[\'\"]/i.test(testFile)) {
let reg = /import\s+\{([^\}]+)\} from [\'\"]ant-design-vue[\'\"]/i;
newFile = testFile
.replace(reg, ($0, $1) => {
let str = '';
if ($1) {
let oldComponents = $1.trim();
str = `import {\n ${oldComponents},\n ${components}\n} from 'ant-design-vue'`;
} else {
str = $0;
}
return str
})
.replace(/(Vue\.use\(\w+\)\n?)+/i, ($0, $1) => {
return $0 + '\n' + useStr.join('')
})
} else {
importStr = `import {\n ${components}\n} from 'ant-design-vue'\n`;
importStr += useStr.join('');
// 判断是否引入了vue
if (!/import Vue from/.test(testFile)) {
importStr = `import Vue from 'vue'\n` + importStr
}
newFile = testFile.replace(/(<\/template>\s*<script[^>]*>)/i, ($0, $1) => {
return $0 + '\n' + importStr
})
}
console.log('追加了', needImportList.length, '个组件', needImportList.join(',').trim(), filePath.match(/([^\/]+)$/)[1].trim());
fs.writeFileSync(filePath, newFile, { encoding: 'utf-8' })
// console.log('newFile ', newFile);
} else {
if (Object.keys(needImportMapCopy).length > 0 && needImportList.length === 0) {
console.log('追加了', needImportList.length, '个组件', needImportList.join(',').trim(), filePath.match(/([^\/]+)$/)[1].trim());
// console.log(filePath, '已经添加');
} else if (Object.keys(needImportMapCopy).length === 0) {
console.log('追加了', needImportList.length, '个组件', needImportList.join(',').trim(), filePath.match(/([^\/]+)$/)[1].trim());
// console.log(filePath, '未引用组件');
}
}
}
let vueComponentNameList = getAnt(antFrameworkPath)
let vueList = scannerVueFile(project, []);
console.log('总共有:', vueList.length);
vueList.forEach((filePath, index) => {
getNewFile(filePath)
})