mirror of
https://github.com/aspnet/JavaScriptServices.git
synced 2025-12-22 17:47:53 +00:00
Update aspnet-webpack to 2.0.1, automatically disabling the middleware if we detect the process doesn't have sufficient disk permissions
This commit is contained in:
1700
src/Microsoft.AspNetCore.SpaServices/npm/aspnet-webpack/package-lock.json
generated
Normal file
1700
src/Microsoft.AspNetCore.SpaServices/npm/aspnet-webpack/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "aspnet-webpack",
|
"name": "aspnet-webpack",
|
||||||
"version": "2.0.0",
|
"version": "2.0.1",
|
||||||
"description": "Helpers for using Webpack in ASP.NET Core projects. Works in conjunction with the Microsoft.AspNetCore.SpaServices NuGet package.",
|
"description": "Helpers for using Webpack in ASP.NET Core projects. Works in conjunction with the Microsoft.AspNetCore.SpaServices NuGet package.",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -5,11 +5,11 @@ import * as fs from 'fs';
|
|||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import * as querystring from 'querystring';
|
import * as querystring from 'querystring';
|
||||||
import { requireNewCopy } from './RequireNewCopy';
|
import { requireNewCopy } from './RequireNewCopy';
|
||||||
|
import { hasSufficientPermissions } from './WebpackTestPermissions';
|
||||||
|
|
||||||
export type CreateDevServerResult = {
|
export type CreateDevServerResult = {
|
||||||
Port: number,
|
Port: number,
|
||||||
PublicPaths: string[],
|
PublicPaths: string[]
|
||||||
PublicPath: string // For backward compatibility with older verions of Microsoft.AspNetCore.SpaServices. Will be removed soon.
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface CreateDevServerCallback {
|
export interface CreateDevServerCallback {
|
||||||
@@ -224,6 +224,16 @@ function beginWebpackWatcher(webpackConfig: webpack.Configuration) {
|
|||||||
export function createWebpackDevServer(callback: CreateDevServerCallback, optionsJson: string) {
|
export function createWebpackDevServer(callback: CreateDevServerCallback, optionsJson: string) {
|
||||||
const options: CreateDevServerOptions = JSON.parse(optionsJson);
|
const options: CreateDevServerOptions = JSON.parse(optionsJson);
|
||||||
|
|
||||||
|
// See the large comment in WebpackTestPermissions.ts for details about this
|
||||||
|
if (!hasSufficientPermissions()) {
|
||||||
|
console.log('WARNING: Webpack dev middleware is not enabled because the server process does not have sufficient permissions. You should either remove the UseWebpackDevMiddleware call from your code, or to make it work, give your server process user account permission to write to your application directory and to read all ancestor-level directories.');
|
||||||
|
callback(null, {
|
||||||
|
Port: 0,
|
||||||
|
PublicPaths: []
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Read the webpack config's export, and normalize it into the more general 'array of configs' format
|
// Read the webpack config's export, and normalize it into the more general 'array of configs' format
|
||||||
let webpackConfigExport: WebpackConfigFileExport = requireNewCopy(options.webpackConfigPath);
|
let webpackConfigExport: WebpackConfigFileExport = requireNewCopy(options.webpackConfigPath);
|
||||||
if (webpackConfigExport instanceof Function) {
|
if (webpackConfigExport instanceof Function) {
|
||||||
@@ -298,11 +308,7 @@ export function createWebpackDevServer(callback: CreateDevServerCallback, option
|
|||||||
// Tell the ASP.NET app what addresses we're listening on, so that it can proxy requests here
|
// Tell the ASP.NET app what addresses we're listening on, so that it can proxy requests here
|
||||||
callback(null, {
|
callback(null, {
|
||||||
Port: listener.address().port,
|
Port: listener.address().port,
|
||||||
PublicPaths: normalizedPublicPaths,
|
PublicPaths: normalizedPublicPaths
|
||||||
|
|
||||||
// For back-compatibility with older versions of Microsoft.AspNetCore.SpaServices, in the case where
|
|
||||||
// you have exactly one webpackConfigArray entry. This will be removed soon.
|
|
||||||
PublicPath: normalizedPublicPaths[0]
|
|
||||||
});
|
});
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
callback(ex.stack, null);
|
callback(ex.stack, null);
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
import * as fs from 'fs';
|
||||||
|
import * as path from 'path';
|
||||||
|
const isWindows = /^win/.test(process.platform);
|
||||||
|
|
||||||
|
// On Windows, Node (still as of v8.1.3) has an issue whereby, when locating JavaScript modules
|
||||||
|
// on disk, it walks up the directory hierarchy to the disk root, testing whether each directory
|
||||||
|
// is a symlink or not. This fails with an exception if the process doesn't have permission to
|
||||||
|
// read those directories. This is a problem when hosting in full IIS, because in typical cases
|
||||||
|
// the process does not have read permission for higher-level directories.
|
||||||
|
//
|
||||||
|
// NodeServices itself works around this by injecting a patched version of Node's 'lstat' API that
|
||||||
|
// suppresses these irrelevant errors during module loads. This covers most scenarios, but isn't
|
||||||
|
// enough to make Webpack dev middleware work, because typical Webpack configs use loaders such as
|
||||||
|
// 'awesome-typescript-loader', which works by forking a child process to do some of its work. The
|
||||||
|
// child process does not get the patched 'lstat', and hence fails. It's an especially bad failure,
|
||||||
|
// because the Webpack compiler doesn't even surface the exception - it just never completes the
|
||||||
|
// compilation process, causing the application to hang indefinitely.
|
||||||
|
//
|
||||||
|
// Additionally, Webpack dev middleware will want to write its output to disk, which is also going
|
||||||
|
// to fail in a typical IIS process, because you won't have 'write' permission to the app dir by
|
||||||
|
// default. We have to actually write the build output to disk (and not purely keep it in the in-
|
||||||
|
// memory file system) because the server-side prerendering Node instance is a separate process
|
||||||
|
// that only knows about code changes when it sees the compiled files on disk change.
|
||||||
|
//
|
||||||
|
// In the future, we'll hopefully get Node to fix its underlying issue, and figure out whether VS
|
||||||
|
// could give 'write' access to the app dir when launching sites in IIS. But until then, disable
|
||||||
|
// Webpack dev middleware if we detect the server process doesn't have the necessary permissions.
|
||||||
|
|
||||||
|
export function hasSufficientPermissions() {
|
||||||
|
if (isWindows) {
|
||||||
|
return canReadDirectoryAndAllAncestors(process.cwd());
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function canReadDirectoryAndAllAncestors(dir: string): boolean {
|
||||||
|
if (!canReadDirectory(dir)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const parentDir = path.resolve(dir, '..');
|
||||||
|
if (parentDir === dir) {
|
||||||
|
// There are no more parent directories - we've reached the disk root
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return canReadDirectoryAndAllAncestors(parentDir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function canReadDirectory(dir: string): boolean {
|
||||||
|
try {
|
||||||
|
fs.statSync(dir);
|
||||||
|
return true;
|
||||||
|
} catch(ex) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user