You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
188 lines
7.8 KiB
188 lines
7.8 KiB
"use strict"; |
|
var __importDefault = (this && this.__importDefault) || function (mod) { |
|
return (mod && mod.__esModule) ? mod : { "default": mod }; |
|
}; |
|
Object.defineProperty(exports, "__esModule", { value: true }); |
|
exports.transformVue = exports.uniAppUVuePlugin = void 0; |
|
const path_1 = __importDefault(require("path")); |
|
const fs_extra_1 = __importDefault(require("fs-extra")); |
|
const shared_1 = require("@vue/shared"); |
|
const uni_cli_shared_1 = require("@dcloudio/uni-cli-shared"); |
|
const descriptorCache_1 = require("./descriptorCache"); |
|
const error_1 = require("./error"); |
|
const utils_1 = require("../utils"); |
|
const script_1 = require("./code/script"); |
|
const template_1 = require("./code/template"); |
|
const style_1 = require("./code/style"); |
|
function resolveAppVue(inputDir) { |
|
const appUVue = path_1.default.resolve(inputDir, 'app.uvue'); |
|
if (fs_extra_1.default.existsSync(appUVue)) { |
|
return (0, uni_cli_shared_1.normalizePath)(appUVue); |
|
} |
|
return (0, uni_cli_shared_1.normalizePath)(path_1.default.resolve(inputDir, 'App.vue')); |
|
} |
|
function uniAppUVuePlugin() { |
|
const options = { |
|
root: process.env.UNI_INPUT_DIR, |
|
sourceMap: false, |
|
// eslint-disable-next-line no-restricted-globals |
|
compiler: require('@vue/compiler-sfc'), |
|
targetLanguage: process.env.UNI_UTS_TARGET_LANGUAGE, |
|
}; |
|
const appVue = resolveAppVue(process.env.UNI_INPUT_DIR); |
|
function isAppVue(id) { |
|
return (0, uni_cli_shared_1.normalizePath)(id) === appVue; |
|
} |
|
function normalizeEasyComSource(source) { |
|
// 把源码source调整为.uvue目录 |
|
return (0, utils_1.parseUTSImportFilename)(source); |
|
} |
|
return { |
|
name: 'uni:app-uvue', |
|
apply: 'build', |
|
async resolveId(id) { |
|
// serve sub-part requests (*?vue) as virtual modules |
|
if ((0, uni_cli_shared_1.parseVueRequest)(id).query.vue) { |
|
return id; |
|
} |
|
}, |
|
load(id) { |
|
const { filename, query } = (0, uni_cli_shared_1.parseVueRequest)(id); |
|
// select corresponding block for sub-part virtual modules |
|
if (query.vue) { |
|
if (query.src) { |
|
return fs_extra_1.default.readFileSync(filename, 'utf-8'); |
|
} |
|
const descriptor = (0, descriptorCache_1.getDescriptor)(filename, options); |
|
let block; |
|
if (query.type === 'style') { |
|
block = descriptor.styles[query.index]; |
|
} |
|
else if (query.index != null) { |
|
block = descriptor.customBlocks[query.index]; |
|
} |
|
if (block) { |
|
return { |
|
code: block.content, |
|
map: block.map, |
|
}; |
|
} |
|
} |
|
}, |
|
async transform(code, id) { |
|
const { filename, query } = (0, uni_cli_shared_1.parseVueRequest)(id); |
|
if (!(0, utils_1.isVue)(filename)) { |
|
return; |
|
} |
|
if (!query.vue) { |
|
// main request |
|
const { errors, uts, js } = await transformVue(code, filename, options, this, isAppVue, normalizeEasyComSource); |
|
if (errors.length) { |
|
errors.forEach((error) => this.error((0, error_1.createRollupError)(filename, error))); |
|
return null; |
|
} |
|
this.emitFile({ |
|
type: 'asset', |
|
fileName: (0, utils_1.parseUTSRelativeFilename)(filename), |
|
source: uts, |
|
}); |
|
return { |
|
code: js, |
|
}; |
|
} |
|
else { |
|
// sub block request |
|
const descriptor = query.src |
|
? (0, descriptorCache_1.getSrcDescriptor)(filename) |
|
: (0, descriptorCache_1.getDescriptor)(filename, options); |
|
if (query.type === 'style') { |
|
return (0, style_1.transformStyle)(code, descriptor, Number(query.index), options, this, filename); |
|
} |
|
} |
|
}, |
|
generateBundle(_, bundle) { |
|
// 遍历vue文件,填充style,尽量减少全局变量 |
|
Object.keys(bundle).forEach((name) => { |
|
const file = bundle[name]; |
|
if (file && |
|
file.type === 'asset' && |
|
(0, utils_1.isVue)(file.fileName) && |
|
(0, shared_1.isString)(file.source)) { |
|
const fileName = (0, uni_cli_shared_1.normalizePath)(file.fileName); |
|
const classNameComment = `/*${(0, utils_1.genClassName)(fileName, options.classNamePrefix)}Styles*/`; |
|
if (file.source.includes(classNameComment)) { |
|
const styleAssetName = fileName + '.style.uts'; |
|
const styleAsset = bundle[styleAssetName]; |
|
if (styleAsset && |
|
styleAsset.type === 'asset' && |
|
(0, shared_1.isString)(styleAsset.source)) { |
|
file.source = file.source.replace(classNameComment, styleAsset.source.replace('export ', '')); |
|
delete bundle[styleAssetName]; |
|
} |
|
} |
|
} |
|
}); |
|
}, |
|
}; |
|
} |
|
exports.uniAppUVuePlugin = uniAppUVuePlugin; |
|
async function transformVue(code, filename, options, pluginContext, isAppVue = () => false, normalizeEasyComSource) { |
|
if (!options.compiler) { |
|
options.compiler = require('@vue/compiler-sfc'); |
|
} |
|
// prev descriptor is only set and used for hmr |
|
const { descriptor, errors } = (0, descriptorCache_1.createDescriptor)(filename, code, options); |
|
if (errors.length) { |
|
return { errors, descriptor }; |
|
} |
|
const isApp = isAppVue(filename); |
|
const fileName = path_1.default.relative(options.root, filename); |
|
const className = (0, utils_1.genClassName)(fileName, options.classNamePrefix); |
|
let templateCode = ''; |
|
let templateImportEasyComponentsCode = ''; |
|
let templateImportUTSComponentsCode = ''; |
|
if (!isApp) { |
|
const templateResult = (0, template_1.genTemplate)(descriptor, { |
|
targetLanguage: options.targetLanguage, |
|
mode: 'function', |
|
filename: className, |
|
prefixIdentifiers: true, |
|
sourceMap: true, |
|
matchEasyCom: (tag, uts) => { |
|
const source = (0, uni_cli_shared_1.matchEasycom)(tag); |
|
if (uts && source) { |
|
return normalizeEasyComSource(source); |
|
} |
|
return source; |
|
}, |
|
parseUTSComponent: uni_cli_shared_1.parseUTSComponent, |
|
}); |
|
templateCode = templateResult.code; |
|
templateImportEasyComponentsCode = |
|
templateResult.importEasyComponents.join('\n'); |
|
templateImportUTSComponentsCode = |
|
templateResult.importUTSComponents.join('\n'); |
|
} |
|
// 生成 script 文件 |
|
let utsCode = (0, script_1.genScript)(descriptor, { filename: className }) + |
|
'\n' + |
|
(0, style_1.genStyle)(descriptor, { filename: fileName, className }) + |
|
'\n'; |
|
utsCode += templateCode; |
|
let jsCode = templateImportEasyComponentsCode + '\n' + templateImportUTSComponentsCode; |
|
const content = descriptor.script?.content; |
|
if (content) { |
|
jsCode += await (0, utils_1.parseImports)(content); |
|
} |
|
if (descriptor.styles.length) { |
|
jsCode += '\n' + (await (0, style_1.genJsStylesCode)(descriptor, pluginContext)); |
|
} |
|
jsCode += `\nexport default "${className}"`; |
|
return { |
|
errors: [], |
|
uts: utsCode, |
|
js: jsCode, |
|
descriptor, |
|
}; |
|
} |
|
exports.transformVue = transformVue;
|
|
|