init
This commit is contained in:
173
node_modules/@dcloudio/uni-mp-weixin/lib/analyze-wxcomponent-dependency/collect-dependency.js
generated
vendored
Normal file
173
node_modules/@dcloudio/uni-mp-weixin/lib/analyze-wxcomponent-dependency/collect-dependency.js
generated
vendored
Normal file
@@ -0,0 +1,173 @@
|
||||
const path = require('path');
|
||||
const fs = require('fs-extra');
|
||||
const htmlparser2 = require('htmlparser2');
|
||||
const { MpComponentFileExtension } = require('./constant');
|
||||
const { transformScript, resolveToContext } = require('./utils.js');
|
||||
const { parse } = require('@babel/parser');
|
||||
const { default: traverse } = require('@babel/traverse');
|
||||
|
||||
class CollectDependency {
|
||||
constructor (context, readFileSync, existsSync, addExtension) {
|
||||
this.context = context;
|
||||
this.existsSync = existsSync || fs.existsSync.bind(fs);
|
||||
this.readFileSync = readFileSync || fs.readFileSync.bind(fs);
|
||||
this.addExtension = addExtension;
|
||||
}
|
||||
|
||||
getWxCssDeps (file) {
|
||||
const deps = [];
|
||||
const dirName = path.dirname(file);
|
||||
let content = this.readFileSync(file, 'utf-8');
|
||||
if (content instanceof Buffer) {
|
||||
content = content.toString('utf-8');
|
||||
}
|
||||
const importRegExp = /@import\s*['"](.+)['"];*/g;
|
||||
let matched;
|
||||
while ((matched = importRegExp.exec(content)) !== null) {
|
||||
if (!matched[1]) {
|
||||
continue;
|
||||
}
|
||||
const wxssFile = resolveToContext(dirName, matched[1], this.context);
|
||||
if (this.existsSync(wxssFile)) {
|
||||
deps.push(wxssFile);
|
||||
}
|
||||
}
|
||||
return deps;
|
||||
};
|
||||
|
||||
getWxHtmlDeps (file) {
|
||||
const deps = [];
|
||||
const dirName = path.dirname(file);
|
||||
let content = this.readFileSync(file, 'utf-8');
|
||||
if (content instanceof Buffer) {
|
||||
content = content.toString('utf-8');
|
||||
}
|
||||
// https://developers.weixin.qq.com/miniprogram/dev/reference/wxml/import.html
|
||||
// WXML 提供两种文件引用方式import和include。
|
||||
const targetTags = ['import', 'include', 'wxs'];
|
||||
const existsSync = this.existsSync;
|
||||
const htmlParser = new htmlparser2.Parser({
|
||||
onopentag (name, attribs = {}) {
|
||||
if (!targetTags.includes(name)) {
|
||||
return;
|
||||
}
|
||||
const { src } = attribs;
|
||||
if (!src) {
|
||||
return;
|
||||
}
|
||||
const wxmlFile = resolveToContext(dirName, src, this.context);
|
||||
console.log(wxmlFile);
|
||||
if (existsSync(wxmlFile)) {
|
||||
deps.push(wxmlFile);
|
||||
}
|
||||
},
|
||||
});
|
||||
htmlParser.write(content);
|
||||
htmlParser.end();
|
||||
return deps;
|
||||
}
|
||||
|
||||
getJsonDeps (file) {
|
||||
const deps = [];
|
||||
const dirName = path.dirname(file);
|
||||
let fileContent = this.readFileSync(file);
|
||||
if (fileContent && fileContent instanceof Buffer) {
|
||||
fileContent = fileContent.toString('utf-8');
|
||||
}
|
||||
if (!fileContent || !(fileContent.trim())) {
|
||||
return [];
|
||||
}
|
||||
fileContent = JSON.parse(fileContent);
|
||||
const usingComponents = fileContent.usingComponents;
|
||||
if (usingComponents && typeof usingComponents === 'object') {
|
||||
Object.values(usingComponents).forEach((component) => {
|
||||
component = resolveToContext(dirName, component, this.context);
|
||||
// 每个组件都需要判断 js/json/wxml/wxss 文件是否存在
|
||||
MpComponentFileExtension.forEach((ext) => {
|
||||
const file = this.addExtension(component, ext);
|
||||
if (this.existsSync(file)) {
|
||||
deps.push(file);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
return deps;
|
||||
}
|
||||
|
||||
getJsDeps (file) {
|
||||
const deps = [];
|
||||
const dirName = path.dirname(file);
|
||||
// 读取 js 文件内容
|
||||
let content = this.readFileSync(file, 'utf-8');
|
||||
if (content instanceof Buffer) {
|
||||
content = content.toString('utf-8');
|
||||
}
|
||||
// 将代码转化为 AST
|
||||
const ast = parse(content, { sourceType: 'module', plugins: ['exportDefaultFrom'] });
|
||||
// 遍历 AST
|
||||
traverse(ast, {
|
||||
ImportDeclaration: ({ node }) => {
|
||||
// 获取 import from 地址
|
||||
const { value } = node.source;
|
||||
const jsFile = transformScript(dirName, value, this.existsSync);
|
||||
if (jsFile) {
|
||||
deps.push(jsFile);
|
||||
}
|
||||
},
|
||||
Property: (nodePath) => {
|
||||
const parentPath = nodePath.parentPath;
|
||||
const callee = parentPath && parentPath.parent && parentPath.parent.callee;
|
||||
if (!callee || callee.name !== 'Component') {
|
||||
return;
|
||||
}
|
||||
const relationsNodes = nodePath.container.filter(item => item.key.name === 'relations');
|
||||
if (!relationsNodes.length) {
|
||||
return;
|
||||
}
|
||||
const relationsNode = relationsNodes[0];
|
||||
const propertyNodes = relationsNode.value.properties || [];
|
||||
let allRelationsComponents = propertyNodes.map(filePathNode => {
|
||||
if (!filePathNode.key.value) {
|
||||
return '';
|
||||
}
|
||||
return path.resolve(dirName, filePathNode.key.value);
|
||||
});
|
||||
allRelationsComponents = allRelationsComponents.filter(item => item);
|
||||
allRelationsComponents.forEach(component => {
|
||||
MpComponentFileExtension.forEach((ext) => {
|
||||
const file = this.addExtension(component, ext);
|
||||
if (this.existsSync(file)) {
|
||||
deps.push(file);
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
ExportNamedDeclaration: ({ node }) => {
|
||||
if (!node.source) {
|
||||
return;
|
||||
}
|
||||
// 获取 export from 地址
|
||||
const { value } = node.source;
|
||||
const jsFile = transformScript(dirName, value, this.existsSync);
|
||||
if (jsFile) {
|
||||
deps.push(jsFile);
|
||||
}
|
||||
},
|
||||
CallExpression: ({ node }) => {
|
||||
if ((node.callee.name && node.callee.name === 'require') && node.arguments.length >= 1) {
|
||||
// 获取 require 地址
|
||||
const [{ value }] = node.arguments;
|
||||
|
||||
const jsFile = transformScript(dirName, value, this.existsSync);
|
||||
if (jsFile) {
|
||||
deps.push(jsFile);
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
return deps;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = CollectDependency;
|
||||
Reference in New Issue
Block a user