React で ./src/locales/ の中身を全て読み取ろうとしたが無理だった - react は複数の json を読み込めない!
why
前回の記事で 5言語の切り替えを実装したが、毎回
import xxJson from './locales/xx.json' xx: { translation: xxJson, }, <button onClick={ () => setLang('xx') }> XXXXXX
これを書かないと言語を追加できないクソ設計なので直す
やったこと
react-i18next で json ファイルを map しようとした
fs で map しようとするけどどの代替ライブラリを使ってもできなかった
Reactでfsは使えません。 React動かすのは大抵ブラウザ上でしょ?
説明ページの中身をよく読んで、これはNode.js上で動かす事を想定しているのか、 JavaScript上で動かす事を想定しているのか推測してください。
teratail で完璧な回答があった.....
解決策
一つの json file にデータを置いて map する
map する先の json は 1 file!
それの実行は次回の記事
記事のURL をここに入れろ!!!
失敗した取り組み
fs をまず使ってみるがダメ
path と fs のライブラリを使ってフォルダから読み込んで cll に出力してみる
両方 Node の根幹だから import は必要ない。
const localesDir = path.join(process.cwd(), 'locales') console.log(localesDir);
これで
/locales
path が 作れてる
fs.readdirSync を...
あれ?
fsWEBPACK_IMPORTED_MODULE_3_default.a.readdirSync is not a function
ググってみると
se brfs , https://github.com/browserify/brfs
fs.readFileSync() and fs.readFile() static asset browserify transform
ブラウザだから使えないようなことが書いてある
fs 以外で使えるものをいろいろググってみるが全滅
brfs は毎回ビルドになる
browserify というシステムの brfs
コンパイラで毎回ビルドするのはやってることと違うので拒否
browserify-fs を使うが同じエラーが出る
この fs 互換で行けるか?
import fs from 'browserify-fs' const fileNames = fs.readdirSync(localesDir);
browserify_fsWEBPACK_IMPORTED_MODULE_3_default.a.readdirSync is not a function
readdirSync がない.... 同じエラーだ...
brfs の方だと bundle しないといちいちビルドしないと実行できなくなるってことになる、それは開発効率下がるからしたくない
list-react-files を試すが fs を結局使っている
list-react-files というライブラリがあるらしい
npm i list-react-files import listReactFiles from 'list-react-files' listReactFiles(__dirname).then(files => console.log(files))
Promise か....展開して... あれ?
glob.js:547 Uncaught (in promise) TypeError: fs.readdir is not a function at Glob.push../node_modules/glob/glob.js.Glob._readdir (glob.js:547) at Glob.push../node_modules/glob/glob.js.Glob._processGlobStar (glob.js:625) at Glob.push../node_modules/glob/glob.js.Glob._process (glob.js:362) at new Glob (glob.js:170) at glob (glob.js:75) at index.js:29 at new Promise (<anonymous>) at listReactFiles (index.js:28)
listReactFiles は glob を使っていて、glob も fs.readFiles を使っているからダメらしい。
indeed, it throws Unhandled Rejection (TypeError): fs.readdir is not a function – Mugen Jun 18 '19 at 13:34
コメントに書いてある通りやんけ
list-files を使う
リプライがないけど、最後の回答を試してみる
import find from 'list-files' find(function(result) { console.log(result); } ,{ dir: localesDir, name: 'json' });
index.js:19 Uncaught TypeError: exec is not a function
exec を 使うらしい
const exec = require('child_process').exec;
実際に使うと
dentifier 'exec' has already been declared (14:7)
で
import zhJson from './locales/zh.json'
を指摘されてしまう。exec がすでにされているってことらしい
exec の基礎が何もわかっていない....
fs でのエラーハンドリング
いろいろ試したけどファイルからの json ファイル名の取得すらできない....
そもそもエラーハンドリングをしないと使えない?
https://www.codegrepper.com/code-examples/javascript/list+all+files+in+dir+react
fs.readdir(localesDir, function (err, files) { //handling error if (err) { return console.log('Unable to scan directory: ' + err); } //listing all files using forEach files.forEach(function (file) { // Do whatever you want to do with the file console.log(file); }); });
fsWEBPACK_IMPORTED_MODULE_3_default.a.readdir is not a function
まず readdir が fs にないって言われてしまってどうしようもない...