mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-05 05:42:44 +08:00
feat(@vant/cli): auto complete mjs path (#10649)
* feat(@vant/cli): auto complete mjs path * release: 3.5.0-beta.1
This commit is contained in:
parent
0b6de0aa77
commit
79dfc4b8cb
@ -43,7 +43,15 @@ export const STYLE_DEPS_JSON_FILE = join(DIST_DIR, 'style-deps.json');
|
||||
export const POSTCSS_CONFIG_FILE = join(CJS_DIR, 'postcss.config.cjs');
|
||||
export const JEST_CONFIG_FILE = join(CJS_DIR, 'jest.config.cjs');
|
||||
|
||||
export const SCRIPT_EXTS = ['.js', '.jsx', '.vue', '.ts', '.tsx'];
|
||||
export const SCRIPT_EXTS = [
|
||||
'.js',
|
||||
'.jsx',
|
||||
'.vue',
|
||||
'.ts',
|
||||
'.tsx',
|
||||
'.mjs',
|
||||
'.cjs',
|
||||
];
|
||||
export const STYLE_EXTS = ['.css', '.less', '.scss'];
|
||||
|
||||
export function getPackageJson() {
|
||||
|
@ -16,12 +16,15 @@ export async function compileScript(
|
||||
return;
|
||||
}
|
||||
|
||||
const extensionMap = getVantConfig().build?.extensions;
|
||||
const extension = extensionMap?.[format] || '.js';
|
||||
|
||||
let code = readFileSync(filePath, 'utf-8');
|
||||
|
||||
if (!filePath.includes(`${sep}style${sep}`)) {
|
||||
code = replaceCSSImportExt(code);
|
||||
}
|
||||
code = replaceScriptImportExt(code, '.vue', '');
|
||||
code = replaceScriptImportExt(code, filePath, extension);
|
||||
|
||||
if (isJsx(filePath)) {
|
||||
const babelResult = await babel.transformAsync(code, {
|
||||
@ -50,9 +53,8 @@ export async function compileScript(
|
||||
|
||||
({ code } = esbuildResult);
|
||||
|
||||
const extensionMap = getVantConfig().build?.extensions;
|
||||
const extension = extensionMap?.[format] || '.js';
|
||||
const jsFilePath = replaceExt(filePath, extension);
|
||||
|
||||
removeSync(filePath);
|
||||
outputFileSync(jsFilePath, code);
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ export function checkStyleExists(component: string) {
|
||||
// analyze component dependencies
|
||||
function analyzeComponentDeps(components: string[], component: string) {
|
||||
const checkList: string[] = [];
|
||||
const componentEntry = fillExt(join(SRC_DIR, component, 'index'));
|
||||
const componentEntry = fillExt(join(SRC_DIR, component, 'index')).path;
|
||||
const record = new Set();
|
||||
|
||||
function search(filePath: string) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { join } from 'path';
|
||||
import { SCRIPT_EXTS } from '../common/constant.js';
|
||||
import { SCRIPT_EXTS, STYLE_EXTS } from '../common/constant.js';
|
||||
import { readFileSync, existsSync } from 'fs';
|
||||
|
||||
let depsMap: Record<string, string[]> = {};
|
||||
@ -8,12 +8,19 @@ let existsCache: Record<string, boolean> = {};
|
||||
// https://regexr.com/47jlq
|
||||
const IMPORT_RE =
|
||||
/import\s+?(?:(?:(?:[\w*\s{},]*)\s+from(\s+)?)|)(?:(?:".*?")|(?:'.*?'))[\s]*?(?:;|$|)/g;
|
||||
const EXPORT_FROM_RE =
|
||||
/@?export\s+?(?:(?:(?:[\w*\s{},]*)\s+from(\s+)?)|)(?:(?:".*?")|(?:'.*?'))[\s]*?(?:;|$|)/g;
|
||||
|
||||
function matchImports(code: string): string[] {
|
||||
const imports = code.match(IMPORT_RE) || [];
|
||||
return imports.filter((line) => !line.includes('import type'));
|
||||
}
|
||||
|
||||
function matchExportFroms(code: string): string[] {
|
||||
const exportFroms = code.match(EXPORT_FROM_RE) || [];
|
||||
return exportFroms.filter((line) => !line.includes('export type'));
|
||||
}
|
||||
|
||||
function exists(filePath: string) {
|
||||
if (!(filePath in existsCache)) {
|
||||
existsCache[filePath] = existsSync(filePath);
|
||||
@ -26,23 +33,36 @@ export function fillExt(filePath: string) {
|
||||
for (let i = 0; i < SCRIPT_EXTS.length; i++) {
|
||||
const completePath = `${filePath}${SCRIPT_EXTS[i]}`;
|
||||
if (exists(completePath)) {
|
||||
return completePath;
|
||||
return {
|
||||
path: completePath,
|
||||
isIndex: false,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < SCRIPT_EXTS.length; i++) {
|
||||
const completePath = `${filePath}/index${SCRIPT_EXTS[i]}`;
|
||||
if (exists(completePath)) {
|
||||
return completePath;
|
||||
return {
|
||||
path: completePath,
|
||||
isIndex: true,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
return {
|
||||
path: '',
|
||||
isIndex: false,
|
||||
};
|
||||
}
|
||||
|
||||
function getImportRelativePath(code: string) {
|
||||
const divider = code.includes('"') ? '"' : "'";
|
||||
return code.split(divider)[1];
|
||||
}
|
||||
|
||||
function getPathByImport(code: string, filePath: string) {
|
||||
const divider = code.includes('"') ? '"' : "'";
|
||||
const relativePath = code.split(divider)[1];
|
||||
const relativePath = getImportRelativePath(code);
|
||||
|
||||
if (relativePath.includes('.')) {
|
||||
return fillExt(join(filePath, '..', relativePath));
|
||||
@ -64,7 +84,7 @@ export function getDeps(filePath: string) {
|
||||
const code = readFileSync(filePath, 'utf-8');
|
||||
const imports = matchImports(code);
|
||||
const paths = imports
|
||||
.map((item) => getPathByImport(item, filePath))
|
||||
.map((item) => getPathByImport(item, filePath)?.path)
|
||||
.filter((item) => !!item) as string[];
|
||||
|
||||
depsMap[filePath] = paths;
|
||||
@ -74,14 +94,58 @@ export function getDeps(filePath: string) {
|
||||
return paths;
|
||||
}
|
||||
|
||||
// "import App from 'App.vue';" => "import App from 'App.xxx';"
|
||||
export function replaceScriptImportExt(code: string, from: string, to: string) {
|
||||
const importLines = matchImports(code);
|
||||
/**
|
||||
* 1. Replace .vue extension
|
||||
* @example "import App from 'App.vue';" => "import App from 'App.xxx';"
|
||||
*
|
||||
* 2. if using .mjs or .cjs, complete the import path
|
||||
* @example import './foo' -> import './foo.mjs'
|
||||
* @example import './foo' -> import './foo/index.mjs'
|
||||
*/
|
||||
export function replaceScriptImportExt(
|
||||
code: string,
|
||||
filePath: string,
|
||||
ext: string
|
||||
) {
|
||||
const imports = [...matchImports(code), ...matchExportFroms(code)];
|
||||
|
||||
importLines.forEach((importLine) => {
|
||||
const result = importLine.replace(from, to);
|
||||
code = code.replace(importLine, result);
|
||||
const updateImport = (index: number, newImport: string) => {
|
||||
code = code.replace(imports[index], newImport);
|
||||
imports[index] = newImport;
|
||||
};
|
||||
|
||||
imports.forEach((line, index) => {
|
||||
if (line.includes('.vue')) {
|
||||
updateImport(index, line.replace('.vue', ext));
|
||||
}
|
||||
});
|
||||
|
||||
if (ext === '.mjs' || ext === '.cjs') {
|
||||
imports.forEach((line, index) => {
|
||||
const isStyleImport = STYLE_EXTS.some((ext) => line.includes(ext));
|
||||
if (isStyleImport) {
|
||||
return;
|
||||
}
|
||||
|
||||
const pathInfo = getPathByImport(line, filePath);
|
||||
|
||||
if (pathInfo) {
|
||||
const relativePath = getImportRelativePath(line);
|
||||
|
||||
if (pathInfo.isIndex) {
|
||||
const newLine = line.replace(
|
||||
relativePath,
|
||||
`${relativePath}/index${ext}`
|
||||
);
|
||||
|
||||
updateImport(index, newLine);
|
||||
} else {
|
||||
const newLine = line.replace(relativePath, relativePath + ext);
|
||||
updateImport(index, newLine);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "vant",
|
||||
"version": "3.5.0-beta.0",
|
||||
"version": "3.5.0-beta.1",
|
||||
"description": "Mobile UI Components built on Vue",
|
||||
"main": "lib/vant.cjs.js",
|
||||
"module": "es/index.mjs",
|
||||
|
Loading…
x
Reference in New Issue
Block a user