import { sep, join } from 'path'; import { lstatSync, existsSync, readdirSync, readFileSync, outputFileSync, } from 'fs-extra'; import { merge } from 'webpack-merge'; import { SRC_DIR, getVantConfig, ROOT_WEBPACK_CONFIG_FILE } from './constant'; import { WebpackConfig } from './types'; export const EXT_REGEXP = /\.\w+$/; export const SFC_REGEXP = /\.(vue)$/; export const DEMO_REGEXP = new RegExp('\\' + sep + 'demo$'); export const TEST_REGEXP = new RegExp('\\' + sep + 'test$'); export const ASSET_REGEXP = /\.(png|jpe?g|gif|webp|ico|jfif|svg|woff2?|ttf)$/i; export const STYLE_REGEXP = /\.(css|less|scss)$/; export const SCRIPT_REGEXP = /\.(js|ts|jsx|tsx)$/; export const ENTRY_EXTS = ['js', 'ts', 'tsx', 'jsx', 'vue']; export function removeExt(path: string) { return path.replace('.js', ''); } export function replaceExt(path: string, ext: string) { return path.replace(EXT_REGEXP, ext); } export function hasDefaultExport(code: string) { return code.includes('export default') || code.includes('export { default }'); } export function getComponents() { const EXCLUDES = ['.DS_Store']; const dirs = readdirSync(SRC_DIR); return dirs .filter((dir) => !EXCLUDES.includes(dir)) .filter((dir) => ENTRY_EXTS.some((ext) => { const path = join(SRC_DIR, dir, `index.${ext}`); if (existsSync(path)) { return hasDefaultExport(readFileSync(path, 'utf-8')); } return false; }) ); } export function isDir(dir: string) { return lstatSync(dir).isDirectory(); } export function isDemoDir(dir: string) { return DEMO_REGEXP.test(dir); } export function isTestDir(dir: string) { return TEST_REGEXP.test(dir); } export function isAsset(path: string) { return ASSET_REGEXP.test(path); } export function isSfc(path: string) { return SFC_REGEXP.test(path); } export function isStyle(path: string) { return STYLE_REGEXP.test(path); } export function isScript(path: string) { return SCRIPT_REGEXP.test(path); } const camelizeRE = /-(\w)/g; const pascalizeRE = /(\w)(\w*)/g; export function camelize(str: string): string { return str.replace(camelizeRE, (_, c) => c.toUpperCase()); } export function pascalize(str: string): string { return camelize(str).replace( pascalizeRE, (_, c1, c2) => c1.toUpperCase() + c2 ); } export function decamelize(str: string, sep = '-') { return str .replace(/([a-z\d])([A-Z])/g, '$1' + sep + '$2') .replace(/([A-Z]+)([A-Z][a-z\d]+)/g, '$1' + sep + '$2') .toLowerCase(); } export function normalizePath(path: string): string { return path.replace(/\\/g, '/'); } export function getWebpackConfig(defaultConfig: WebpackConfig): WebpackConfig { if (existsSync(ROOT_WEBPACK_CONFIG_FILE)) { const config = require(ROOT_WEBPACK_CONFIG_FILE); // 如果是函数形式,可能并不仅仅是添加额外的处理流程,而是在原有流程上进行修改 // 比如修改markdown-loader,添加options.enableMetaData if (typeof config === 'function') { return merge(defaultConfig, config(defaultConfig)); } return merge(defaultConfig, config); } return defaultConfig; } export type ModuleEnv = 'esmodule' | 'commonjs'; export type NodeEnv = 'production' | 'development' | 'test'; export type BuildTarget = 'site' | 'package'; export function setModuleEnv(value: ModuleEnv) { process.env.BABEL_MODULE = value; } export function setNodeEnv(value: NodeEnv) { process.env.NODE_ENV = value; } export function setBuildTarget(value: BuildTarget) { process.env.BUILD_TARGET = value; } export function isDev() { return process.env.NODE_ENV === 'development'; } // smarter outputFileSync // skip output if file content unchanged export function smartOutputFile(filePath: string, content: string) { if (existsSync(filePath)) { const previousContent = readFileSync(filePath, 'utf-8'); if (previousContent === content) { return; } } outputFileSync(filePath, content); } export { getVantConfig };