-
-
Notifications
You must be signed in to change notification settings - Fork 198
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fixing Windows Support #28
Conversation
645607c
to
d84ef11
Compare
lib/config/path-util.js
Outdated
// start with outputPath, then join publicPath with it, see if it equals outputPath | ||
// in loop, do dirname on outputPath and repeat | ||
// eventually, you (may) get to the right path | ||
var contentBase = outputPath; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should be let
rather than var
769faf8
to
01ad7a7
Compare
Tests are green 🎆 - this is ready :) |
e6f65fa
to
dba5d71
Compare
* We use the intersection of the publicPath (or manifestKeyPrefix) and outputPath | ||
* to determine the "document root" of the web server. For example: | ||
* * outputPath = /var/www/public/build | ||
* * publicPath = /build/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what if publicPath is /subdir/build/
? AFAIK path.join(contentBase, publicPath) === outputPath
will never be true, as outputPath
will use \
everywhere, while path.join(contentBase, publicPath)
will have some /
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're correct. But, if the user has a publicPath
that is not a sub-string of the outputPath
, they will already have received an error forcing them to set manifestKeyPrefix
(you do not need to set this manually... until you deploy under a subdirectory or set publicPath to a CDN). So, this situation won't happen. I've just pushed a commit to hopefully clarify this - it's a bit complex since different parts of the system are working together. It is possible that the user will set a manifestKeyPrefix
that is not a substring of the outputPath
, and then they would see this error (because this is not allowed)
lib/config/path-util.js
Outdated
|
||
let outputPath = webpackConfig.outputPath; | ||
// for comparison purposes, change \ to / on Windows | ||
outputPath = outputPath.split('\\').join('/'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is split+join faster than .replace(/\\/g, '/')
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
replace only replaces the first occurrence :/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no, when using a regex, it depends whether you pass a regex matching the first place or all of them (think preg_match
vs preg_match_all
in PHP). I added the g
modifier on my regex.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right! I was mixing this up with the non-regex behavior or replace, which only replaces the first. I'll update these to regex (it's less "weird" than this)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still suggest doing a benchmark (especially before contributing to webpack-manifest-plugin
if (process.platform === 'win32') { | ||
moduleAssets[file] = moduleAssets[file].split('\\').join('/'); | ||
} | ||
/* *** MODIFICATION END *** */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this be contributed upstream too ?
test/config/path-util.js
Outdated
* | ||
* @returns {boolean} | ||
*/ | ||
function isWindows() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this could be a const rather than a function, as the value being returned will always be the same:
const isWindows = process.platform === 'win32'
// ...
if (isWindows) {
this.skip();
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1
test/config/path-util.js
Outdated
}); | ||
|
||
describe('generateManifestKeyPrefix', () => { | ||
it('manifestKeyPrefix is correctly not required on windows', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't this be skipped on Unix ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally, the code for parsing these paths would be really portable and work on any OS (e.g. even on UNIX, it handles the Windows paths correctly). So far, I've only skipped tests when this is not true - i.e. when Windows does not handle Unix correctly or Unix does not handle Windows correctly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, based on your other suggestion - I've removed all of the skips and just add a bit of isWindows
logic in each function to change the paths based on OS. This means all tests will run on both OS's - best of both worlds (and less duplication as you mentioned)
test/config/path-util.js
Outdated
expect(actualPrefix).to.equal('build/'); | ||
}); | ||
|
||
it('with absolute publicPath, manifestKeyPrefix must be set', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't this be skipped on windows ?
test/config/path-util.js
Outdated
|
||
it('when outputPath and publicPath are incompatible, manifestKeyPrefix must be set', () => { | ||
const config = createConfig(); | ||
config.outputPath = '/tmp/public/build'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to have a windows test for that too (or just change the output path here depending on the OS instead of duplicating everything)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea to alternate the path based on OS - doing that!
test/config/path-util.js
Outdated
* Some tests are very specific to different operating systems. | ||
* We use this to only run them when needed. | ||
* | ||
* @returns {boolean} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@returns
is wrong for a constant
// for Windows, we want the keys to use /, not \ | ||
// (and path.join will obviously use \ in Windows) | ||
if (process.platform === 'win32') { | ||
moduleAssets[file] = moduleAssets[file].replace(/\\/g).join('/'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is broken. proper code is .replace(/\\/g, '/')
* Refactoring delicate path logic into path-util * Fixing logic that relied in unix-style paths * Fixed a bug inside webpack-manifest-plugin that used \ for manifest.json key paths on Windows
eebc711
to
6164d80
Compare
This PR was squashed before being merged into the master branch (closes #28). Discussion ---------- Fixing Windows Support In a few places, we rely (relied) on doing some "string replace" on paths. Obviously, that doesn't play well with the windows `\` directory separators. This fixes the few places that rely on this and includes tests that exposed those failures on AppVeyor. Commits ------- 78a0680 cs 6164d80 Tweaks thanks to Stof, including combining Unix & windows tests 162d5f5 Moving some validation logic to be more clear about the flow 5f8ff97 Fixing a small bug when reporting the relative output path 6c65840 Fixing Windows support:
In a few places, we rely (relied) on doing some "string replace" on paths. Obviously, that doesn't play well with the windows
\
directory separators. This fixes the few places that rely on this and includes tests that exposed those failures on AppVeyor.