先月中古で購入したEPSON Endeavor ST190Eに、Cordova 11のビルド環境を構築しましたが、下記エラーが発生してビルドできない状態となりました。

Cannot read properties of undefined (reading 'length')

今回は、このエラーの解決方法について説明します。

Cordovaのビルドを実行すると、Node.jsが動作します。
プロジェクト内にある「node_modules」フォルダ内に「cordova-android」フォルダがあります。
その中にある「lib」フォルダに「build.js」というファイルがあり、ビルドを実行すると、このファイルが動作する仕組みとなっています。

この「build.js」というファイルのコード1行1行の動きを追っていきました。
すると、「check_reqs.js」の以下のコードでエラーが発生していることに気が付きました。

module.exports.get_gradle_wrapper = function () {
    var androidStudioPath;
    var i = 0;
    var foundStudio = false;
    var program_dir;
    // OK, This hack only works on Windows, not on Mac OS or Linux.  We will be deleting this eventually!
    if (module.exports.isWindows()) {
        var result = execa.sync(path.join(__dirname, 'getASPath.bat'));
        // console.log('result.stdout =' + result.stdout.toString());
        // console.log('result.stderr =' + result.stderr.toString());

        if (result.stderr.toString().length > 0) {
            var androidPath = path.join(process.env.ProgramFiles, 'Android') + '/';
            if (fs.existsSync(androidPath)) {
                program_dir = fs.readdirSync(androidPath);
                while (i < program_dir.length && !foundStudio) {
                    if (program_dir[i].startsWith('Android Studio')) {
                        foundStudio = true;
                        androidStudioPath = path.join(process.env.ProgramFiles, 'Android', program_dir[i], 'gradle');
                    } else { ++i; }
                }
            }
        } else {
            // console.log('got android studio path from registry');
            // remove the (os independent) new line char at the end of stdout
            // add gradle to match the above.
            androidStudioPath = path.join(result.stdout.toString().split('\r\n')[0], 'gradle');
        }
    }

    if (androidStudioPath !== null && fs.existsSync(androidStudioPath)) {
        var dirs = fs.readdirSync(androidStudioPath);
        if (dirs[0].split('-')[0] === 'gradle') {
            return path.join(androidStudioPath, dirs[0], 'bin', 'gradle');
        }
    } else {
        // OK, let's try to check for Gradle!
        return forgivingWhichSync('gradle');
    }
};

問題のコードは、33行目のif文です。

Cordova環境の構築時に「gradle-7.4.2.zip」をダウンロードし、「AndroidStudio」フォルダ内に「gradle」フォルダを作成し、そこに展開しました。
例)「C:\AndroidStudio\gradle\~」

この状態でビルドすると、31行のif文は「androidStudioPath」に「C:\AndroidStudio\gradle」が格納されているのでTrueとなり、33行のif文は「gradle」フォルダは存在しないのでFalseとなります。
このとき、returnがないのでUndefinedとなります。

そこで「AndroidStudio」フォルダ内に作成した「gradle」フォルダの中に「gradle」フォルダを作成し、そこにgradleを移動しました。
例)「C:\AndroidStudio\gradle\gradle\~」

この状態でビルドすると、31行のif文はTrueとなり、33行のif文もTrueとなるので、returnで戻り値が返ります。

結論として、以下の二つの方法で解決することができます。

1.「gradle-7.4.2.zip」をダウンロードし、「AndroidStudio」フォルダ内に「gradle-7.4.2」フォルダを作成して展開する。
2.「gradle-7.4.2.zip」をダウンロードし、「AndroidStudio」フォルダ内に「gradle」フォルダを作成し、さらにその中に「gradle」フォルダを作成して展開する。

Recommended Posts