forked from daren.hsu/line_push
update
This commit is contained in:
+5
@@ -0,0 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
const middleware = require("./index");
|
||||
|
||||
module.exports = middleware.default;
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = wdm;
|
||||
|
||||
var _schemaUtils = require("schema-utils");
|
||||
|
||||
var _mimeTypes = _interopRequireDefault(require("mime-types"));
|
||||
|
||||
var _middleware = _interopRequireDefault(require("./middleware"));
|
||||
|
||||
var _getFilenameFromUrl = _interopRequireDefault(require("./utils/getFilenameFromUrl"));
|
||||
|
||||
var _setupHooks = _interopRequireDefault(require("./utils/setupHooks"));
|
||||
|
||||
var _setupWriteToDisk = _interopRequireDefault(require("./utils/setupWriteToDisk"));
|
||||
|
||||
var _setupOutputFileSystem = _interopRequireDefault(require("./utils/setupOutputFileSystem"));
|
||||
|
||||
var _ready = _interopRequireDefault(require("./utils/ready"));
|
||||
|
||||
var _options = _interopRequireDefault(require("./options.json"));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
const noop = () => {};
|
||||
|
||||
function wdm(compiler, options = {}) {
|
||||
(0, _schemaUtils.validate)(_options.default, options, {
|
||||
name: "Dev Middleware",
|
||||
baseDataPath: "options"
|
||||
});
|
||||
const {
|
||||
mimeTypes
|
||||
} = options;
|
||||
|
||||
if (mimeTypes) {
|
||||
const {
|
||||
types
|
||||
} = _mimeTypes.default; // mimeTypes from user provided options should take priority
|
||||
// over existing, known types
|
||||
|
||||
_mimeTypes.default.types = { ...types,
|
||||
...mimeTypes
|
||||
};
|
||||
}
|
||||
|
||||
const context = {
|
||||
state: false,
|
||||
stats: null,
|
||||
callbacks: [],
|
||||
options,
|
||||
compiler,
|
||||
watching: null
|
||||
}; // eslint-disable-next-line no-param-reassign
|
||||
|
||||
context.logger = context.compiler.getInfrastructureLogger("webpack-dev-middleware");
|
||||
(0, _setupHooks.default)(context);
|
||||
|
||||
if (options.writeToDisk) {
|
||||
(0, _setupWriteToDisk.default)(context);
|
||||
}
|
||||
|
||||
(0, _setupOutputFileSystem.default)(context); // Start watching
|
||||
|
||||
if (context.compiler.watching) {
|
||||
context.watching = context.compiler.watching;
|
||||
} else {
|
||||
let watchOptions;
|
||||
|
||||
if (Array.isArray(context.compiler.compilers)) {
|
||||
watchOptions = context.compiler.compilers.map(childCompiler => childCompiler.options.watchOptions || {});
|
||||
} else {
|
||||
watchOptions = context.compiler.options.watchOptions || {};
|
||||
}
|
||||
|
||||
context.watching = context.compiler.watch(watchOptions, error => {
|
||||
if (error) {
|
||||
// TODO: improve that in future
|
||||
// For example - `writeToDisk` can throw an error and right now it is ends watching.
|
||||
// We can improve that and keep watching active, but it is require API on webpack side.
|
||||
// Let's implement that in webpack@5 because it is rare case.
|
||||
context.logger.error(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const instance = (0, _middleware.default)(context); // API
|
||||
|
||||
instance.getFilenameFromUrl = url => (0, _getFilenameFromUrl.default)(context, url);
|
||||
|
||||
instance.waitUntilValid = (callback = noop) => {
|
||||
(0, _ready.default)(context, callback);
|
||||
};
|
||||
|
||||
instance.invalidate = (callback = noop) => {
|
||||
(0, _ready.default)(context, callback);
|
||||
context.watching.invalidate();
|
||||
};
|
||||
|
||||
instance.close = (callback = noop) => {
|
||||
context.watching.close(callback);
|
||||
};
|
||||
|
||||
instance.context = context;
|
||||
return instance;
|
||||
}
|
||||
+124
@@ -0,0 +1,124 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = wrapper;
|
||||
|
||||
var _path = _interopRequireDefault(require("path"));
|
||||
|
||||
var _mimeTypes = _interopRequireDefault(require("mime-types"));
|
||||
|
||||
var _getFilenameFromUrl = _interopRequireDefault(require("./utils/getFilenameFromUrl"));
|
||||
|
||||
var _handleRangeHeaders = _interopRequireDefault(require("./utils/handleRangeHeaders"));
|
||||
|
||||
var _ready = _interopRequireDefault(require("./utils/ready"));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
function wrapper(context) {
|
||||
return async function middleware(req, res, next) {
|
||||
const acceptedMethods = context.options.methods || ["GET", "HEAD"]; // fixes #282. credit @cexoso. in certain edge situations res.locals is undefined.
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
|
||||
res.locals = res.locals || {};
|
||||
|
||||
if (!acceptedMethods.includes(req.method)) {
|
||||
await goNext();
|
||||
return;
|
||||
}
|
||||
|
||||
(0, _ready.default)(context, processRequest, req);
|
||||
|
||||
async function goNext() {
|
||||
if (!context.options.serverSideRender) {
|
||||
return next();
|
||||
}
|
||||
|
||||
return new Promise(resolve => {
|
||||
(0, _ready.default)(context, () => {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
res.locals.webpack = {
|
||||
devMiddleware: context
|
||||
};
|
||||
resolve(next());
|
||||
}, req);
|
||||
});
|
||||
}
|
||||
|
||||
async function processRequest() {
|
||||
const filename = (0, _getFilenameFromUrl.default)(context, req.url);
|
||||
let {
|
||||
headers
|
||||
} = context.options;
|
||||
|
||||
if (typeof headers === "function") {
|
||||
headers = headers(req, res, context);
|
||||
}
|
||||
|
||||
let content;
|
||||
|
||||
if (!filename) {
|
||||
await goNext();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
content = context.outputFileSystem.readFileSync(filename);
|
||||
} catch (_ignoreError) {
|
||||
await goNext();
|
||||
return;
|
||||
}
|
||||
|
||||
const contentTypeHeader = res.get ? res.get("Content-Type") : res.getHeader("Content-Type");
|
||||
|
||||
if (!contentTypeHeader) {
|
||||
// content-type name(like application/javascript; charset=utf-8) or false
|
||||
const contentType = _mimeTypes.default.contentType(_path.default.extname(filename)); // Only set content-type header if media type is known
|
||||
// https://tools.ietf.org/html/rfc7231#section-3.1.1.5
|
||||
|
||||
|
||||
if (contentType) {
|
||||
// Express API
|
||||
if (res.set) {
|
||||
res.set("Content-Type", contentType);
|
||||
} // Node.js API
|
||||
else {
|
||||
res.setHeader("Content-Type", contentType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (headers) {
|
||||
const names = Object.keys(headers);
|
||||
|
||||
for (const name of names) {
|
||||
// Express API
|
||||
if (res.set) {
|
||||
res.set(name, headers[name]);
|
||||
} // Node.js API
|
||||
else {
|
||||
res.setHeader(name, headers[name]);
|
||||
}
|
||||
}
|
||||
} // Buffer
|
||||
|
||||
|
||||
content = (0, _handleRangeHeaders.default)(context, content, req, res); // Express API
|
||||
|
||||
if (res.send) {
|
||||
res.send(content);
|
||||
} // Node.js API
|
||||
else {
|
||||
res.setHeader("Content-Length", content.length);
|
||||
|
||||
if (req.method === "HEAD") {
|
||||
res.end();
|
||||
} else {
|
||||
res.end(content);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"mimeTypes": {
|
||||
"description": "Allows a user to register custom mime types or extension mappings.",
|
||||
"type": "object"
|
||||
},
|
||||
"writeToDisk": {
|
||||
"description": "Allows to write generated files on disk.",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"instanceof": "Function"
|
||||
}
|
||||
]
|
||||
},
|
||||
"methods": {
|
||||
"description": "Allows to pass the list of HTTP request methods accepted by the middleware.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"minlength": "1"
|
||||
}
|
||||
},
|
||||
"headers": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"instanceof": "Function"
|
||||
}
|
||||
]
|
||||
},
|
||||
"publicPath": {
|
||||
"description": "The `publicPath` specifies the public URL address of the output files when referenced in a browser.",
|
||||
"anyOf": [
|
||||
{
|
||||
"enum": ["auto"]
|
||||
},
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"instanceof": "Function"
|
||||
}
|
||||
]
|
||||
},
|
||||
"stats": {
|
||||
"description": "Stats options object or preset name.",
|
||||
"anyOf": [
|
||||
{
|
||||
"enum": [
|
||||
"none",
|
||||
"summary",
|
||||
"errors-only",
|
||||
"errors-warnings",
|
||||
"minimal",
|
||||
"normal",
|
||||
"detailed",
|
||||
"verbose"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"serverSideRender": {
|
||||
"description": "Instructs the module to enable or disable the server-side rendering mode.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"outputFileSystem": {
|
||||
"description": "Set the default file system which will be used by webpack as primary destination of generated files.",
|
||||
"type": "object"
|
||||
},
|
||||
"index": {
|
||||
"description": "Allows to serve an index of the directory.",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"minlength": "1"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = getFilenameFromUrl;
|
||||
|
||||
var _path = _interopRequireDefault(require("path"));
|
||||
|
||||
var _url = require("url");
|
||||
|
||||
var _querystring = _interopRequireDefault(require("querystring"));
|
||||
|
||||
var _mem = _interopRequireDefault(require("mem"));
|
||||
|
||||
var _getPaths = _interopRequireDefault(require("./getPaths"));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
const memoizedParse = (0, _mem.default)(_url.parse);
|
||||
|
||||
function getFilenameFromUrl(context, url) {
|
||||
const {
|
||||
options
|
||||
} = context;
|
||||
const paths = (0, _getPaths.default)(context);
|
||||
let foundFilename;
|
||||
let urlObject;
|
||||
|
||||
try {
|
||||
// The `url` property of the `request` is contains only `pathname`, `search` and `hash`
|
||||
urlObject = memoizedParse(url, false, true);
|
||||
} catch (_ignoreError) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const {
|
||||
publicPath,
|
||||
outputPath
|
||||
} of paths) {
|
||||
let filename;
|
||||
let publicPathObject;
|
||||
|
||||
try {
|
||||
publicPathObject = memoizedParse(publicPath !== "auto" && publicPath ? publicPath : "/", false, true);
|
||||
} catch (_ignoreError) {
|
||||
// eslint-disable-next-line no-continue
|
||||
continue;
|
||||
}
|
||||
|
||||
if (urlObject.pathname && urlObject.pathname.startsWith(publicPathObject.pathname)) {
|
||||
filename = outputPath; // Strip the `pathname` property from the `publicPath` option from the start of requested url
|
||||
// `/complex/foo.js` => `foo.js`
|
||||
|
||||
const pathname = urlObject.pathname.substr(publicPathObject.pathname.length);
|
||||
|
||||
if (pathname) {
|
||||
filename = _path.default.join(outputPath, _querystring.default.unescape(pathname));
|
||||
}
|
||||
|
||||
let fsStats;
|
||||
|
||||
try {
|
||||
fsStats = context.outputFileSystem.statSync(filename);
|
||||
} catch (_ignoreError) {
|
||||
// eslint-disable-next-line no-continue
|
||||
continue;
|
||||
}
|
||||
|
||||
if (fsStats.isFile()) {
|
||||
foundFilename = filename;
|
||||
break;
|
||||
} else if (fsStats.isDirectory() && (typeof options.index === "undefined" || options.index)) {
|
||||
const indexValue = typeof options.index === "undefined" || typeof options.index === "boolean" ? "index.html" : options.index;
|
||||
filename = _path.default.join(filename, indexValue);
|
||||
|
||||
try {
|
||||
fsStats = context.outputFileSystem.statSync(filename);
|
||||
} catch (__ignoreError) {
|
||||
// eslint-disable-next-line no-continue
|
||||
continue;
|
||||
}
|
||||
|
||||
if (fsStats.isFile()) {
|
||||
foundFilename = filename;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // eslint-disable-next-line consistent-return
|
||||
|
||||
|
||||
return foundFilename;
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = getPaths;
|
||||
|
||||
function getPaths(context) {
|
||||
const {
|
||||
stats,
|
||||
options
|
||||
} = context;
|
||||
const childStats = stats.stats ? stats.stats : [stats];
|
||||
const publicPaths = [];
|
||||
|
||||
for (const {
|
||||
compilation
|
||||
} of childStats) {
|
||||
// The `output.path` is always present and always absolute
|
||||
const outputPath = compilation.getPath(compilation.outputOptions.path);
|
||||
const publicPath = options.publicPath ? compilation.getPath(options.publicPath) : compilation.outputOptions.publicPath ? compilation.getPath(compilation.outputOptions.publicPath) : "";
|
||||
publicPaths.push({
|
||||
outputPath,
|
||||
publicPath
|
||||
});
|
||||
}
|
||||
|
||||
return publicPaths;
|
||||
}
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = handleRangeHeaders;
|
||||
|
||||
var _rangeParser = _interopRequireDefault(require("range-parser"));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
function handleRangeHeaders(context, content, req, res) {
|
||||
// assumes express API. For other servers, need to add logic to access
|
||||
// alternative header APIs
|
||||
if (res.set) {
|
||||
res.set("Accept-Ranges", "bytes");
|
||||
} else {
|
||||
res.setHeader("Accept-Ranges", "bytes");
|
||||
}
|
||||
|
||||
let range; // Express API
|
||||
|
||||
if (req.get) {
|
||||
range = req.get("range");
|
||||
} // Node.js API
|
||||
else {
|
||||
({
|
||||
range
|
||||
} = req.headers);
|
||||
}
|
||||
|
||||
if (range) {
|
||||
const ranges = (0, _rangeParser.default)(content.length, range); // unsatisfiable
|
||||
|
||||
if (ranges === -1) {
|
||||
// Express API
|
||||
if (res.set) {
|
||||
res.set("Content-Range", `bytes */${content.length}`);
|
||||
res.status(416);
|
||||
} // Node.js API
|
||||
else {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
res.statusCode = 416;
|
||||
res.setHeader("Content-Range", `bytes */${content.length}`);
|
||||
}
|
||||
} else if (ranges === -2) {
|
||||
// malformed header treated as regular response
|
||||
context.logger.error("A malformed Range header was provided. A regular response will be sent for this request.");
|
||||
} else if (ranges.length !== 1) {
|
||||
// multiple ranges treated as regular response
|
||||
context.logger.error("A Range header with multiple ranges was provided. Multiple ranges are not supported, so a regular response will be sent for this request.");
|
||||
} else {
|
||||
// valid range header
|
||||
const {
|
||||
length
|
||||
} = content; // Express API
|
||||
|
||||
if (res.set) {
|
||||
// Content-Range
|
||||
res.status(206);
|
||||
res.set("Content-Range", `bytes ${ranges[0].start}-${ranges[0].end}/${length}`);
|
||||
} // Node.js API
|
||||
else {
|
||||
// Content-Range
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
res.statusCode = 206;
|
||||
res.setHeader("Content-Range", `bytes ${ranges[0].start}-${ranges[0].end}/${length}`);
|
||||
} // eslint-disable-next-line no-param-reassign
|
||||
|
||||
|
||||
content = content.slice(ranges[0].start, ranges[0].end + 1);
|
||||
}
|
||||
}
|
||||
|
||||
return content;
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = ready;
|
||||
|
||||
// eslint-disable-next-line consistent-return
|
||||
function ready(context, callback, req) {
|
||||
if (context.state) {
|
||||
return callback(context.stats);
|
||||
}
|
||||
|
||||
const name = req && req.url || callback.name;
|
||||
context.logger.info(`wait until bundle finished${name ? `: ${name}` : ""}`);
|
||||
context.callbacks.push(callback);
|
||||
}
|
||||
+142
@@ -0,0 +1,142 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = setupHooks;
|
||||
|
||||
var _webpack = _interopRequireDefault(require("webpack"));
|
||||
|
||||
var _colorette = _interopRequireDefault(require("colorette"));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
function setupHooks(context) {
|
||||
function invalid() {
|
||||
if (context.state) {
|
||||
context.logger.log("Compilation starting...");
|
||||
} // We are now in invalid state
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
|
||||
|
||||
context.state = false; // eslint-disable-next-line no-param-reassign, no-undefined
|
||||
|
||||
context.stats = undefined;
|
||||
}
|
||||
|
||||
const statsForWebpack4 = _webpack.default.Stats && _webpack.default.Stats.presetToOptions;
|
||||
|
||||
function normalizeStatsOptions(statsOptions) {
|
||||
if (statsForWebpack4) {
|
||||
if (typeof statsOptions === "undefined") {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
statsOptions = {};
|
||||
} else if (typeof statsOptions === "boolean" || typeof statsOptions === "string") {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
statsOptions = _webpack.default.Stats.presetToOptions(statsOptions);
|
||||
}
|
||||
|
||||
return statsOptions;
|
||||
}
|
||||
|
||||
if (typeof statsOptions === "undefined") {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
statsOptions = {
|
||||
preset: "normal"
|
||||
};
|
||||
} else if (typeof statsOptions === "boolean") {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
statsOptions = statsOptions ? {
|
||||
preset: "normal"
|
||||
} : {
|
||||
preset: "none"
|
||||
};
|
||||
} else if (typeof statsOptions === "string") {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
statsOptions = {
|
||||
preset: statsOptions
|
||||
};
|
||||
}
|
||||
|
||||
return statsOptions;
|
||||
}
|
||||
|
||||
function done(stats) {
|
||||
// We are now on valid state
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
context.state = true; // eslint-disable-next-line no-param-reassign
|
||||
|
||||
context.stats = stats; // Do the stuff in nextTick, because bundle may be invalidated if a change happened while compiling
|
||||
|
||||
process.nextTick(() => {
|
||||
const {
|
||||
compiler,
|
||||
logger,
|
||||
options,
|
||||
state,
|
||||
callbacks
|
||||
} = context; // Check if still in valid state
|
||||
|
||||
if (!state) {
|
||||
return;
|
||||
}
|
||||
|
||||
logger.log("Compilation finished");
|
||||
const isMultiCompilerMode = Boolean(compiler.compilers);
|
||||
let statsOptions;
|
||||
|
||||
if (typeof options.stats !== "undefined") {
|
||||
statsOptions = isMultiCompilerMode ? {
|
||||
children: compiler.compilers.map(() => options.stats)
|
||||
} : options.stats;
|
||||
} else {
|
||||
statsOptions = isMultiCompilerMode ? {
|
||||
children: compiler.compilers.map(child => child.options.stats)
|
||||
} : compiler.options.stats;
|
||||
}
|
||||
|
||||
if (isMultiCompilerMode) {
|
||||
statsOptions.children = statsOptions.children.map(childStatsOptions => {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
childStatsOptions = normalizeStatsOptions(childStatsOptions);
|
||||
|
||||
if (typeof childStatsOptions.colors === "undefined") {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
childStatsOptions.colors = Boolean(_colorette.default.options.enabled);
|
||||
}
|
||||
|
||||
return childStatsOptions;
|
||||
});
|
||||
} else {
|
||||
statsOptions = normalizeStatsOptions(statsOptions);
|
||||
|
||||
if (typeof statsOptions.colors === "undefined") {
|
||||
statsOptions.colors = Boolean(_colorette.default.options.enabled);
|
||||
}
|
||||
} // TODO webpack@4 doesn't support `{ children: [{ colors: true }, { colors: true }] }` for stats
|
||||
|
||||
|
||||
if (compiler.compilers && statsForWebpack4) {
|
||||
statsOptions.colors = statsOptions.children.some(child => child.colors);
|
||||
}
|
||||
|
||||
const printedStats = stats.toString(statsOptions); // Avoid extra empty line when `stats: 'none'`
|
||||
|
||||
if (printedStats) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(printedStats);
|
||||
} // eslint-disable-next-line no-param-reassign
|
||||
|
||||
|
||||
context.callbacks = []; // Execute callback that are delayed
|
||||
|
||||
callbacks.forEach(callback => {
|
||||
callback(stats);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
context.compiler.hooks.watchRun.tap("webpack-dev-middleware", invalid);
|
||||
context.compiler.hooks.invalid.tap("webpack-dev-middleware", invalid);
|
||||
(context.compiler.webpack ? context.compiler.hooks.afterDone : context.compiler.hooks.done).tap("webpack-dev-middleware", done);
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = setupOutputFileSystem;
|
||||
|
||||
var _path = _interopRequireDefault(require("path"));
|
||||
|
||||
var _memfs = require("memfs");
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
function setupOutputFileSystem(context) {
|
||||
let outputFileSystem;
|
||||
|
||||
if (context.options.outputFileSystem) {
|
||||
// eslint-disable-next-line no-shadow
|
||||
const {
|
||||
outputFileSystem: outputFileSystemFromOptions
|
||||
} = context.options; // Todo remove when we drop webpack@4 support
|
||||
|
||||
if (typeof outputFileSystemFromOptions.join !== "function") {
|
||||
throw new Error("Invalid options: options.outputFileSystem.join() method is expected");
|
||||
} // Todo remove when we drop webpack@4 support
|
||||
|
||||
|
||||
if (typeof outputFileSystemFromOptions.mkdirp !== "function") {
|
||||
throw new Error("Invalid options: options.outputFileSystem.mkdirp() method is expected");
|
||||
}
|
||||
|
||||
outputFileSystem = outputFileSystemFromOptions;
|
||||
} else {
|
||||
outputFileSystem = (0, _memfs.createFsFromVolume)(new _memfs.Volume()); // TODO: remove when we drop webpack@4 support
|
||||
|
||||
outputFileSystem.join = _path.default.join.bind(_path.default);
|
||||
}
|
||||
|
||||
const compilers = context.compiler.compilers || [context.compiler];
|
||||
|
||||
for (const compiler of compilers) {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
compiler.outputFileSystem = outputFileSystem;
|
||||
} // eslint-disable-next-line no-param-reassign
|
||||
|
||||
|
||||
context.outputFileSystem = outputFileSystem;
|
||||
}
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = setupWriteToDisk;
|
||||
|
||||
var _fs = _interopRequireDefault(require("fs"));
|
||||
|
||||
var _path = _interopRequireDefault(require("path"));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
function setupWriteToDisk(context) {
|
||||
const compilers = context.compiler.compilers || [context.compiler];
|
||||
|
||||
for (const compiler of compilers) {
|
||||
compiler.hooks.emit.tap("DevMiddleware", compilation => {
|
||||
if (compiler.hasWebpackDevMiddlewareAssetEmittedCallback) {
|
||||
return;
|
||||
}
|
||||
|
||||
compiler.hooks.assetEmitted.tapAsync("DevMiddleware", (file, info, callback) => {
|
||||
let targetPath = null;
|
||||
let content = null; // webpack@5
|
||||
|
||||
if (info.compilation) {
|
||||
({
|
||||
targetPath,
|
||||
content
|
||||
} = info);
|
||||
} else {
|
||||
let targetFile = file;
|
||||
const queryStringIdx = targetFile.indexOf("?");
|
||||
|
||||
if (queryStringIdx >= 0) {
|
||||
targetFile = targetFile.substr(0, queryStringIdx);
|
||||
}
|
||||
|
||||
let {
|
||||
outputPath
|
||||
} = compiler;
|
||||
outputPath = compilation.getPath(outputPath, {});
|
||||
content = info;
|
||||
targetPath = _path.default.join(outputPath, targetFile);
|
||||
}
|
||||
|
||||
const {
|
||||
writeToDisk: filter
|
||||
} = context.options;
|
||||
const allowWrite = filter && typeof filter === "function" ? filter(targetPath) : true;
|
||||
|
||||
if (!allowWrite) {
|
||||
return callback();
|
||||
}
|
||||
|
||||
const dir = _path.default.dirname(targetPath);
|
||||
|
||||
const name = compiler.options.name ? `Child "${compiler.options.name}": ` : "";
|
||||
return _fs.default.mkdir(dir, {
|
||||
recursive: true
|
||||
}, mkdirError => {
|
||||
if (mkdirError) {
|
||||
context.logger.error(`${name}Unable to write "${dir}" directory to disk:\n${mkdirError}`);
|
||||
return callback(mkdirError);
|
||||
}
|
||||
|
||||
return _fs.default.writeFile(targetPath, content, writeFileError => {
|
||||
if (writeFileError) {
|
||||
context.logger.error(`${name}Unable to write "${targetPath}" asset to disk:\n${writeFileError}`);
|
||||
return callback(writeFileError);
|
||||
}
|
||||
|
||||
context.logger.log(`${name}Asset written to disk: "${targetPath}"`);
|
||||
return callback();
|
||||
});
|
||||
});
|
||||
});
|
||||
compiler.hasWebpackDevMiddlewareAssetEmittedCallback = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user