提交 d07d1359 编写于 作者: fxy060608's avatar fxy060608

fix(mp-weixin): Components start with wx (#3451)

上级 4791a571
......@@ -10,6 +10,9 @@ import {
} from '../src/mp/usingComponents'
const inputDir = '/usr/xxx/projects/test/src'
function normalizeComponentName(name: string) {
return name
}
async function resolve(id: string, importer?: string) {
return {
id: importer ? path.resolve(path.dirname(importer), id) : id,
......@@ -44,6 +47,7 @@ export function createApp() {
{
inputDir,
resolve,
normalizeComponentName,
}
)
......@@ -88,6 +92,7 @@ export function createApp() {
{
inputDir,
resolve,
normalizeComponentName,
}
)
......@@ -118,7 +123,11 @@ export function createApp() {
) {
const ast = parseProgram(source, filename, {})
const { imports } = await parseMainDescriptor(filename, ast, resolve)
updateMiniProgramComponentsByMainFilename(filename, inputDir)
updateMiniProgramComponentsByMainFilename(
filename,
inputDir,
normalizeComponentName
)
expect(findUsingComponents('pages/index/index')).toMatchObject(
usingComponents
)
......
......@@ -53,6 +53,10 @@ export interface MiniProgramCompilerOptions {
* 父组件 setData 后,子组件的 properties 是否可以同步获取,目前仅 mp-weixin,mp-qq,mp-alipay 支持
*/
getPropertySync?: boolean
/**
* 格式化组件名称,比如 wx-btn => weixin-btn (微信不允许以 wx 命名自定义组件)
*/
normalizeName?: (name: string) => string
}
directive: string
emitFile?: (emittedFile: EmittedAsset) => string
......
......@@ -117,21 +117,31 @@ export async function parseMainDescriptor(
export function updateMiniProgramComponentsByScriptFilename(
scriptFilename: string,
inputDir: string
inputDir: string,
normalizeComponentName: (name: string) => string
) {
const mainFilename = findMainFilenameByScriptFilename(scriptFilename)
if (mainFilename) {
updateMiniProgramComponentsByMainFilename(mainFilename, inputDir)
updateMiniProgramComponentsByMainFilename(
mainFilename,
inputDir,
normalizeComponentName
)
}
}
export function updateMiniProgramComponentsByTemplateFilename(
templateFilename: string,
inputDir: string
inputDir: string,
normalizeComponentName: (name: string) => string
) {
const mainFilename = findMainFilenameByTemplateFilename(templateFilename)
if (mainFilename) {
updateMiniProgramComponentsByMainFilename(mainFilename, inputDir)
updateMiniProgramComponentsByMainFilename(
mainFilename,
inputDir,
normalizeComponentName
)
}
}
......@@ -153,9 +163,11 @@ export async function updateMiniProgramGlobalComponents(
{
inputDir,
resolve,
normalizeComponentName,
}: {
inputDir: string
resolve: ParseDescriptor['resolve']
normalizeComponentName: (name: string) => string
}
) {
const { bindingComponents, imports } = await parseGlobalDescriptor(
......@@ -165,7 +177,12 @@ export async function updateMiniProgramGlobalComponents(
)
addMiniProgramUsingComponents(
'app',
createUsingComponents(bindingComponents, imports, inputDir)
createUsingComponents(
bindingComponents,
imports,
inputDir,
normalizeComponentName
)
)
return {
imports,
......@@ -175,7 +192,8 @@ export async function updateMiniProgramGlobalComponents(
function createUsingComponents(
bindingComponents: BindingComponents,
imports: ImportDeclaration[],
inputDir: string
inputDir: string,
normalizeComponentName: (name: string) => string
) {
const usingComponents: Record<string, string> = {}
imports.forEach(({ source: { value }, specifiers: [specifier] }) => {
......@@ -183,7 +201,9 @@ function createUsingComponents(
if (!bindingComponents[name]) {
return
}
const componentName = hyphenate(bindingComponents[name].tag)
const componentName = normalizeComponentName(
hyphenate(bindingComponents[name].tag)
)
if (!usingComponents[componentName]) {
usingComponents[componentName] = addLeadingSlash(
removeExt(normalizeMiniProgramFilename(value, inputDir))
......@@ -195,7 +215,8 @@ function createUsingComponents(
export function updateMiniProgramComponentsByMainFilename(
mainFilename: string,
inputDir: string
inputDir: string,
normalizeComponentName: (name: string) => string
) {
const mainDescriptor = mainDescriptors.get(mainFilename)
if (!mainDescriptor) {
......@@ -221,7 +242,12 @@ export function updateMiniProgramComponentsByMainFilename(
addMiniProgramUsingComponents(
removeExt(normalizeMiniProgramFilename(mainFilename, inputDir)),
createUsingComponents(bindingComponents, imports, inputDir)
createUsingComponents(
bindingComponents,
imports,
inputDir,
normalizeComponentName
)
)
}
......
......@@ -335,6 +335,9 @@ function genElement(node: ElementNode, context: TemplateCodegenContext) {
}
if (isUserComponent(node, context)) {
tag = hyphenate(tag)
if (context.component?.normalizeName) {
tag = context.component?.normalizeName(tag)
}
}
const { push } = context
......
......@@ -22,11 +22,15 @@ export default (options: UniMiniProgramPluginOptions) => {
if (!options.app.plugins) {
delete process.env.UNI_MP_PLUGIN
}
const normalizeComponentName = options.template.component?.normalizeName
return [
(options: {
vueOptions?: { script?: Partial<SFCScriptCompileOptions> }
}) => {
return uniMainJsPlugin(options.vueOptions?.script)
return uniMainJsPlugin({
normalizeComponentName,
babelParserPlugins: options.vueOptions?.script?.babelParserPlugins,
})
},
uniManifestJsonPlugin(options),
uniPagesJsonPlugin(options),
......@@ -38,7 +42,10 @@ export default (options: UniMiniProgramPluginOptions) => {
(options: {
vueOptions?: { script?: Partial<SFCScriptCompileOptions> }
}) => {
return uniUsingComponentsPlugin(options.vueOptions?.script)
return uniUsingComponentsPlugin({
normalizeComponentName,
babelParserPlugins: options.vueOptions?.script?.babelParserPlugins,
})
},
...(process.env.UNI_SUBPACKAGE ? [uniSubpackagePlugin(options)] : []),
...(process.env.UNI_MP_PLUGIN ? [uniMiniProgramPluginPlugin(options)] : []),
......
......@@ -10,8 +10,13 @@ import type { SFCScriptCompileOptions } from '@vue/compiler-sfc'
import { dynamicImport } from './usingComponents'
export function uniMainJsPlugin(
options: Partial<SFCScriptCompileOptions> = {}
options: {
normalizeComponentName?: (name: string) => string
babelParserPlugins?: SFCScriptCompileOptions['babelParserPlugins']
} = {}
) {
const normalizeComponentName =
options.normalizeComponentName || ((name: string) => name)
return defineUniMainJsPlugin((opts) => {
return {
name: 'uni:mp-main-js',
......@@ -31,6 +36,7 @@ export function uniMainJsPlugin(
{
inputDir,
resolve: this.resolve,
normalizeComponentName,
}
)
const { code, map } = await transformDynamicImports(source, imports, {
......
......@@ -18,8 +18,13 @@ import {
import { virtualComponentPath, virtualPagePath } from './entry'
export function uniUsingComponentsPlugin(
options: Partial<SFCScriptCompileOptions> = {}
options: {
normalizeComponentName?: (name: string) => string
babelParserPlugins?: SFCScriptCompileOptions['babelParserPlugins']
} = {}
): Plugin {
const normalizeComponentName =
options.normalizeComponentName || ((name: string) => name)
const parseAst = (source: string, id: string) => {
return parseProgram(source, id, {
babelParserPlugins: options.babelParserPlugins,
......@@ -56,7 +61,11 @@ export function uniUsingComponentsPlugin(
isExternal: true,
}
)
updateMiniProgramComponentsByScriptFilename(filename, inputDir)
updateMiniProgramComponentsByScriptFilename(
filename,
inputDir,
normalizeComponentName
)
return transformDynamicImports(
source,
descriptor.imports,
......@@ -73,7 +82,11 @@ export function uniUsingComponentsPlugin(
isExternal: true,
}
)
updateMiniProgramComponentsByTemplateFilename(filename, inputDir)
updateMiniProgramComponentsByTemplateFilename(
filename,
inputDir,
normalizeComponentName
)
return transformDynamicImports(
source,
descriptor.imports,
......@@ -90,7 +103,11 @@ export function uniUsingComponentsPlugin(
const descriptor = await parseMainDescriptor(filename, ast, this.resolve)
updateMiniProgramComponentsByMainFilename(filename, inputDir)
updateMiniProgramComponentsByMainFilename(
filename,
inputDir,
normalizeComponentName
)
return transformDynamicImports(
source,
......
import { assert } from './testUtils'
import { customElements } from '../src/compiler/options'
describe('mp-weixin: transform component', () => {
test(`Components start with wx`, () => {
assert(
`<WxBtn/>`,
`<weixin-btn u-i="2a9ec0b0-0" bind:__l="__l"/>`,
`(_ctx, _cache) => {
return {}
}`
)
})
test(`component with v-show`, () => {
assert(
`<custom v-show="ok"/>`,
......
......@@ -100,7 +100,8 @@ const miniProgram = {
component: {
dir: COMPONENTS_DIR,
vShow: uniCliShared.COMPONENT_CUSTOM_HIDDEN,
getPropertySync: false, // 为了避免 Setting data field "uP" to undefined is invalid 警告
getPropertySync: false,
normalizeName: (name) => name.startsWith('wx-') ? name.replace('wx-', 'weixin-') : name,
},
};
const projectConfigFilename = 'project.config.json';
......
......@@ -57,6 +57,8 @@ export const miniProgram: MiniProgramCompilerOptions = {
dir: COMPONENTS_DIR,
vShow: COMPONENT_CUSTOM_HIDDEN,
getPropertySync: false, // 为了避免 Setting data field "uP" to undefined is invalid 警告
normalizeName: (name) =>
name.startsWith('wx-') ? name.replace('wx-', 'weixin-') : name,
},
}
const projectConfigFilename = 'project.config.json'
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册