zoy-l 384ee56f13
feat(cli): add convention static directory (#8929)
* fix: #8890 sfc compile error

* chore(vant-cli): add convention static directory

* chore(vant-cli): another way to deal with static resources
2021-06-25 17:02:55 +08:00

156 lines
3.9 KiB
TypeScript

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 };