react-scripts
Version:
Configuration and scripts for Create React App.
663 lines (522 loc) • 17.9 kB
JavaScript
/**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
*/
/*!
* fast-path - index.js
* MIT License
*
* Copyright Joyent, Inc. and other Node contributors.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do so, subject to the
* following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
* NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* original author: dead_horse <dead_horse@qq.com>
* ported by: yaycmyk <evan@yaycmyk.com>
*
* VERSION 1.2.0
*/
;
const fs = require('fs');
const path = require('path');
const util = require('util');
// fastpath is only useful on older versions of nodejs.
if (
process.versions.node &&
parseInt(process.versions.node.split('.')[0], 10) >= 5)
{
module.exports = Object.assign(
{},
{ replace: () => {} },
path);
} else {
const IS_WINDOWS = process.platform === 'win32';
function isString(arg) {
return typeof arg === 'string';
}
const splitDeviceRe =
/^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/;
function getDevice(filename) {
const result = splitDeviceRe.exec(filename);
return (result[1] || '') + (result[2] || '');
}
// resolves . and .. elements in a path array with directory names there
// must be no slashes, or device names (c:\) in the array
// (so also no leading and trailing slashes - it does not distinguish
// relative and absolute paths)
function normalizeArray(
parts,
allowAboveRoot)
{
const nonEmptyParts = [];
let nonBack = true;
for (let i = 0; i < parts.length; i++) {
const p = parts[i];
if (p && p !== '.') {
nonEmptyParts.push(p);
}
if (p === '..') {
nonBack = false;
}
}
parts = nonEmptyParts;
// if the path does not contain ..
if (nonBack) {
return parts;
}
// if the path tries to go ab ove the root, `up` ends up > 0
let up = 0;
const res = [];
for (let i = parts.length - 1; i >= 0; i--) {
if (parts[i] === '..') {
up++;
} else if (up) {
up--;
} else {
res.push(parts[i]);
}
}
// if the path is allowed to go above the root, restore leading ..s
if (allowAboveRoot) {
for (; up--; up) {
res.push('..');
}
}
return res.reverse();
}
function trim(arr) {
let start = 0;
for (; start < arr.length; start++) {
if (arr[start] !== '') {break;}
}
let end = arr.length - 1;
for (; end >= 0; end--) {
if (arr[end] !== '') {break;}
}
return start <= end ? arr.slice(start, end + 1) : [];
}
function normalizeUNCRoot(device) {
return '\\\\' + device.replace(/^[\\\/]+/, '').replace(/[\\\/]+/g, '\\');
}
const sep = IS_WINDOWS ? '\\' : '/';
exports.sep = sep;
exports.delimiter = IS_WINDOWS ? ';' : ':';
if (IS_WINDOWS) {
// path.resolve([from ...], to)
// windows version
exports.resolve = function resolveWIN32() {
let resolvedDevice = '';
let resolvedTail = '';
let resolvedAbsolute = false;
for (let i = arguments.length - 1; i >= -1; i--) {
let path;
if (i >= 0) {
path = arguments[i];
} else if (!resolvedDevice) {
path = process.cwd();
} else {
// Windows has the concept of drive-specific current working
// directories. If we've resolved a drive letter but not yet an
// absolute path, get cwd for that drive. We're sure the device is not
// an unc path at this points, because unc paths are always absolute.
path = process.env['=' + resolvedDevice];
// Verify that a drive-local cwd was found and that it actually points
// to our drive. If not, default to the drive's root.
if (!path || path.substr(0, 3).toLowerCase() !==
resolvedDevice.toLowerCase() + '\\') {
path = resolvedDevice + '\\';
}
}
// Skip empty and invalid entries
if (!isString(path)) {
throw new TypeError('Arguments to path.resolve must be strings');
} else if (!path) {
continue;
}
const result = splitDeviceRe.exec(path);
const device = result[1] || '';
const isUnc = device && device.charAt(1) !== ':';
const isAbsolute = exports.isAbsolute(path);
const tail = result[3];
if (device &&
resolvedDevice &&
device.toLowerCase() !== resolvedDevice.toLowerCase()) {
// This path points to another device so it is not applicable
continue;
}
if (!resolvedDevice) {
resolvedDevice = device;
}
if (!resolvedAbsolute) {
resolvedTail = tail + '\\' + resolvedTail;
resolvedAbsolute = isAbsolute;
}
// Convert slashes to backslashes when `resolvedDevice` points to an UNC
// root. Also squash multiple slashes into a single one where
// appropriate.
if (isUnc) {
resolvedDevice = normalizeUNCRoot(resolvedDevice);
}
if (resolvedDevice && resolvedAbsolute) {
break;
}
}
// At this point the path should be resolved to a full absolute path,
// but handle relative paths to be safe (might happen when process.cwd()
// fails)
// Normalize the tail path
resolvedTail = normalizeArray(
resolvedTail.split(/[\\\/]+/),
!resolvedAbsolute).
join('\\');
return resolvedDevice + (resolvedAbsolute ? '\\' : '') + resolvedTail ||
'.';
};
// windows version
exports.normalize = function normalizeWIN32(path) {
const result = splitDeviceRe.exec(path);
let device = result[1] || '';
const isUnc = device && device.charAt(1) !== ':';
const isAbsolute = exports.isAbsolute(path);
let tail = result[3];
const trailingSlash = /[\\\/]$/.test(tail);
// Normalize the tail path
tail = normalizeArray(tail.split(/[\\\/]+/), !isAbsolute).join('\\');
if (!tail && !isAbsolute) {
tail = '.';
}
if (tail && trailingSlash) {
tail += '\\';
}
// Convert slashes to backslashes when `device` points to an UNC root.
// Also squash multiple slashes into a single one where appropriate.
if (isUnc) {
device = normalizeUNCRoot(device);
}
return device + (isAbsolute ? '\\' : '') + tail;
};
// windows version
exports.isAbsolute = function isAbsoluteWIN32(path) {
const result = splitDeviceRe.exec(path);
const device = result[1] || '';
const isUnc = !!device && device.charAt(1) !== ':';
// UNC paths are always absolute
return !!result[2] || isUnc;
};
// windows version
exports.join = function joinWIN32() {
function f(p) {
if (!isString(p)) {
throw new TypeError('Arguments to path.join must be strings');
}
return p;
}
const paths = Array.prototype.filter.call(arguments, f);
let joined = paths.join('\\');
// Make sure that the joined path doesn't start with two slashes, because
// normalize() will mistake it for an UNC path then.
//
// This step is skipped when it is very clear that the user actually
// intended to point at an UNC path. This is assumed when the first
// non-empty string arguments starts with exactly two slashes followed by
// at least one more non-slash character.
//
// Note that for normalize() to treat a path as an UNC path it needs to
// have at least 2 components, so we don't filter for that here.
// This means that the user can use join to construct UNC paths from
// a server name and a share name; for example:
// path.join('//server', 'share') -> '\\\\server\\share\')
if (!/^[\\\/]{2}[^\\\/]/.test(paths[0])) {
joined = joined.replace(/^[\\\/]{2,}/, '\\');
}
return exports.normalize(joined);
};
// path.relative(from, to)
// it will solve the relative path from 'from' to 'to', for instance:
// from = 'C:\\orandea\\test\\aaa'
// to = 'C:\\orandea\\impl\\bbb'
// The output of the function should be: '..\\..\\impl\\bbb'
// windows version
exports.relative = function relativeWIN32(
from,
to)
{
from = exports.resolve(from);
to = exports.resolve(to);
// windows is not case sensitive
const lowerFrom = from.toLowerCase();
const lowerTo = to.toLowerCase();
const toParts = trim(to.split('\\'));
const lowerFromParts = trim(lowerFrom.split('\\'));
const lowerToParts = trim(lowerTo.split('\\'));
const length = Math.min(lowerFromParts.length, lowerToParts.length);
let samePartsLength = length;
for (let i = 0; i < length; i++) {
if (lowerFromParts[i] !== lowerToParts[i]) {
samePartsLength = i;
break;
}
}
if (samePartsLength == 0) {
return to;
}
let outputParts = [];
for (let i = samePartsLength; i < lowerFromParts.length; i++) {
outputParts.push('..');
}
outputParts = outputParts.concat(toParts.slice(samePartsLength));
return outputParts.join('\\');
};
} else /* posix */{
// path.resolve([from ...], to)
// posix version
exports.resolve = function resolvePOSIX() {
let resolvedPath = '';
let resolvedAbsolute = false;
for (let i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
const path = i >= 0 ? arguments[i] : process.cwd();
// Skip empty and invalid entries
if (!isString(path)) {
throw new TypeError('Arguments to path.resolve must be strings');
} else if (!path) {
continue;
}
resolvedPath = path + '/' + resolvedPath;
resolvedAbsolute = path.charAt(0) === '/';
}
// At this point the path should be resolved to a full absolute path, but
// handle relative paths to be safe (might happen when process.cwd()
// fails)
// Normalize the path
resolvedPath = normalizeArray(
resolvedPath.split('/'),
!resolvedAbsolute).
join('/');
return (resolvedAbsolute ? '/' : '') + resolvedPath || '.';
};
// path.normalize(path)
// posix version
exports.normalize = function normalizePOSIX(path) {
const isAbsolute = exports.isAbsolute(path);
const trailingSlash = path[path.length - 1] === '/';
// normalize the path
path = normalizeArray(path.split('/'), !isAbsolute).join('/');
if (!path && !isAbsolute) {
path = '.';
}
if (path && trailingSlash) {
path += '/';
}
return (isAbsolute ? '/' : '') + path;
};
// posix version
exports.isAbsolute = function isAbsolutePOSIX(path) {
return path.charAt(0) === '/';
};
// posix version
exports.join = function joinPOSIX() {
let path = '';
for (let i = 0; i < arguments.length; i++) {
const segment = arguments[i];
if (!isString(segment)) {
throw new TypeError('Arguments to path.join must be strings');
}
if (segment) {
path += `${ path ? '/' : '' }${ segment }`;
}
}
return exports.normalize(path);
};
// path.relative(from, to)
// posix version
exports.relative = function relativePOSIX(
from,
to)
{
from = exports.resolve(from).substr(1);
to = exports.resolve(to).substr(1);
const fromParts = trim(from.split('/'));
const toParts = trim(to.split('/'));
const length = Math.min(fromParts.length, toParts.length);
let samePartsLength = length;
for (let i = 0; i < length; i++) {
if (fromParts[i] !== toParts[i]) {
samePartsLength = i;
break;
}
}
let outputParts = [];
for (let i = samePartsLength; i < fromParts.length; i++) {
outputParts.push('..');
}
outputParts = outputParts.concat(toParts.slice(samePartsLength));
return outputParts.join('/');
};
}
exports.exists = util.deprecate(
(path, callback) => fs.exists(path, callback),
'path.exists is now called `fs.exists`.');
exports.existsSync = util.deprecate(
path => fs.existsSync(path),
'path.existsSync is now called `fs.existsSync`.');
if (IS_WINDOWS) {
exports._makeLong = function _makeLongWIN32(path) {
// Note: this will *probably* throw somewhere.
if (!isString(path)) {return path;}
if (!path) {return '';}
const resolvedPath = exports.resolve(path);
if (/^[a-zA-Z]\:\\/.test(resolvedPath)) {
// path is local filesystem path, which needs to be converted
// to long UNC path.
return '\\\\?\\' + resolvedPath;
} else if (/^\\\\[^?.]/.test(resolvedPath)) {
// path is network UNC path, which needs to be converted
// to long UNC path.
return '\\\\?\\UNC\\' + resolvedPath.substring(2);
}
return path;
};
} else {
exports._makeLong = function _makeLongPOSIX(path) {
return path;
};
}
exports.extname = function _extname(filename) {
if (!filename) {return '';}
// /a.js///
let end = filename.length;
let c = filename[end - 1];
while (c === sep || c === '/') {
end--;
c = filename[end - 1];
}
let lastDot = -1;
let lastSep = -1;
for (let i = end; i--;) {
const ch = filename[i];
if (lastDot === -1 && ch === '.') {
lastDot = i;
} else if (lastSep === -1 && ch === '/') {
lastSep = i;
} else if (IS_WINDOWS && lastSep === -1 && ch === '\\') {
lastSep = i;
}
// /xxx
if (lastSep !== -1 && lastDot === -1) {return '';}
// /*.js
if (lastDot !== -1 && i === lastDot - 2) {break;}
// /.js
if (lastSep !== -1 && lastDot !== -1) {break;}
}
// ./js and /.js
if (lastDot < lastSep + 2) {return '';}
const extname = filename.slice(lastDot, end);
if (extname === '.' && filename[lastDot - 1] === '.') {
// ..
if (lastDot === 1) {return '';}
const pre = filename[lastDot - 2];
// [//\/]..
if (pre === '/' || pre === sep) {return '';}
}
return extname;
};
exports.basename = function _basename(
filename,
ext)
{
if (!filename) {return '';}
// /a.js///
let end = filename.length;
let c = filename[end - 1];
while (c === sep || c === '/') {
end--;
c = filename[end - 1];
}
let lastSep = -1;
for (let i = end; i--;) {
const ch = filename[i];
if (lastSep === -1 && ch === '/') {
lastSep = i;
break;
}
if (IS_WINDOWS && lastSep === -1 && ch === '\\') {
lastSep = i;
break;
}
}
const basename = filename.slice(lastSep + 1, end);
if (ext) {
const match = basename.lastIndexOf(ext);
if (match === -1 || match !== basename.length - ext.length) {
return basename;
}
return basename.slice(0, basename.length - ext.length);
}
return basename;
};
exports.dirname = function _dirname(filename) {
if (!filename) {return '.';}
let start = 0;
let device = '';
if (IS_WINDOWS) {
// need to get device in windows
device = getDevice(filename);
if (device) {start = device.length;}
}
// /a.js///
let end = filename.length;
let c = filename[end - 1];
while (end >= start && c === sep || c === '/') {
end--;
c = filename[end - 1];
}
let lastSep = -1;
for (let i = end; i-- > start;) {
const ch = filename[i];
if (lastSep === -1 && ch === '/') {
lastSep = i;
break;
}
if (IS_WINDOWS && lastSep === -1 && ch === '\\') {
lastSep = i;
break;
}
}
if (lastSep <= start) {
if (device) {
return device;
}
if (filename[0] === '/' || filename[0] === sep) {
return filename[0];
}
return '.';
}
return device + filename.slice(start, lastSep);
};
exports.replace = function () {
Object.keys(exports).
filter(name => name !== 'replace').
forEach(name => path[name] = exports[name]);
};
}