Skip to content

Instantly share code, notes, and snippets.

@lizhengnacl
Last active June 3, 2020 02:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lizhengnacl/3d5a67543af482b4b2dd41a72aac19b6 to your computer and use it in GitHub Desktop.
Save lizhengnacl/3d5a67543af482b4b2dd41a72aac19b6 to your computer and use it in GitHub Desktop.
/**
* * Created by lee on 2019/3/25
*
* 直接依赖安装在第一层
* 不处理node_modules搜索路径,提示非当前目录
*/
const path = require('path');
const fs = require('fs');
class CheckNpmModules {
constructor (params) {
this.name = params.name || 'check-dep.json';
this.root = params.root;
this.output = params.output || params.root;
this.state = {
using: {},
notInDependencies: {},
notMatch: {},
error: {}
};
}
apply (compiler) {
compiler.resolverFactory.hooks.resolver.for("normal").tap('resolver normal', resolver => {
resolver.hooks.resolve.tap('CheckNpmModules', (params) => {
// Only handler direct dependencies, not sub-dependencies
if(!params.context.issuer.includes('node_modules')) {
// 解析得到name prop-types/checkPropTypes
// 当前项目中不存在module时,会递归向上查找;线上没找到时,会出现为空的情况
if(params.__innerRequest !== void 0) {
let moduleName = params.__innerRequest.split('/')[0];
if(moduleName.indexOf('@') === 0) {
moduleName = params.__innerRequest.split('/').slice(0, 2).join('/')
}
let version = getModuleVersion(path.resolve(this.root, 'node_modules', moduleName));
this.state.using[moduleName] = version;
// 判断是否在dependencies中
// 不用考虑匹配问题,以实际使用版本为准
try {
let v = params.descriptionFileData.dependencies && params.descriptionFileData.dependencies[moduleName];
if(v === void 0) {
this.state.notInDependencies[moduleName] = version;
} else if(v.indexOf(version) === -1) {
this.state.notMatch[moduleName] = `${v} | ${version}`;
}
} catch(e) {
this.state.error[moduleName] = e.stack;
}
}
}
});
});
// emit 是异步 hook,使用 tapAsync 触及它,还可以使用 tapPromise/tap(同步)
compiler.hooks.emit.tapAsync('CheckNpmModules', (compilation, callback) => {
let content = JSON.stringify(this.state, null, 4);
// compilation.assets[this.name] = {
// source: function() {
// return content;
// },
// size: function() {
// return content.length;
// }
// };
// 手动创建文件
fs.writeFileSync(path.resolve(this.output, this.name), content);
callback();
});
}
}
function getModuleVersion (moduleRoot) {
let isExists = fs.existsSync(moduleRoot);
if(isExists) {
try {
let content = fs.readFileSync(path.resolve(moduleRoot, 'package.json'), 'utf8');
content = JSON.parse(content);
return content.version;
} catch(e) {
return 'package.json not exists, or format error';
}
} else {
return 'not install in current project';
}
}
module.exports = CheckNpmModules;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment