-
Notifications
You must be signed in to change notification settings - Fork 4
/
index.js
89 lines (82 loc) · 3.34 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
const {join} = require('path');
const {existsSync} = require('fs');
const t = require('babel-types');
const filesStatCache = new Set();
const isLocaleExtra = curr => ~['locale', 'i18n'].indexOf(curr);
const isExportFuncExtra = curr => ~['dialog', 'toast', 'flex', 'steps', 'skeleton'].indexOf(curr);
/**
* 生成新的specifiers
* @param {array} specifiers
* @param {object} opts - babel plugin传入的参数
* @returns {array}
*/
function genImportDeclaration(specifiers = [], opts) {
const packagesPath = `${opts.libraryName}/${opts.libraryDirectory}/`;
return specifiers.reduce(function(newSpecifiers, curr) {
const _curr = curr.toLowerCase();
const isLocale = isLocaleExtra(_curr);
const {style, sourceCode} = opts;
const importLocal = t.identifier(curr);
const importDefault = t.importDefaultSpecifier(importLocal);
const imported = t.importSpecifier(importLocal, importLocal);
const imports = [
t.importDeclaration([
isLocale? imported: importDefault
], t.stringLiteral(getTarget(_curr, packagesPath, sourceCode)))
]
if(style && !isLocale) {
const cssTarget = `${packagesPath + _curr}/${_curr}.${style}`;
const cssFile = join(process.cwd(), 'node_modules', cssTarget);
if(!filesStatCache.has(cssFile)) {
const hasFile = existsSync(cssFile);
if(hasFile) {
filesStatCache.add(cssFile);
}
}
if(filesStatCache.has(cssFile)) {
imports.push(t.importDeclaration([], t.stringLiteral(cssTarget)));
}
}
return newSpecifiers.concat(imports);
}, []);
}
/**
* 根据参数改变引用文件类型
*/
function getTarget(pkgName, pkgPath, isSourceCode) {
let target = pkgPath;
if(isSourceCode) {
const isLocale = isLocaleExtra(pkgName);
const isExportFunc = isExportFuncExtra(pkgName);
const localePath = join(pkgPath, '..', 'locales');
const exportFuncTarget = `${pkgPath}/${pkgName}/_${pkgName}.js`;
const sourceFile = `${pkgPath + pkgName}/${pkgName}.vue`;
target = isLocale? localePath: isExportFunc? exportFuncTarget: sourceFile;
}else{
target = `${target + pkgName}/${pkgName}.js`;
}
return target;
}
module.exports = function() {
return {
visitor: {
ImportDeclaration(path, {opts = {}}) {
if(!opts.libraryName) opts.libraryName = '@nutui/nutui';
if(!opts.libraryDirectory) opts.libraryDirectory = 'dist/packages';
if(!opts.sourceCode) opts.sourceCode = false;
const {style} = opts;
const {node} = path;
opts.style = style ? (style === 'scss'? 'scss': 'css') : '';
if(!node.source) return;
const {value} = node.source;
const {specifiers} = node;
if(value === opts.libraryName && specifiers && specifiers.length) {
const spes = specifiers.filter(specifier => specifier.type === 'ImportSpecifier').map(specifier => specifier.local.name);
if(spes.length) {
path.replaceWithMultiple(genImportDeclaration(spes, opts))
}
}
}
}
}
}