UNPKG

@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.

207 lines 7.3 kB
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'; import { CUSTOM_KEYS } from '../constants.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; } config.custom = { ...(config.custom || {}), [CUSTOM_KEYS.output_ascii_only]: `${!!config.output.asciiOnly}` }; // 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