-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
BREAKING CHANGES: create static option and remove replaced options #2670
Changes from 34 commits
972cd03
2529175
64b767e
745fb81
88f08d2
e365430
16e0221
497f35d
9fb688c
7728596
f1e3302
963244c
5df413c
bf0f789
d5a4ae4
d6821c3
a612b38
dfc8f69
da0357f
24c82f6
769e080
b64e513
888b96e
544e0b4
0191a57
51c6b2d
1670984
4b65a57
0e3e20b
f26069f
ce5468b
efe9bf4
b17f327
20f1fb6
30b3aca
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,7 +18,6 @@ const webpackDevMiddleware = require('webpack-dev-middleware'); | |
const getFilenameFromUrl = require('webpack-dev-middleware/dist/utils/getFilenameFromUrl') | ||
.default; | ||
const validateOptions = require('schema-utils'); | ||
const isAbsoluteUrl = require('is-absolute-url'); | ||
const normalizeOptions = require('./utils/normalizeOptions'); | ||
const updateCompiler = require('./utils/updateCompiler'); | ||
const getCertificate = require('./utils/getCertificate'); | ||
|
@@ -304,112 +303,43 @@ class Server { | |
} | ||
|
||
setupStaticFeature() { | ||
const contentBase = this.options.contentBase; | ||
const contentBasePublicPath = this.options.contentBasePublicPath; | ||
|
||
if (Array.isArray(contentBase)) { | ||
contentBase.forEach((item, index) => { | ||
let publicPath = contentBasePublicPath; | ||
|
||
if ( | ||
Array.isArray(contentBasePublicPath) && | ||
contentBasePublicPath[index] | ||
) { | ||
publicPath = contentBasePublicPath[index] || contentBasePublicPath[0]; | ||
} | ||
|
||
this.app.use(publicPath, express.static(item)); | ||
}); | ||
} else if (isAbsoluteUrl(String(contentBase))) { | ||
this.logger.warn( | ||
'Using a URL as contentBase is deprecated and will be removed in the next major version. Please use the proxy option instead.' | ||
); | ||
|
||
this.logger.warn( | ||
'proxy: {\n\t"*": "<your current contentBase configuration>"\n}' | ||
); | ||
|
||
// Redirect every request to contentBase | ||
this.app.get('*', (req, res) => { | ||
res.writeHead(302, { | ||
Location: contentBase + req.path + (req._parsedUrl.search || ''), | ||
}); | ||
|
||
res.end(); | ||
}); | ||
} else if (typeof contentBase === 'number') { | ||
this.logger.warn( | ||
'Using a number as contentBase is deprecated and will be removed in the next major version. Please use the proxy option instead.' | ||
); | ||
|
||
this.logger.warn( | ||
'proxy: {\n\t"*": "//localhost:<your current contentBase configuration>"\n}' | ||
); | ||
|
||
// Redirect every request to the port contentBase | ||
this.app.get('*', (req, res) => { | ||
res.writeHead(302, { | ||
Location: `//localhost:${contentBase}${req.path}${ | ||
req._parsedUrl.search || '' | ||
}`, | ||
}); | ||
|
||
res.end(); | ||
this.options.static.forEach((staticOption) => { | ||
staticOption.publicPath.forEach((publicPath) => { | ||
this.app.use( | ||
publicPath, | ||
express.static(staticOption.directory, staticOption.staticOptions) | ||
); | ||
}); | ||
} else { | ||
// route content request | ||
this.app.use( | ||
contentBasePublicPath, | ||
express.static(contentBase, this.options.staticOptions) | ||
); | ||
} | ||
}); | ||
} | ||
|
||
setupServeIndexFeature() { | ||
const contentBase = this.options.contentBase; | ||
const contentBasePublicPath = this.options.contentBasePublicPath; | ||
|
||
if (Array.isArray(contentBase)) { | ||
contentBase.forEach((item) => { | ||
this.app.use(contentBasePublicPath, (req, res, next) => { | ||
// serve-index doesn't fallthrough non-get/head request to next middleware | ||
if (req.method !== 'GET' && req.method !== 'HEAD') { | ||
return next(); | ||
} | ||
this.options.static.forEach((staticOption) => { | ||
staticOption.publicPath.forEach((publicPath) => { | ||
if (staticOption.serveIndex) { | ||
this.app.use(publicPath, (req, res, next) => { | ||
// serve-index doesn't fallthrough non-get/head request to next middleware | ||
if (req.method !== 'GET' && req.method !== 'HEAD') { | ||
return next(); | ||
} | ||
|
||
serveIndex(item, { icons: true })(req, res, next); | ||
}); | ||
}); | ||
} else if ( | ||
typeof contentBase !== 'number' && | ||
!isAbsoluteUrl(String(contentBase)) | ||
) { | ||
this.app.use(contentBasePublicPath, (req, res, next) => { | ||
// serve-index doesn't fallthrough non-get/head request to next middleware | ||
if (req.method !== 'GET' && req.method !== 'HEAD') { | ||
return next(); | ||
serveIndex(staticOption.directory, staticOption.serveIndex)( | ||
req, | ||
res, | ||
next | ||
); | ||
}); | ||
} | ||
|
||
serveIndex(contentBase, { icons: true })(req, res, next); | ||
}); | ||
} | ||
}); | ||
} | ||
|
||
setupWatchStaticFeature() { | ||
const contentBase = this.options.contentBase; | ||
|
||
if (isAbsoluteUrl(String(contentBase)) || typeof contentBase === 'number') { | ||
throw new Error('Watching remote files is not supported.'); | ||
} else if (Array.isArray(contentBase)) { | ||
contentBase.forEach((item) => { | ||
if (isAbsoluteUrl(String(item)) || typeof item === 'number') { | ||
throw new Error('Watching remote files is not supported.'); | ||
} | ||
this._watch(item); | ||
}); | ||
} else { | ||
this._watch(contentBase); | ||
} | ||
this.options.static.forEach((staticOption) => { | ||
if (staticOption.watch) { | ||
this.watchFiles(staticOption.directory, staticOption.watch); | ||
} | ||
}); | ||
} | ||
|
||
setupOnBeforeSetupMiddlewareFeature() { | ||
|
@@ -449,16 +379,13 @@ class Server { | |
this.setupHistoryApiFallbackFeature(); | ||
} | ||
}, | ||
// Todo rename to `static` in future major release | ||
contentBaseFiles: () => { | ||
static: () => { | ||
this.setupStaticFeature(); | ||
}, | ||
// Todo rename to `serveIndex` in future major release | ||
contentBaseIndex: () => { | ||
staticServeIndex: () => { | ||
this.setupServeIndexFeature(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And let's rename method names: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Just did that 👍 |
||
}, | ||
// Todo rename to `watchStatic` in future major release | ||
watchContentBase: () => { | ||
staticWatch: () => { | ||
this.setupWatchStaticFeature(); | ||
}, | ||
onBeforeSetupMiddleware: () => { | ||
|
@@ -501,24 +428,20 @@ class Server { | |
runnableFeatures.push('proxy', 'middleware'); | ||
} | ||
|
||
if (this.options.contentBase !== false) { | ||
runnableFeatures.push('contentBaseFiles'); | ||
if (this.options.static) { | ||
runnableFeatures.push('static'); | ||
} | ||
|
||
if (this.options.historyApiFallback) { | ||
runnableFeatures.push('historyApiFallback', 'middleware'); | ||
|
||
if (this.options.contentBase !== false) { | ||
runnableFeatures.push('contentBaseFiles'); | ||
if (this.options.static) { | ||
runnableFeatures.push('static'); | ||
} | ||
} | ||
|
||
if (this.options.contentBase && this.options.serveIndex) { | ||
runnableFeatures.push('contentBaseIndex'); | ||
} | ||
|
||
if (this.options.watchContentBase) { | ||
runnableFeatures.push('watchContentBase'); | ||
if (this.options.static) { | ||
runnableFeatures.push('staticServeIndex', 'staticWatch'); | ||
} | ||
|
||
runnableFeatures.push('magicHtml'); | ||
|
@@ -903,31 +826,31 @@ class Server { | |
} | ||
} | ||
|
||
_watch(watchPath) { | ||
watchFiles(watchPath, watchOptions) { | ||
// duplicate the same massaging of options that watchpack performs | ||
// https://github.com/webpack/watchpack/blob/master/lib/DirectoryWatcher.js#L49 | ||
// this isn't an elegant solution, but we'll improve it in the future | ||
// eslint-disable-next-line no-undefined | ||
const usePolling = this.options.watchOptions.poll ? true : undefined; | ||
const usePolling = watchOptions.poll ? true : undefined; | ||
const interval = | ||
typeof this.options.watchOptions.poll === 'number' | ||
? this.options.watchOptions.poll | ||
typeof watchOptions.poll === 'number' | ||
? watchOptions.poll | ||
: // eslint-disable-next-line no-undefined | ||
undefined; | ||
|
||
const watchOptions = { | ||
const finalWatchOptions = { | ||
ignoreInitial: true, | ||
persistent: true, | ||
followSymlinks: false, | ||
atomic: false, | ||
alwaysStat: true, | ||
ignorePermissionErrors: true, | ||
ignored: this.options.watchOptions.ignored, | ||
ignored: watchOptions.ignored, | ||
usePolling, | ||
interval, | ||
}; | ||
|
||
const watcher = chokidar.watch(watchPath, watchOptions); | ||
const watcher = chokidar.watch(watchPath, finalWatchOptions); | ||
// disabling refreshing on changing the content | ||
if (this.options.liveReload) { | ||
watcher.on('change', () => { | ||
|
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 be multiple
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.
@evilebottnawi Like
--static=example/dir1,example/dir2
?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.
Like
--static=example/dir1 --static=example/dir2