feat(cli): support scoped style (#5910)

This commit is contained in:
neverland 2020-03-25 16:31:30 +08:00 committed by GitHub
parent fd5ec085f1
commit 46372779db
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 40 additions and 21 deletions

View File

@ -74,6 +74,7 @@
"eslint": "^6.8.0",
"fast-glob": "^3.2.2",
"gh-pages": "2.0.1",
"hash-sum": "^2.0.0",
"html-webpack-plugin": "3.2.0",
"husky": "^4.2.3",
"jest": "^25.1.0",

View File

@ -1,5 +1,6 @@
import * as compiler from 'vue-template-compiler';
import * as compileUtils from '@vue/component-compiler-utils';
import hash from 'hash-sum';
import { parse } from 'path';
import { remove, writeFileSync, readFileSync } from 'fs-extra';
import { replaceExt } from '../common';
@ -34,6 +35,10 @@ function injectRender(script: string, render: string) {
);
}
function injectScopeId(script: string, scopeId: string) {
return script.replace(EXPORT, `${EXPORT}\n _scopeId: '${scopeId}',\n\n`);
}
function injectStyle(
script: string,
styles: compileUtils.SFCBlock[],
@ -63,10 +68,6 @@ function compileTemplate(template: string) {
return result.code;
}
type CompileSfcOptions = {
skipStyle?: boolean;
};
export function parseSfc(filePath: string) {
const source = readFileSync(filePath, 'utf-8');
@ -79,15 +80,16 @@ export function parseSfc(filePath: string) {
return descriptor;
}
export async function compileSfc(
filePath: string,
options: CompileSfcOptions = {}
): Promise<any> {
export async function compileSfc(filePath: string): Promise<any> {
const tasks = [remove(filePath)];
const source = readFileSync(filePath, 'utf-8');
const jsFilePath = replaceExt(filePath, '.js');
const descriptor = parseSfc(filePath);
const { template, styles } = descriptor;
const hasScoped = styles.some(s => s.scoped);
const scopeId = hasScoped ? `data-v-${hash(source)}` : '';
// compile js part
if (descriptor.script) {
tasks.push(
@ -100,6 +102,10 @@ export async function compileSfc(
script = injectRender(script, render);
}
if (scopeId) {
script = injectScopeId(script, scopeId);
}
writeFileSync(jsFilePath, script);
compileJs(jsFilePath)
.then(resolve)
@ -109,21 +115,27 @@ export async function compileSfc(
}
// compile style part
if (!options.skipStyle) {
tasks.push(
...styles.map((style, index: number) => {
const cssFilePath = getSfcStylePath(
filePath,
style.lang || 'css',
index
);
tasks.push(
...styles.map((style, index: number) => {
const cssFilePath = getSfcStylePath(filePath, style.lang || 'css', index);
writeFileSync(cssFilePath, trim(style.content));
let styleSource = trim(style.content);
return compileStyle(cssFilePath);
})
);
}
if (style.scoped) {
styleSource = compileUtils.compileStyle({
id: scopeId,
scoped: true,
source: styleSource,
filename: cssFilePath,
preprocessLang: style.lang,
}).code;
}
writeFileSync(cssFilePath, styleSource);
return compileStyle(cssFilePath);
})
);
return Promise.all(tasks);
}

View File

@ -2,6 +2,7 @@
declare module 'less';
declare module 'sass';
declare module 'execa';
declare module 'hash-sum';
declare module 'clean-css';
declare module 'webpackbar';
declare module 'release-it';

View File

@ -5370,6 +5370,11 @@ hash-sum@^1.0.2:
resolved "https://registry.yarnpkg.com/hash-sum/-/hash-sum-1.0.2.tgz#33b40777754c6432573c120cc3808bbd10d47f04"
integrity sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=
hash-sum@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/hash-sum/-/hash-sum-2.0.0.tgz#81d01bb5de8ea4a214ad5d6ead1b523460b0b45a"
integrity sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==
hash.js@^1.0.0, hash.js@^1.0.3:
version "1.1.7"
resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42"