Last active
June 3, 2020 02:15
-
-
Save lizhengnacl/3d5a67543af482b4b2dd41a72aac19b6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* * 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