【Laravel8】npm run devがエラーになるときの対処法【パス名が空白】

PHP Programming

どうも、あきのりです。
プログラミングを勉強しつつ、Webサービスやゲーム制作(予定)をしています。

Laravelを使ってWebアプリを作っているんですが、Node.JSを使う必要があるんですね。
Login機能だったり、Sassなどを使うときに必要だったりするので、インストールしてみました。

が、途中でエラー地獄にハマって、丸1日格闘したのでその共有をしておきたいと思います。

開発者がファイル修正してくれたみたいで、再度インストールすればエラーは消えるそうです(感謝!)。
・Windows10
・VS Code
・XAMPP, PHP 7.4.11
・Laravel 8.5.8

npm run devを実行するとエラーに

Laravelでnode.jsを使うには以下のコマンドを打ち込む必要があります。

npm install

Laravelプロジェクトを立ち上げたとき、あらかじめ入っているpackage.jsonにある情報から必要なファイルをインストールしてきてくれます。それがnode_modulesというディレクトリに入ります。

ここまでは、OK。

例えばSassをCSS変換したり、ログイン機能を作るためには以下のコマンドを打つわけですが、

npm run dev

なぜかエラーが出まくります。


> @ dev C:\Users\*** ***\sample_app
> npm run development


> @ development C:\Users\*** ***\sample_app
> mix

[webpack-cli] Running multiple commands at the same time is not possible
[webpack-cli] Found commands: 'bundle', 'Akinori\sample_app\node_modules\laravel-mix\setup\webpack.config.js'
[webpack-cli] Run 'webpack --help' to see available commands and options
npm ERR! code ELIFECYCLE
npm ERR! errno 2
npm ERR! @ development: `mix`
npm ERR! Exit status 2
npm ERR!
npm ERR! Failed at the @ development script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     C:\Users\*** ***\AppData\Roaming\npm-cache\_logs\2021-01-14T17_00_01_305Z-debug.log
npm ERR! code ELIFECYCLE
npm ERR! errno 2
npm ERR! @ dev: `npm run development`
npm ERR! Exit status 2
npm ERR!
npm ERR! Failed at the @ dev script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     C:\Users\*** ***\AppData\Roaming\npm-cache\_logs\2021-01-14T17_00_01_347Z-debug.log

*** ***は僕の名前です)
いろいろ調べても出なかったんですが、こちらの議論を見ると、こんなことが書いてありました。

パス名に空白が入っているとエラーになるのかも

僕はC:/User/自分の名前/sample_appという感じで、「自分の名前」フォルダの中にLaravelプロジェクトを入れていました。

そして、自分の名前が「苗字 名前」という感じで空白があったんですよね。
これがどうやらエラーの原因らしいです。

解決方法3つ

いろいろ調べても解決策が見つからなかったのですが、丸1日かけて3つほどさがしたのでシェアします。
どれか1つは誰でもできるはずなのでぜひぜひ。

フォルダ名を変えたり、場所を変える

手っ取り早いのはフォルダ名を変えたり、そもそもLaravelファイルをごっそり別に移動することです。
例えば、Windows(C):直下に移動して、npm run devを実行すると、うまくいきました。

ただ、ユーザー名のフォルダ(僕のような例)だと、ちょっと厄介です。
まず、フォルダ名を変更することができないんですね(できるんですが、ミスると最悪PCが使えなくなります)。

また、場所を移動させるにも、デスクトップなどは結局「ユーザフォルダ」内にあるので、ちょっと管理がめんどくさい。

さらに、ターミナル起動時は「ユーザフォルダ」から始まるのですこぶる面倒くさいです。

なので、保存場所はあまり変更はしたくないですね。

laravel-mixの内容を変更

ということで、laravel-mixのコードをそのままいじっちゃいましょう。

一応、解決方法を見つけました。こちらを参考にしています。

製作者も「まだ仮の解決法」と言っているので、確実とは言えませんが、これで動くのは確認済みです。

まず、Laravelプロジェクト内でnode_modules/laravel-mix/bin/cli.jsを開きます。

そして、以下のように書き換えて下さい(コードを全て消して、これをコピペしてください)。


#!/usr/bin/env node

const { Command } = require('commander');
const { spawn } = require('child_process');
//added
const path = require('path');

run();

/**
 * Run the program.
 */
async function run() {
    const program = new Command();

    program.name('mix');
    program.version('0.0.1');
    program.option(
        '--mix-config ',
        'The path to your Mix configuration file.',
        'webpack.mix'
    );

    program
        .command('watch')
        .description('Build and watch files for changes.')
        .option('--hot', 'Enable hot reloading.', false)
        .action(cmd =>
            executeScript('watch', { ...program.opts(), ...cmd.opts() }, cmd.args)
        );

    program
        .command('build', { isDefault: true })
        .description('Compile Mix.')
        .option('-p, --production', 'Run Mix in production mode.', false)
        .action(cmd =>
            executeScript('build', { ...program.opts(), ...cmd.opts() }, cmd.args)
        );

    await program.parseAsync(process.argv);
}

/**
 * Execute the script.
 *
 * @param {"build"|"watch"} cmd
 * @param {{[key: string]: any}} opts
 * @param {string[]} args
 */
async function executeScript(cmd, opts, args = []) {
    const env = opts.production
        ? 'production'
        : (isTesting() && process.env.NODE_ENV === 'test') || !process.env.NODE_ENV
        ? 'development'
        : process.env.NODE_ENV;

    //added
    // We MUST use a relative path because the files
    // created by npm dont correctly handle paths
    // containg spaces on Windows (yarn does)
    const configPath = path.relative(
        process.cwd(),
        require.resolve('../setup/webpack.config.js')
    );

    let script = [
        `cross-env NODE_ENV=${env}`,
        `MIX_FILE="${opts.mixConfig}"`,
        commandScript(cmd, opts),
        //deleted & added
        `--config="${configPath}"`,
        ...quoteArgs(args)
    ].join(' ');

    if (isTesting()) {
        return process.stdout.write(script);
    }

    const child = spawn(script, {
        stdio: 'inherit',
        shell: true
    });

    child.on('exit', code => {
        process.exitCode = code;
    });
}

/**
 * Get the command-specific portion of the script.
 *
 * @param {"build"|"watch"} cmd
 * @param {{[key: string]: any}} opts
 */
function commandScript(cmd, opts) {
    if (cmd === 'build') {
        if (isTTY()) {
            return 'npx webpack --progress';
        }

        return 'npx webpack';
    } else if (cmd === 'watch' && !opts.hot) {
        if (isTTY()) {
            return 'npx webpack --progress --watch';
        }

        return 'npx webpack --watch';
    } else if (cmd === 'watch' && opts.hot) {
        return 'npx webpack serve --hot';
    }
}

/**
 * Get the command arguments with quoted values.
 *
 * @param {string[]} args
 */
function quoteArgs(args) {
    return args.map(arg => {
        // Split string at first = only
        const pattern = /^([^=]+)=(.*)$/;
        const keyValue = arg.includes('=') ? pattern.exec(arg).slice(1) : [];

        if (keyValue.length === 2) {
            return `${keyValue[0]}="${keyValue[1]}"`;
        }

        return arg;
    });
}

function isTesting() {
    return process.env.TESTING;
}

function isTTY() {
    if (isTesting() && process.env.IS_TTY !== undefined) {
        return process.env.IS_TTY === 'true';
    }

    if (isTesting() && process.stdout.isTTY === undefined) {
        return true;
    }

    return process.stdout.isTTY;
}

これで、動きます。

動かなかった場合は、一度元に戻して、こちらを元に、「+(プラス)」の部分を追加、「-(マイナス)」の部分を消去して修正してください。

yarnを使って実行する

もう一つが、yarnを使う方法です(これは試してないので、うまくいくか分かりません)。
yarnnpmと同じでnode.jsの機能を持ったパッケージ(図書館みたいな)です。
インストールがyarnの方が速かったりとちょっとした違いはあるようですが、根本は一緒です。

先ほどのリンクでも書かれていたんですが、

npmで操作したときだけ、どうやらエラーになるらしい

です。

yarnを使うとうまくいくと別で書いてあったので、イケるのかも。
ただ、そのためにはpackage.jsonの内容を変更しないといけなかったりと、設定が少し面倒です。

参考になりそうなものはこちら。

Laravelのバージョンを下げる

後はこれですかね。一応、前まではエラーがなかったらしいので載せておきます。
が、全く根拠がないですし、うまくいっても根本的に解決していないのでオススメしません。

まとめ

ということで、今回のようなエラー出たときは、これを参考にしてやりくりしてください。
おそらく開発者がバグを修正してくれると思うので期待しましょう。

あと、エラーとかを英語とかで調べられると良いですね。今回のエラーは日本語じゃ全く出てこなかったので。
英会話ですけど、ぜひお試しを。
DMM英会話

QQ English

ではでは、以上です。

スポンサードサーチ

オススメ英語学習用SNS "Our Dictionary"

人気記事英語学習用SNSをLaravelで作ってみた【システム解説あり】