@farmfe/core
Version:
Farm is a extremely fast web build tool written in Rust. Farm can start a project in milliseconds and perform HMR within 10ms, making it much faster than similar tools like webpack and vite.
202 lines • 7.12 kB
JavaScript
import { browsersWithSupportForFeatures } from 'farm-browserslist-generator';
import path, { isAbsolute } from 'node:path';
import { urlRegex } from '../../utils/http.js';
import { FARM_TARGET_BROWSER_ENVS, mapTargetEnvValue, normalizeBasePath } from '../../utils/share.js';
export function normalizeOutput(config, isProduction, logger) {
if (!config.output) {
config.output = {};
}
if (!config.output.targetEnv) {
config.output.targetEnv = 'browser';
}
if (isProduction) {
if (!config.output.filename) {
config.output.filename = '[resourceName].[contentHash].[ext]';
}
if (!config.output.assetsFilename) {
config.output.assetsFilename = '[resourceName].[contentHash].[ext]';
}
}
if (config.output.clean === undefined) {
config.output.clean = true;
}
// only set default polyfill in production
if (isProduction) {
normalizeTargetEnv(config);
}
// the rust compiler only receives 'node' or 'browser'.
mapTargetEnvValue(config);
// resolve public path
config.output.publicPath = normalizePublicPath(config.output.targetEnv, config.output?.publicPath, logger);
}
const es2015Browsers = browsersWithSupportForFeatures('es6');
const es2017Browsers = browsersWithSupportForFeatures('async-functions');
const LEGACY_BROWSERS = ['ie >= 9'];
const targetsMap = {
node16: {
scriptTargets: ['node 16'],
cssTargets: null
},
'node-legacy': {
scriptTargets: ['node 10'],
cssTargets: null
},
'node-next': null,
'browser-legacy': {
scriptTargets: LEGACY_BROWSERS,
cssTargets: LEGACY_BROWSERS,
scriptGenTarget: 'es5'
},
'browser-es2015': {
scriptTargets: es2015Browsers,
cssTargets: es2015Browsers,
scriptGenTarget: 'es2015'
},
'browser-es2017': {
scriptTargets: es2017Browsers,
cssTargets: es2017Browsers,
scriptGenTarget: 'es2017'
},
'browser-esnext': null,
library: null,
'library-browser': null,
'library-node': null
};
/**
* Set up targets for the given targetEnv.
* @param config
*/
function normalizeTargetEnv(config) {
var _a;
const aliasMap = {
node: 'node16',
browser: 'browser-es2017'
};
const targetEnv = (aliasMap[config.output.targetEnv] ??
config.output.targetEnv);
if (targetsMap[targetEnv]) {
const { scriptTargets, cssTargets, scriptGenTarget } = targetsMap[targetEnv];
// set defaults for targets
if (config.presetEnv !== false) {
// null means disable presetEnv
if (scriptTargets == null) {
config.presetEnv = false;
}
else if (typeof config.presetEnv === 'object') {
(_a = config.presetEnv).options ?? (_a.options = {});
if (!config.presetEnv.options.targets) {
config.presetEnv.options.targets = scriptTargets;
}
}
else {
if (FARM_TARGET_BROWSER_ENVS.includes(targetEnv) &&
config.input &&
Object.values(config.input).some((v) => v?.endsWith('.html'))) {
config.presetEnv = {
options: {
targets: scriptTargets
}
};
}
else {
config.presetEnv = false;
}
}
}
config.script ?? (config.script = { plugins: [] });
config.script.target = config.script.target ?? scriptGenTarget ?? 'esnext';
if (!config)
if (config.css?.prefixer !== null) {
if (cssTargets == null) {
config.css ?? (config.css = {});
config.css.prefixer = null;
}
else if (typeof config.css?.prefixer === 'object') {
if (!config.css.prefixer.targets) {
config.css.prefixer.targets = cssTargets;
}
}
else {
config.css ?? (config.css = {});
config.css.prefixer = {
targets: cssTargets
};
}
}
}
else {
// disable presetEnv and prefixer
config.presetEnv = false;
config.script ?? (config.script = { plugins: [] });
config.script.target = 'esnext';
config.css ?? (config.css = {});
config.css.prefixer = null;
}
}
function tryGetDefaultPublicPath(targetEnv, publicPath, logger) {
if (!targetEnv) {
return publicPath;
}
if (publicPath) {
if (urlRegex.test(publicPath)) {
return publicPath;
}
if (publicPath) {
return publicPath;
}
if (targetEnv === 'node' && isAbsolute(publicPath)) {
// vitejs plugin maybe set absolute path, should transform to relative path
const relativePath = './' + path.posix.normalize(publicPath).slice(1);
logger.warn(`publicPath can't support absolute path in NodeJs, will be transform "${publicPath}" to "${relativePath}".`);
return relativePath;
}
return publicPath;
}
if (['node', 'browser'].includes(targetEnv)) {
return targetEnv === 'node' ? './' : '/';
}
}
/**
* @param outputConfig publicPath option
* @param logger logger instance
* @param isPrefixNeeded whether to add a prefix to the publicPath
* @returns normalized publicPath
*/
export function normalizePublicPath(targetEnv, publicPath, logger, isPrefixNeeded = true) {
let defaultPublicPath = tryGetDefaultPublicPath(targetEnv, publicPath, logger) ?? '/';
let warning = false;
// ../ or ../xxx warning
// normalize relative path
if (defaultPublicPath.startsWith('..')) {
warning = true;
}
// . ./xx => ./ ./xx/
// normalize appended relative path
if (!defaultPublicPath.endsWith('/')) {
if (!urlRegex.test(defaultPublicPath)) {
warning = true;
}
defaultPublicPath = defaultPublicPath + '/';
}
// normalize prepended relative path
if (defaultPublicPath.startsWith('/') &&
!urlRegex.test(defaultPublicPath) &&
!isPrefixNeeded) {
defaultPublicPath = defaultPublicPath.slice(1);
}
warning &&
isPrefixNeeded &&
logger.warn(` (!) Irregular 'publicPath' options: '${publicPath}', it should only be an absolute path like '/publicPath/', './', an url or an empty string.`);
return defaultPublicPath;
}
export function getValidPublicPath(publicPath = '/') {
let validPublicPath = '';
if (publicPath.startsWith('/')) {
validPublicPath = publicPath;
}
else if (publicPath.startsWith('.')) {
validPublicPath = normalizeBasePath(path.join('/', publicPath));
}
return validPublicPath;
}
//# sourceMappingURL=normalize-output.js.map