Skip to content

Commit

Permalink
feat: 完善生成vue文件样式依赖逻辑
Browse files Browse the repository at this point in the history
  • Loading branch information
xiangmaoshuo committed Jan 6, 2023
1 parent 4f254ae commit d665771
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 32 deletions.
10 changes: 8 additions & 2 deletions packages/vant-cli/src/commands/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,11 @@ async function buildCJSOutputs() {
await compileDir(LIB_DIR, 'cjs');
}

async function buildTypeDeclarations() {
await Promise.all([preCompileDir(ES_DIR), preCompileDir(LIB_DIR)]);
function preCompileDirs() {
return Promise.all([preCompileDir(ES_DIR), preCompileDir(LIB_DIR)]);
}

async function buildTypeDeclarations() {
const tsConfig = join(process.cwd(), 'tsconfig.declaration.json');

if (existsSync(tsConfig)) {
Expand Down Expand Up @@ -150,6 +152,10 @@ const tasks = [
text: 'Build Package Script Entry',
task: buildPackageScriptEntry,
},
{
text: 'Compile sfc and remove unneeded dirs',
task: preCompileDirs,
},
{
text: 'Build Component Style Entry',
task: buildStyleEntry,
Expand Down
115 changes: 86 additions & 29 deletions packages/vant-cli/src/compiler/compile-sfc.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import fse from 'fs-extra';
import path from 'node:path';
import { parse as pathParse, join, relative, dirname, sep } from 'node:path';
import hash from 'hash-sum';
import {
parse,
Expand All @@ -8,9 +8,17 @@ import {
compileScript,
compileStyle,
} from 'vue/compiler-sfc';
import { replaceExt } from '../common/index.js';
import {
replaceExt,
getComponents,
isSfc,
normalizePath,
} from '../common/index.js';
import { CSS_LANG } from '../common/css.js';
import { getVantConfig, SRC_DIR, ROOT } from '../common/constant.js';
import { getDeps, fillExt } from './get-deps.js';

const { remove, readFileSync, outputFile } = fse;
const { remove, readFileSync, outputFile, existsSync } = fse;

const RENDER_FN = '__vue_render__';
const VUEIDS = '__vue_sfc__';
Expand Down Expand Up @@ -42,18 +50,16 @@ function injectScopeId(script: string, scopeId: string) {
return script;
}

function injectStyle(script: string, styles: SFCBlock[], filePath: string) {
if (styles.length) {
const imports = styles
.map((style, index) => {
const { base } = path.parse(getSfcStylePath(filePath, 'css', index));
return `import './${base}';`;
})
.join('\n');

script = `${imports}\n${script}`;

return script;
function injectStyle(
script: string,
styles: SFCBlock[],
filePath: string,
theme: boolean | 'css3'
) {
// 如果有样式,并且不需要主题,则引入css
if (styles.length && !theme) {
const { base } = pathParse(replaceExt(filePath, `.css`));
return `import './${base}';\n${script}`;
}

return script;
Expand All @@ -68,10 +74,23 @@ export function parseSfc(filename: string) {
return descriptor;
}

let cacheComponentPaths: null | string[] = null;

function getComponentPaths() {
if (cacheComponentPaths) return cacheComponentPaths;
cacheComponentPaths = getComponents().map(
(component) => fillExt(join(SRC_DIR, component, 'index')).path
);
return cacheComponentPaths;
}

export async function compileSfc(filePath: string): Promise<any> {
const tasks = [remove(filePath)];
const source = readFileSync(filePath, 'utf-8');
const descriptor = parseSfc(filePath);
const vantConfig = getVantConfig();
// css3 or boolean
const theme = vantConfig.build?.css.theme || 'css3';

const { template, styles } = descriptor;

Expand Down Expand Up @@ -99,7 +118,7 @@ export async function compileSfc(filePath: string): Promise<any> {
script += descriptor.script!.content;
}

script = injectStyle(script, styles, filePath);
script = injectStyle(script, styles, filePath, theme);
script = script.replace(EXPORT, `const ${VUEIDS} =`);

if (template) {
Expand Down Expand Up @@ -134,19 +153,57 @@ export async function compileSfc(filePath: string): Promise<any> {

// compile style part
tasks.push(
...styles.map(async (style, index: number) => {
const cssFilePath = getSfcStylePath(filePath, style.lang || 'css', index);

const styleSource = compileStyle({
id: scopeId,
scoped: style.scoped,
source: trim(style.content),
filename: cssFilePath,
// @ts-ignore
preprocessLang: style.lang,
}).code;

return outputFile(cssFilePath, styleSource);
new Promise((resolve, reject) => {
const componentPaths = getComponentPaths();
const sfcStyleDeps = getDeps(filePath)
.filter((dep) => {
if (!isSfc(dep)) return false;
const relativePath = relative(ROOT, dep);
const absoluteSrcPath = join(
SRC_DIR,
relativePath.slice(relativePath.indexOf(sep) + 1)
);
return !componentPaths.includes(absoluteSrcPath);
})
.map((key) => {
const relativePath = normalizePath(
relative(dirname(filePath), replaceExt(key, `.${CSS_LANG}`))
);
const importUrl = relativePath.startsWith('.')
? relativePath
: `./${relativePath}`;
return `@import "${importUrl}";`;
})
.join('\n');
const styleFiles = styles.map((style, index: number) => {
const cssFilePath = getSfcStylePath(
filePath,
style.lang || 'css',
index
);

let styleSource = trim(style.content);
// 如果为true,则不进行compileStyle,这也意味着不支持scope\v-bind()等
// 这种一般用于使用less等进行主题配置场景
if (theme === true) {
styleSource = compileStyle({
id: scopeId,
scoped: style.scoped,
source: styleSource,
filename: cssFilePath,
// @ts-ignore
preprocessLang: style.lang,
}).code;
}

return styleSource;
});
const indexStylePath = replaceExt(filePath, `.${CSS_LANG}`);
let indexStyleContent = existsSync(indexStylePath)
? readFileSync(indexStylePath, 'utf-8')
: '';
indexStyleContent += `\n${sfcStyleDeps}\n${styleFiles.join('\n')}`;
outputFile(indexStylePath, trim(indexStyleContent)).then(resolve, reject);
})
);

Expand Down
4 changes: 3 additions & 1 deletion packages/vant-cli/src/compiler/gen-style-deps-map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ function getStylePath(component: string) {
}

export function checkStyleExists(component: string) {
return existsSync(getStylePath(component));
const sfcPath = join(SRC_DIR, component, `index.vue`);
// 如果该组件是用vue编写的,则默认其有style文件
return existsSync(sfcPath) || existsSync(getStylePath(component));
}

// analyze component dependencies
Expand Down

0 comments on commit d665771

Please sign in to comment.