![](/img/trans.png)
[英]Webpack is importing modules from my machine's global `node_modules`. How do I get it to only import from my project's `node_modules`?
[英]How do node_modules packages read config files in the project root?
我正在創建一個 npm package 需要能夠從項目根目錄讀取配置文件。 我不知道該怎么做。
例如,
./pages/
和./next.config.js
./jest.config.js
./.eslintrc.json
./.prettierrc.js
./tsconfig.json
./.babelrc
我已經嘗試查看他們的源代碼以了解他們是如何做到的,但是項目太大以至於我找不到相關部分。
他們如何做到這一點?
首先在path.dirname(process.mainModule.filename)
中搜索,然后向上搜索目錄樹../, ../../, ../../../
等,直到找到配置文件。
這是我從 rc ( https://github.com/dominictarr/rc ) 包中竊取的代碼,它將從名為.projectrc
的文件中讀取並解析配置:
const fs = require('fs');
const path = require('path');
// Utils shamefully stolen from
// https://github.com/dominictarr/rc/blob/master/lib/utils.js
find(...args) {
const rel = path.join.apply(null, [].slice.call(args));
return findStartingWith(path.dirname(process.mainModule.filename), rel);
}
findStartingWith(start, rel) {
const file = path.join(start, rel);
try {
fs.statSync(file);
return file;
} catch (err) {
// They are equal for root dir
if (path.dirname(start) !== start) {
return findStartingWith(path.dirname(start), rel);
}
}
}
parse(content) {
if (/^\s*{/.test(content)) {
return JSON.parse(content);
}
return undefined;
}
file(...args) {
const nonNullArgs = [].slice.call(args).filter(arg => arg != null);
// path.join breaks if it's a not a string, so just skip this.
for (let i = 0; i < nonNullArgs.length; i++) {
if (typeof nonNullArgs[i] !== 'string') {
return;
}
}
const file = path.join.apply(null, nonNullArgs);
try {
return fs.readFileSync(file, 'utf-8');
} catch (err) {
return undefined;
}
}
json(...args) {
const content = file.apply(null, args);
return content ? parse(content) : null;
}
// Find the rc file path
const rcPath = find('.projectrc');
// Or
// const rcPath = find('/.config', '.projectrc');
// Read the contents as json
const rcObject = json(rcPath);
console.log(rcObject);
您還可以將 rc 包用作依賴npm i rc
,然后在您的代碼中:
var configuration = require('rc')(appname, {
// Default configuration goes here
port: 2468
});
這將從名為.${appname}rc
的文件中讀取配置。
當我制作第一個npm
package 時遇到了這個問題findup-sync
庫很好地解決了這個問題:
const findup = require('findup-sync');
const filePath = findup('filename');
它們從文件所在的目錄開始,並在文件系統樹中遞歸地向上查找,直到找到它要查找的文件。
像這樣的東西:
const FILE_NAME = 'target-file.json';
const fsp = require('fs').promises,
path = require('path');
let find = async (dir=__dirname) => {
let ls = await fsp.readdir(dir);
if(ls.includes(FILE_NAME))
return path.join(dir,FILE_NAME);
else if(dir == '/')
throw new Error(`Could not find ${FILE_NAME}`);
else
return find(path.resolve(dir,'..'));
}
或者,如果您正在尋找一個標准節點“項目根”,您可能想要遞歸並找到一個包含目錄名稱“node_modules”的目錄,如下所示:
const fsp = require('fs').promises,
path = require('path');
let find = async (dir=__dirname) => {
let ls = await fsp.readdir(dir);
if(ls.includes('node_modules'))
return dir;
else if(dir == '/')
throw new Error(`Could not find project root`);
else
return find(path.resolve(dir,'..'));
}
有多種方法可以做到這一點。 我創建了一個test-package和一個演示項目node-package-test來測試它。
為了方便參考,請在此處提供主要代碼:
project-main\node_modules\test-package\index.js :
const path = require('path');
const fs = require('fs');
const CONFIG_NAME = 'cfg.json';
function init(rootDir = null) {
console.log(`test-package: process.cwd(): ${process.cwd()}`);
console.log(`test-package: path.resolve('./'): ${path.resolve('./')}`);
if (!rootDir) {
//rootDir = path.resolve('./');
// OR
rootDir = process.cwd();
}
//const configPath = path.resolve('./', CONFIG_NAME);
// OR
const configPath = path.join(rootDir, CONFIG_NAME);
if (fs.existsSync(configPath)) {
console.log(`test-package: Reading config from: ${configPath}`);
try {
//const data = fs.readFileSync(configPath, 'utf8');
//const config = JSON.parse(data);
// OR
const config = require(configPath);
console.log(config);
} catch (err) {
console.error(err)
}
} else {
console.log(`test-package: Couldn't find config file ${configPath}. Using default.`)
}
console.log('\n')
}
//init()
const features = {
init: init,
message: `Hello from test-package! 👋`
}
module.exports = features;
項目主\ main.js :
const utils = require('@onkarruikar/test-package')
utils.init();
// OR use
//utils.init('/path/to/rootdir');
console.log(`${utils.message}`);
輸出:
E:\node-package-test-main>npm install
added 1 package, and audited 2 packages in 4s
found 0 vulnerabilities
E:\node-package-test-main>npm start
> start
> node .
test-package: process.cwd(): E:\node-package-test-main
test-package: path.resolve('./'): E:\node-package-test-main
test-package: Reading config from: E:\node-package-test-main\cfg.json
{ compilerOptions: { allowJs: true, checkJs: true, noEmit: true } }
Hello from test-package! 👋
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.