wintercms / winter

Free, open-source, self-hosted CMS platform based on the Laravel PHP Framework.
https://wintercms.com
MIT License
1.38k stars 193 forks source link

Laravel Mix is not working as expected on Windows Platform #505

Closed iamyigitkoc closed 2 years ago

iamyigitkoc commented 2 years ago

Winter CMS Build

1.1

PHP Version

8.0

Database engine

MySQL/MariaDB

Plugins installed

Issue description

Summary

Laravel Mix implementation has issues on Windows 10. The newly implemted "mix:compile" and "mix:watch" commands have many issues preventing mix feature running. [Exact PHP version 8.0.14]

Bug 1:

First of all, I found out that path concatenations are not cross platform safe. Because of this bug, relative paths can't be concatenated and the returnes something like "C:\path\to\root\C:\path\to\root\themes\foo-bar/mix.webpack.js".

Example issue from code:

// System\Classes\MixAssets : Line 102

$this->registerPackage($name, $theme->getPath() . '/' . $file);

Should be:

$this->registerPackage($name, $theme->getPath() . DIRECTORY_SEPARATOR . $file);

(PHP should have handled conversion but it didn't in this case)

Following classes in System module have this issue.

Error message and log:

PS F:\Dev\wn-laravel-mix-error> php artisan mix:compile --verbose
Mixing package "snowboard"

In Filesystem.php line 133:

  [ErrorException]
  file_put_contents(F:\Dev\wn-laravel-mix-error\F:\Dev\wn-laravel-mix-error\modules\system\assets\js\snowboard/mix.we
  bpack.js): Failed to open stream: No such file or directory

Exception trace:
  at F:\Dev\wn-laravel-mix-error\vendor\laravel\framework\src\Illuminate\Filesystem\Filesystem.php:133
 Illuminate\Foundation\Bootstrap\HandleExceptions->handleError() at n/a:n/a
 file_put_contents() at F:\Dev\wn-laravel-mix-error\vendor\laravel\framework\src\Illuminate\Filesystem\Filesystem.php:133
 Illuminate\Filesystem\Filesystem->put() at F:\Dev\wn-laravel-mix-error\vendor\winter\storm\src\Filesystem\Filesystem.php:243
 Winter\Storm\Filesystem\Filesystem->put() at F:\Dev\wn-laravel-mix-error\vendor\laravel\framework\src\Illuminate\Support\Facades\Facade.php:261
 Illuminate\Support\Facades\Facade::__callStatic() at F:\Dev\wn-laravel-mix-error\modules\system\console\MixCompile.php:206
 System\Console\MixCompile->createWebpackConfig() at F:\Dev\wn-laravel-mix-error\modules\system\console\MixCompile.php:148
 System\Console\MixCompile->mixPackage() at F:\Dev\wn-laravel-mix-error\modules\system\console\MixCompile.php:96
 System\Console\MixCompile->handle() at F:\Dev\wn-laravel-mix-error\vendor\laravel\framework\src\Illuminate\Container\BoundMethod.php:36
 Illuminate\Container\BoundMethod::Illuminate\Container\{closure}() at F:\Dev\wn-laravel-mix-error\vendor\laravel\framework\src\Illuminate\Container\Util.php:37
 Illuminate\Container\Util::unwrapIfClosure() at F:\Dev\wn-laravel-mix-error\vendor\laravel\framework\src\Illuminate\Container\BoundMethod.php:93
 Illuminate\Container\BoundMethod::callBoundMethod() at F:\Dev\wn-laravel-mix-error\vendor\laravel\framework\src\Illuminate\Container\BoundMethod.php:37
 Illuminate\Container\BoundMethod::call() at F:\Dev\wn-laravel-mix-error\vendor\laravel\framework\src\Illuminate\Container\Container.php:590
 Illuminate\Container\Container->call() at F:\Dev\wn-laravel-mix-error\vendor\laravel\framework\src\Illuminate\Console\Command.php:134
 Illuminate\Console\Command->execute() at F:\Dev\wn-laravel-mix-error\vendor\symfony\console\Command\Command.php:255
 Symfony\Component\Console\Command\Command->run() at F:\Dev\wn-laravel-mix-error\vendor\laravel\framework\src\Illuminate\Console\Command.php:121
 Illuminate\Console\Command->run() at F:\Dev\wn-laravel-mix-error\vendor\symfony\console\Application.php:1009
 Symfony\Component\Console\Application->doRunCommand() at F:\Dev\wn-laravel-mix-error\vendor\symfony\console\Application.php:273
 Symfony\Component\Console\Application->doRun() at F:\Dev\wn-laravel-mix-error\vendor\symfony\console\Application.php:149
 Symfony\Component\Console\Application->run() at F:\Dev\wn-laravel-mix-error\vendor\laravel\framework\src\Illuminate\Console\Application.php:93
 Illuminate\Console\Application->run() at F:\Dev\wn-laravel-mix-error\vendor\laravel\framework\src\Illuminate\Foundation\Console\Kernel.php:131
 Illuminate\Foundation\Console\Kernel->handle() at F:\Dev\wn-laravel-mix-error\artisan:35

Bug 2:

After fixing the each one of the concatenations, compilation process couldn't run webpack.js in bin directory. A windows execution error window appeared on screen for "Microsoft JScript Error". "Trying to execute a script..." page on stackoverflow entry had some temporary solutions however system default is an issue. Thus, I tried to find main issue.

"System\Console\MixCompile->createCommand()" tries to execute webpack directly however Windows does not start this script with Node.js. I tried removing .JS from PATHEXT but it didn't workout. Then selected node.exe as default program for .js files. It kind of worked but it was not a good workaround.

I removed webpack.js path then added "npx mix build/watch", changed "--config" to "--mix-config" and removed '--progress'; this worked for me. Still, this is not a good execution command.

Error Message:

PS F:\Dev\wn-laravel-mix-error> php artisan mix:compile --verbose
Mixing package "snowboard"
Unknown command: "F:\Dev\wn-laravel-mix-error\node_modules\webpack\bin\webpack.js"

To see a list of supported npm commands, run:
  npm help
Unable to compile package "snowboard"

Bug 3:

require() function can't find 'laravel-mix' module when MixCompile executes the process. I didn't understand, but require removes the seperators in path somehow.

Error message:

PS F:\Dev\wn-laravel-mix-error> php artisan mix:compile --verbose
Mixing package "snowboard"
[webpack-cli] Error: Cannot find module 'F:Devwn-laravel-mix-error/node_modules/laravel-mix/src/Engine'
Require stack:
- F:\Dev\wn-laravel-mix-error\modules\system\assets\js\snowboard\mix.webpack.js
- F:\Dev\wn-laravel-mix-error\node_modules\laravel-mix\setup\webpack.config.js
- F:\Dev\wn-laravel-mix-error\node_modules\webpack-cli\lib\webpack-cli.js
- F:\Dev\wn-laravel-mix-error\node_modules\webpack-cli\lib\bootstrap.js
- F:\Dev\wn-laravel-mix-error\node_modules\webpack-cli\bin\cli.js
- F:\Dev\wn-laravel-mix-error\node_modules\webpack\bin\webpack.js
    at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
    at Function.Module._load (node:internal/modules/cjs/loader:778:27)
    at Module.require (node:internal/modules/cjs/loader:1005:19)
    at require (node:internal/modules/cjs/helpers:102:18)
    at Object.<anonymous> (F:\Dev\wn-laravel-mix-error\modules\system\assets\js\snowboard\mix.webpack.js:2:40)
    at Module._compile (node:internal/modules/cjs/loader:1101:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
    at Module.require (node:internal/modules/cjs/loader:1005:19) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    'F:\\Dev\\wn-laravel-mix-error\\modules\\system\\assets\\js\\snowboard\\mix.webpack.js',
    'F:\\Dev\\wn-laravel-mix-error\\node_modules\\laravel-mix\\setup\\webpack.config.js',
    'F:\\Dev\\wn-laravel-mix-error\\node_modules\\webpack-cli\\lib\\webpack-cli.js',
    'F:\\Dev\\wn-laravel-mix-error\\node_modules\\webpack-cli\\lib\\bootstrap.js',
    'F:\\Dev\\wn-laravel-mix-error\\node_modules\\webpack-cli\\bin\\cli.js',
    'F:\\Dev\\wn-laravel-mix-error\\node_modules\\webpack\\bin\\webpack.js'
  ]
}
Unable to compile package "snowboard"

Additional note:

Steps to replicate

  1. Fresh installation of Winter CMS [Using SQLite is enough since no DB work needed]
  2. Run "php artisan mix:install"
  3. Run "php artisan mix:compile" Bug 1 happens at this point
  4. Replace all '/' seperators on bugged classes with "DIRECTORY_SEPARATOR" constant [Overwriting old files with files in "bug-1-fix" branch of wn-laravel-mix-error-fix is enough]
  5. Run "PHP artisan mix:compile" "Bug 2 happens at this point"
  6. Fix $command in createCommand() of MixCompile class [Overwriting old files with files in "bug-2-fix" branch of wn-laravel-mix-error-fix is enough]
  7. Run "PHP artisan mix:compile" "Bug 3 happens at this point"

Workaround

I provided some kind of "fixed" code in wn-laravel-mix-error-fix for Bug 1 and Bug 2 seperately.

fixed-for-windows branch is a workaround that makes running "php artisan mix:compile" or "php artisan mix:watch" possible.

The last bug was caused by singular '\'. Window's separator was not revesed or escaped in webpack config file created via fixture. To fix this issue I added addslashes() escape function to every path value replaced in config file.

Last words

Edit 1:

Created a complete workaround.

bennothommo commented 2 years ago

Great work investigating this @iamyigitkoc. We'll take a look at your workaround and do some of our own investigation into this. I had a feeling that Windows paths might not be handled by the new functionality as most of its functionality operates on the CLI level, although we had hoped that PHP (or Symfony Process) might've handled a fair few of the gotchas.

damsfx commented 2 years ago

I can confirm that the patched commands from @iamyigitkoc work's for me.

php artisan mix:compile -p theme-workshop
Mixing package "theme-workshop

Laravel Mix
Build successful

LukeTowers commented 2 years ago

Glad to hear it! Can someone submit the patches as a single PR to this repo?

iamyigitkoc commented 2 years ago

I can do it this weekend. I will also test it on linux based OS wether it breaks previous builds or not.

damsfx commented 2 years ago

I can do it this weekend. I will also test it on linux based OS wether it breaks previous builds or not.

Any news @iamyigitkoc ?

iamyigitkoc commented 2 years ago

I can do it this weekend. I will also test it on linux based OS wether it breaks previous builds or not.

Any news @iamyigitkoc ?

I had a personal urgency, just updated the code. Gonna test the code then open the PR.

iamyigitkoc commented 2 years ago

Can someone validate the build on a linux machine if it works as expected?

damsfx commented 2 years ago

Thank's for this PR @iamyigitkoc !!