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

wip(mp): mp-toutiao

上级 ecd00250
因为 它太大了无法显示 source diff 。你可以改为 查看blob
import fs from 'fs'
import path from 'path'
import { hasOwn } from '@vue/shared'
import { extend, hasOwn } from '@vue/shared'
import { parseJson } from '../json'
import { validatePages } from '../pages'
import { AppJson, NetworkTimeout, PageWindowOptions } from './types'
......@@ -57,11 +57,12 @@ function parsePagesJson(
) {
nvuePages.push(pagePath)
}
pageJsons[pagePath] = parseWindowOptions(
style,
platform,
windowOptionsMap
) as PageWindowOptions
pageJsons[pagePath] = extend(
{
component: true,
},
parseWindowOptions(style, platform, windowOptionsMap) as PageWindowOptions
)
}
// pages
validatePages(pagesJson, jsonStr)
......
......@@ -32,15 +32,11 @@ export function parseWindowOptions(
windowOptionsMap?: Record<string, string>
): PageWindowOptions | AppWindowOptions {
if (!style) {
return {
component: true,
}
return {}
}
const platformStyle = style[platform] || {}
removePlatformStyle(trimJson(style) as any)
const res: PageWindowOptions | AppWindowOptions = {
component: true,
}
const res: PageWindowOptions | AppWindowOptions = {}
if (windowOptionsMap) {
return extend(convert(res, style, windowOptionsMap), platformStyle)
}
......
......@@ -4,7 +4,16 @@ import { LINEFEED } from '@dcloudio/uni-shared'
import { normalizeMiniProgramFilename } from '../utils'
export interface MiniProgramCompilerOptions {
class: {
/**
* 是否支持绑定 array 类型
*/
array: boolean
}
slot: {
/**
* 是否支持后备内容
*/
fallback: boolean
}
filter?: {
......
......@@ -21,7 +21,10 @@ export const resolveMainPathOnce = once((inputDir: string) => {
})
export function resolveBuiltIn(path: string) {
return require.resolve(path, { paths: [process.env.UNI_CLI_CONTEXT] })
if (process.env.UNI_CLI_CONTEXT) {
return require.resolve(path, { paths: [process.env.UNI_CLI_CONTEXT] })
}
return require.resolve(path)
}
export function normalizeIdentifier(str: string) {
......
......@@ -7341,7 +7341,7 @@ function image(Quill) {
"class",
"data-local"
];
Image2.sanitize = (url) => url;
Image2.sanitize = (url) => url ? getRealPath(url) : url;
Image2.formats = function formats(domNode) {
return ATTRIBUTES.reduce(function(formats2, attribute) {
if (domNode.hasAttribute(attribute)) {
......@@ -7363,6 +7363,15 @@ function image(Quill) {
}
};
}
function link(Quill) {
const Link = Quill.import("formats/link");
Link.sanitize = (url) => {
const anchor = document.createElement("a");
anchor.href = url;
const protocol = anchor.href.slice(0, anchor.href.indexOf(":"));
return Link.PROTOCOL_WHITELIST.concat("file").indexOf(protocol) > -1 ? url : Link.SANITIZED_URL;
};
}
function register(Quill) {
const formats = {
divider,
......@@ -7374,7 +7383,8 @@ function register(Quill) {
box,
font,
text,
image
image,
link
};
const options = {};
Object.values(formats).forEach((value) => extend(options, value(Quill)));
......@@ -7395,7 +7405,7 @@ function useQuill(props2, rootRef, trigger) {
});
watch(() => props2.placeholder, (value) => {
if (quillReady) {
quill.root.setAttribute("data-placeholder", value);
setPlaceHolder(value);
}
});
function html2delta(html) {
......@@ -7466,6 +7476,11 @@ function useQuill(props2, rootRef, trigger) {
delta
};
}
function setPlaceHolder(placeholder) {
const placeHolderAttrName = "data-placeholder";
const QuillRoot = quill.root;
QuillRoot.getAttribute(placeHolderAttrName) !== placeholder && QuillRoot.setAttribute(placeHolderAttrName, placeholder);
}
let oldStatus = {};
function updateStatus(range) {
const status = range ? quill.getFormat(range) : {};
......@@ -7497,10 +7512,16 @@ function useQuill(props2, rootRef, trigger) {
const events = ["focus", "blur", "input"];
events.forEach((name) => {
$el.addEventListener(name, ($event) => {
const contents = getContents();
if (name === "input") {
if (getBaseSystemInfo().platform === "ios") {
const regExpContent = (contents.html.match(/<span [\s\S]*>([\s\S]*)<\/span>/) || [])[1];
const placeholder = regExpContent && regExpContent.replace(/\s/g, "") ? "" : props2.placeholder;
setPlaceHolder(placeholder);
}
$event.stopPropagation();
} else {
trigger(name, $event, getContents());
trigger(name, $event, contents);
}
});
});
......
......@@ -384,25 +384,18 @@ function findVmByVueId(instance, vuePid) {
}
}
// function parsePropType(key: string, type: unknown, defaultValue: unknown) {
// // [String]=>String
// if (isArray(type) && type.length === 1) {
// return type[0]
// }
// if ("mp-alipay" === 'mp-baidu') {
// if (
// // [String,Boolean]=>Boolean
// defaultValue === false &&
// isArray(type) &&
// type.length === 2 &&
// type.indexOf(String) !== -1 &&
// type.indexOf(Boolean) !== -1
// ) {
// return Boolean
// }
// }
// return type
// }
const PROP_TYPES = [String, Number, Boolean, Object, Array, null];
function parsePropType(type, defaultValue) {
// [String]=>String
if (isArray(type) && type.length === 1) {
return type[0];
}
return type;
}
function normalizePropType(type, defaultValue) {
const res = parsePropType(type);
return PROP_TYPES.indexOf(res) !== -1 ? res : null;
}
function initDefaultProps(isBehavior = false) {
const properties = {};
if (!isBehavior) {
......@@ -433,7 +426,7 @@ function createProperty(key, prop) {
}
}
/**
* 不再生成具体的 type 类型,因为微信首次初始化,值为 undefined 时,会告警:property received type-uncompatible value
*
* @param mpComponentOptions
* @param rawProps
* @param isBehavior
......@@ -456,18 +449,17 @@ function initProps(mpComponentOptions, rawProps, isBehavior = false) {
if (isFunction(value)) {
value = value();
}
// const type = (opts as any).type as any
// ;(opts as any).type = parsePropType(key, type, value)
const type = opts.type;
opts.type = normalizePropType(type);
properties[key] = createProperty(key, {
type: null,
type: opts.type,
value,
});
}
else {
// content:String
// const type = parsePropType(key, opts, null)
properties[key] = createProperty(key, {
type: null, //PROP_TYPES.indexOf(type) !== -1 ? type : null,
type: normalizePropType(opts),
});
}
});
......
import { isCustomElement, isNativeTag } from '@dcloudio/uni-shared'
import { compile, CompilerOptions } from '@dcloudio/uni-mp-compiler'
import { transformFor } from '../src/plugin/transforms/vFor'
import { transformOn } from '../src/plugin/transforms/vOn'
import { transformModel } from '../src/plugin/transforms/vModel'
import { transformFor } from '../src/compiler/transforms/vFor'
import { transformOn } from '../src/compiler/transforms/vOn'
import { transformModel } from '../src/compiler/transforms/vModel'
import { miniProgram } from '../src/compiler/options'
export function assert(
template: string,
......@@ -26,10 +27,7 @@ export function assert(
model: transformModel,
},
miniProgram: {
slot: {
fallback: false,
},
directive: 's-',
...miniProgram,
emitFile({ source }) {
// console.log(source)
if (!options.onError) {
......
[
{
"input": {
"src/plugin/index.ts": "dist/uni.compiler.js"
"src/compiler/index.ts": "dist/uni.compiler.js"
},
"output": {
"format": "cjs"
......
'use strict';
var uniCliShared = require('@dcloudio/uni-cli-shared');
var initMiniProgramPlugin = require('@dcloudio/uni-mp-vite');
var path = require('path');
var uniMpCompiler = require('@dcloudio/uni-mp-compiler');
var compilerCore = require('@vue/compiler-core');
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
var initMiniProgramPlugin__default = /*#__PURE__*/_interopDefaultLegacy(initMiniProgramPlugin);
var path__default = /*#__PURE__*/_interopDefaultLegacy(path);
var appid = "";
var host = "baiduboxapp";
......@@ -142,27 +143,23 @@ const transformModel = (dir, node, context, augmentor) => {
return res;
};
const uniMiniProgramBaiduPlugin = {
name: 'vite:uni-mp-baidu',
config() {
return {
define: {
__VUE_CREATED_DEFERRED__: false,
},
};
const miniProgram = {
class: {
array: true,
},
slot: {
fallback: false,
},
directive: 's-',
};
const projectConfigFilename = 'project.swan.json';
const options = {
vite: {
inject: {
uni: [
uniCliShared.resolveBuiltIn('@dcloudio/uni-mp-baidu/dist/uni.api.esm.js'),
'default',
],
uni: [path__default["default"].resolve(__dirname, 'uni.api.esm.js'), 'default'],
},
alias: {
'uni-mp-runtime': uniCliShared.resolveBuiltIn('@dcloudio/uni-mp-baidu/dist/uni.mp.esm.js'),
'uni-mp-runtime': path__default["default"].resolve(__dirname, 'uni.mp.esm.js'),
},
copyOptions: {
assets: ['swancomponents'],
......@@ -177,8 +174,7 @@ const options = {
filename: projectConfigFilename,
source,
},
template: {
filter: {
template: Object.assign(Object.assign({}, miniProgram), { filter: {
extname: '.sjs',
lang: 'sjs',
generate(filter, filename) {
......@@ -186,26 +182,30 @@ const options = {
return `<import-sjs src="${filename}.sjs" module="${filter.name}"/>`;
}
return `<import-sjs module="${filter.name}">
${filter.code}
</import-sjs>`;
${filter.code}
</import-sjs>`;
},
},
slot: {
fallback: false,
},
extname: '.swan',
directive: 's-',
compilerOptions: {
}, extname: '.swan', compilerOptions: {
nodeTransforms: [transformFor],
directiveTransforms: {
on: transformOn,
model: transformModel,
},
},
},
} }),
style: {
extname: '.css',
},
};
const uniMiniProgramBaiduPlugin = {
name: 'vite:uni-mp-baidu',
config() {
return {
define: {
__VUE_CREATED_DEFERRED__: false,
},
};
},
};
var index = [uniMiniProgramBaiduPlugin, ...initMiniProgramPlugin__default["default"](options)];
......
......@@ -408,7 +408,7 @@ function findVmByVueId(instance, vuePid) {
}
}
// const PROP_TYPES = [String, Number, Boolean, Object, Array, null]
const PROP_TYPES = [String, Number, Boolean, Object, Array, null];
function createObserver(name) {
return function observer(newVal) {
if (this.$vm) {
......@@ -416,25 +416,28 @@ function createObserver(name) {
}
};
}
// function parsePropType(key: string, type: unknown, defaultValue: unknown) {
// // [String]=>String
// if (isArray(type) && type.length === 1) {
// return type[0]
// }
// if ("mp-baidu" === 'mp-baidu') {
// if (
// // [String,Boolean]=>Boolean
// defaultValue === false &&
// isArray(type) &&
// type.length === 2 &&
// type.indexOf(String) !== -1 &&
// type.indexOf(Boolean) !== -1
// ) {
// return Boolean
// }
// }
// return type
// }
function parsePropType(type, defaultValue) {
// [String]=>String
if (isArray(type) && type.length === 1) {
return type[0];
}
{
if (
// [String,Boolean]=>Boolean
defaultValue === false &&
isArray(type) &&
type.length === 2 &&
type.indexOf(String) !== -1 &&
type.indexOf(Boolean) !== -1) {
return Boolean;
}
}
return type;
}
function normalizePropType(type, defaultValue) {
const res = parsePropType(type, defaultValue);
return PROP_TYPES.indexOf(res) !== -1 ? res : null;
}
function initDefaultProps(isBehavior = false) {
const properties = {};
if (!isBehavior) {
......@@ -472,7 +475,7 @@ function createProperty(key, prop) {
return prop;
}
/**
* 不再生成具体的 type 类型,因为微信首次初始化,值为 undefined 时,会告警:property received type-uncompatible value
*
* @param mpComponentOptions
* @param rawProps
* @param isBehavior
......@@ -495,18 +498,17 @@ function initProps(mpComponentOptions, rawProps, isBehavior = false) {
if (isFunction(value)) {
value = value();
}
// const type = (opts as any).type as any
// ;(opts as any).type = parsePropType(key, type, value)
const type = opts.type;
opts.type = normalizePropType(type, value);
properties[key] = createProperty(key, {
type: null,
type: opts.type,
value,
});
}
else {
// content:String
// const type = parsePropType(key, opts, null)
properties[key] = createProperty(key, {
type: null, //PROP_TYPES.indexOf(type) !== -1 ? type : null,
type: normalizePropType(opts, null),
});
}
});
......@@ -688,7 +690,7 @@ function initTriggerEvent(mpInstance) {
return oldTriggerEvent.apply(mpInstance, [customize(event), ...args]);
};
}
function initHook(name, options) {
function initHook(name, options, isComponent) {
const oldHook = options[name];
if (!oldHook) {
options[name] = function () {
......
import type { Plugin } from 'vite'
import initMiniProgramPlugin from '@dcloudio/uni-mp-vite'
import { options } from './options'
const uniMiniProgramBaiduPlugin: Plugin = {
name: 'vite:uni-mp-baidu',
config() {
return {
define: {
__VUE_CREATED_DEFERRED__: false,
},
}
},
}
export default [uniMiniProgramBaiduPlugin, ...initMiniProgramPlugin(options)]
import type { Plugin } from 'vite'
import { resolveBuiltIn } from '@dcloudio/uni-cli-shared'
import initMiniProgramPlugin, {
UniMiniProgramPluginOptions,
} from '@dcloudio/uni-mp-vite'
import path from 'path'
import { MiniProgramCompilerOptions } from '@dcloudio/uni-cli-shared'
import { UniMiniProgramPluginOptions } from '@dcloudio/uni-mp-vite'
import source from './project.swan.json'
import { transformFor } from './transforms/vFor'
import { transformOn } from './transforms/vOn'
import { transformModel } from './transforms/vModel'
const uniMiniProgramBaiduPlugin: Plugin = {
name: 'vite:uni-mp-baidu',
config() {
return {
define: {
__VUE_CREATED_DEFERRED__: false,
},
}
export const miniProgram: MiniProgramCompilerOptions = {
class: {
array: true,
},
slot: {
fallback: false,
},
directive: 's-',
}
const projectConfigFilename = 'project.swan.json'
const options: UniMiniProgramPluginOptions = {
export const options: UniMiniProgramPluginOptions = {
vite: {
inject: {
uni: [
resolveBuiltIn('@dcloudio/uni-mp-baidu/dist/uni.api.esm.js'),
'default',
],
uni: [path.resolve(__dirname, 'uni.api.esm.js'), 'default'],
},
alias: {
'uni-mp-runtime': resolveBuiltIn(
'@dcloudio/uni-mp-baidu/dist/uni.mp.esm.js'
),
'uni-mp-runtime': path.resolve(__dirname, 'uni.mp.esm.js'),
},
copyOptions: {
assets: ['swancomponents'],
......@@ -49,6 +41,8 @@ const options: UniMiniProgramPluginOptions = {
source,
},
template: {
/* eslint-disable no-restricted-syntax */
...miniProgram,
filter: {
extname: '.sjs',
lang: 'sjs',
......@@ -57,15 +51,11 @@ const options: UniMiniProgramPluginOptions = {
return `<import-sjs src="${filename}.sjs" module="${filter.name}"/>`
}
return `<import-sjs module="${filter.name}">
${filter.code}
</import-sjs>`
${filter.code}
</import-sjs>`
},
},
slot: {
fallback: false,
},
extname: '.swan',
directive: 's-',
compilerOptions: {
nodeTransforms: [transformFor],
directiveTransforms: {
......@@ -78,5 +68,3 @@ ${filter.code}
extname: '.css',
},
}
export default [uniMiniProgramBaiduPlugin, ...initMiniProgramPlugin(options)]
import { assert as baseAssert, miniProgram } from './testUtils'
const assert: typeof baseAssert = (
template,
templateCode,
renderCode,
options
) => {
return baseAssert(template, templateCode, renderCode, {
...options,
miniProgram: {
...miniProgram,
class: {
array: false,
},
emitFile({ source }) {
expect(source).toBe(templateCode)
return ''
},
},
})
}
describe('compiler: transform class to binary expression', () => {
test(`static class`, () => {
assert(
`<view class="foo"/>`,
`<view class="foo"/>`,
`(_ctx, _cache) => {
return {}
}`
)
assert(
`<view class="foo bar"/>`,
`<view class="foo bar"/>`,
`(_ctx, _cache) => {
return {}
}`
)
assert(
`<view class="foo bar"/>`,
`<view class="foo bar"/>`,
`(_ctx, _cache) => {
return {}
}`
)
})
test('v-bind:class basic', () => {
assert(
`<view :class="foo"/>`,
`<view class="{{a}}"/>`,
`(_ctx, _cache) => {
return { a: _n(_ctx.foo) }
}`
)
assert(
`<view :class="foo | bar"/>`,
`<view class="{{a}}"/>`,
`(_ctx, _cache) => {
return { a: _n(_ctx.foo | _ctx.bar) }
}`
)
})
test('v-bind:class basic + class ', () => {
assert(
`<view :class="foo" class="bar"/>`,
`<view class="{{(a) + ' ' + 'bar'}}"/>`,
`(_ctx, _cache) => {
return { a: _n(_ctx.foo) }
}`
)
assert(
`<view class="bar" :class="foo"/>`,
`<view class="{{('bar') + ' ' + a}}"/>`,
`(_ctx, _cache) => {
return { a: _n(_ctx.foo) }
}`
)
})
test('v-bind:class object syntax', () => {
assert(
`<view :class="{ red: \`\${isRed}\` }"/>`,
`<view class="{{(a && 'red')}}"/>`,
`(_ctx, _cache) => {
return { a: \`\${_ctx.isRed}\` ? 1 : '' }
}`
)
assert(
`<view :class="{ a: 1, b: 0, c: true, d: false, e: null, f: undefined, g: ok, h: handle(ok), i: ok>1, j, [k]:1, [l]:m, ...n, ...{a:true}, ...{b:o} }"/>`,
`<view class="{{('a') + ' ' + 'c' + ' ' + (a && 'g') + ' ' + (b && 'h') + ' ' + (c && 'i') + ' ' + (d && 'j') + ' ' + e + ' ' + (g && f) + ' ' + h + ' ' + i + ' ' + j}}"/>`,
`(_ctx, _cache) => {
return { a: _ctx.ok ? 1 : '', b: _ctx.handle(_ctx.ok) ? 1 : '', c: _ctx.ok > 1 ? 1 : '', d: _ctx.j ? 1 : '', e: _ctx.k, f: _ctx.l, g: _ctx.m ? 1 : '', h: _n(_ctx.n), i: _n({ a: true }), j: _n({ b: _ctx.o }) }
}`
)
})
test('v-bind:class object syntax + class', () => {
assert(
`<view :class="{ red: isRed }" class="foo bar"/>`,
`<view class="{{(a && 'red') + ' ' + 'foo' + ' ' + 'bar'}}"/>`,
`(_ctx, _cache) => {
return { a: _ctx.isRed ? 1 : '' }
}`
)
assert(
`<view class="foo bar" :class="{ red: isRed }"/>`,
`<view class="{{('foo') + ' ' + 'bar' + ' ' + (a && 'red')}}"/>`,
`(_ctx, _cache) => {
return { a: _ctx.isRed ? 1 : '' }
}`
)
assert(
`<view :class="{ a: 1, b: 0, c: true, d: false, e: null, f: undefined, g: ok, h: handle(ok), i: ok>1, j, [k]:1, [l]:m, ...n, ...{a:true}, ...{b:o} }" class="foo bar"/>`,
`<view class="{{('a') + ' ' + 'c' + ' ' + (a && 'g') + ' ' + (b && 'h') + ' ' + (c && 'i') + ' ' + (d && 'j') + ' ' + e + ' ' + (g && f) + ' ' + h + ' ' + i + ' ' + j + ' ' + 'foo' + ' ' + 'bar'}}"/>`,
`(_ctx, _cache) => {
return { a: _ctx.ok ? 1 : '', b: _ctx.handle(_ctx.ok) ? 1 : '', c: _ctx.ok > 1 ? 1 : '', d: _ctx.j ? 1 : '', e: _ctx.k, f: _ctx.l, g: _ctx.m ? 1 : '', h: _n(_ctx.n), i: _n({ a: true }), j: _n({ b: _ctx.o }) }
}`
)
assert(
`<view class="foo bar" :class="{ a: 1, b: 0, c: true, d: false, e: null, f: undefined, g: ok, h: handle(ok), i: ok>1, j, [k]:1, [l]:m, ...n, ...{a:true}, ...{b:o} }"/>`,
`<view class="{{('foo') + ' ' + 'bar' + ' ' + 'a' + ' ' + 'c' + ' ' + (a && 'g') + ' ' + (b && 'h') + ' ' + (c && 'i') + ' ' + (d && 'j') + ' ' + e + ' ' + (g && f) + ' ' + h + ' ' + i + ' ' + j}}"/>`,
`(_ctx, _cache) => {
return { a: _ctx.ok ? 1 : '', b: _ctx.handle(_ctx.ok) ? 1 : '', c: _ctx.ok > 1 ? 1 : '', d: _ctx.j ? 1 : '', e: _ctx.k, f: _ctx.l, g: _ctx.m ? 1 : '', h: _n(_ctx.n), i: _n({ a: true }), j: _n({ b: _ctx.o }) }
}`
)
})
test('v-bind:class array syntax', () => {
assert(
`<view :class="[classA, \`\${classB}\`]"/>`,
`<view class="{{(a) + ' ' + b}}"/>`,
`(_ctx, _cache) => {
return { a: _n(_ctx.classA), b: _n(\`\${_ctx.classB}\`) }
}`
)
assert(
`<view :class="[classA, classB]"/>`,
`<view class="{{(a) + ' ' + b}}"/>`,
`(_ctx, _cache) => {
return { a: _n(_ctx.classA), b: _n(_ctx.classB) }
}`
)
assert(
`<view :class="[classA, classB, { classC: isC, classD: isD }, 'classE', isF ? 'classF' : '', isG && 'classG', ...classH, ...[classI,classJ], handle(classK) ]"/>`,
`<view class="{{(a) + ' ' + b + ' ' + c + ' ' + 'classE' + ' ' + d + ' ' + e + ' ' + f + ' ' + g + ' ' + h}}"/>`,
`(_ctx, _cache) => {
return { a: _n(_ctx.classA), b: _n(_ctx.classB), c: _n({ classC: _ctx.isC, classD: _ctx.isD }), d: _n(_ctx.isF ? 'classF' : ''), e: _n(_ctx.isG && 'classG'), f: _n(_ctx.classH), g: _n([_ctx.classI, _ctx.classJ]), h: _n(_ctx.handle(_ctx.classK)) }
}`
)
})
test('v-bind:class array syntax + class', () => {
assert(
`<view :class="[classA, classB]" class="foo bar"/>`,
`<view class="{{(a) + ' ' + b + ' ' + 'foo' + ' ' + 'bar'}}"/>`,
`(_ctx, _cache) => {
return { a: _n(_ctx.classA), b: _n(_ctx.classB) }
}`
)
assert(
`<view class="foo bar" :class="[classA, classB]"/>`,
`<view class="{{('foo') + ' ' + 'bar' + ' ' + a + ' ' + b}}"/>`,
`(_ctx, _cache) => {
return { a: _n(_ctx.classA), b: _n(_ctx.classB) }
}`
)
assert(
`<view :class="[classA, classB, { classC: isC, classD: isD }, 'classE', isF ? 'classF' : '', isG && 'classG', ...classH, ...[classI,classJ], handle(classK) ]" class="foo bar"/>`,
`<view class="{{(a) + ' ' + b + ' ' + c + ' ' + 'classE' + ' ' + d + ' ' + e + ' ' + f + ' ' + g + ' ' + h + ' ' + 'foo' + ' ' + 'bar'}}"/>`,
`(_ctx, _cache) => {
return { a: _n(_ctx.classA), b: _n(_ctx.classB), c: _n({ classC: _ctx.isC, classD: _ctx.isD }), d: _n(_ctx.isF ? 'classF' : ''), e: _n(_ctx.isG && 'classG'), f: _n(_ctx.classH), g: _n([_ctx.classI, _ctx.classJ]), h: _n(_ctx.handle(_ctx.classK)) }
}`
)
assert(
`<view class="foo bar" :class="[classA, classB, { classC: isC, classD: isD }, 'classE', isF ? 'classF' : '', isG && 'classG', ...classH, ...[classI,classJ], handle(classK) ]"/>`,
`<view class="{{('foo') + ' ' + 'bar' + ' ' + a + ' ' + b + ' ' + c + ' ' + 'classE' + ' ' + d + ' ' + e + ' ' + f + ' ' + g + ' ' + h}}"/>`,
`(_ctx, _cache) => {
return { a: _n(_ctx.classA), b: _n(_ctx.classB), c: _n({ classC: _ctx.isC, classD: _ctx.isD }), d: _n(_ctx.isF ? 'classF' : ''), e: _n(_ctx.isG && 'classG'), f: _n(_ctx.classH), g: _n([_ctx.classI, _ctx.classJ]), h: _n(_ctx.handle(_ctx.classK)) }
}`
)
})
})
......@@ -61,14 +61,14 @@ describe('compiler: transform class', () => {
`<view :class="{ red: \`\${isRed}\` }"/>`,
`<view class="{{[a && 'red']}}"/>`,
`(_ctx, _cache) => {
return { a: \`\${_ctx.isRed}\` ? 1 : 0 }
return { a: \`\${_ctx.isRed}\` ? 1 : '' }
}`
)
assert(
`<view :class="{ a: 1, b: 0, c: true, d: false, e: null, f: undefined, g: ok, h: handle(ok), i: ok>1, j, [k]:1, [l]:m, ...n, ...{a:true}, ...{b:o} }"/>`,
`<view class="{{['a', 'c', a && 'g', b && 'h', c && 'i', d && 'j', e, g && f, h, i, j]}}"/>`,
`(_ctx, _cache) => {
return { a: _ctx.ok ? 1 : 0, b: _ctx.handle(_ctx.ok) ? 1 : 0, c: _ctx.ok > 1 ? 1 : 0, d: _ctx.j ? 1 : 0, e: _ctx.k, f: _ctx.l, g: _ctx.m ? 1 : 0, h: _n(_ctx.n), i: _n({ a: true }), j: _n({ b: _ctx.o }) }
return { a: _ctx.ok ? 1 : '', b: _ctx.handle(_ctx.ok) ? 1 : '', c: _ctx.ok > 1 ? 1 : '', d: _ctx.j ? 1 : '', e: _ctx.k, f: _ctx.l, g: _ctx.m ? 1 : '', h: _n(_ctx.n), i: _n({ a: true }), j: _n({ b: _ctx.o }) }
}`
)
})
......@@ -77,28 +77,28 @@ describe('compiler: transform class', () => {
`<view :class="{ red: isRed }" class="foo bar"/>`,
`<view class="{{[a && 'red', 'foo', 'bar']}}"/>`,
`(_ctx, _cache) => {
return { a: _ctx.isRed ? 1 : 0 }
return { a: _ctx.isRed ? 1 : '' }
}`
)
assert(
`<view class="foo bar" :class="{ red: isRed }"/>`,
`<view class="{{['foo', 'bar', a && 'red']}}"/>`,
`(_ctx, _cache) => {
return { a: _ctx.isRed ? 1 : 0 }
return { a: _ctx.isRed ? 1 : '' }
}`
)
assert(
`<view :class="{ a: 1, b: 0, c: true, d: false, e: null, f: undefined, g: ok, h: handle(ok), i: ok>1, j, [k]:1, [l]:m, ...n, ...{a:true}, ...{b:o} }" class="foo bar"/>`,
`<view class="{{['a', 'c', a && 'g', b && 'h', c && 'i', d && 'j', e, g && f, h, i, j, 'foo', 'bar']}}"/>`,
`(_ctx, _cache) => {
return { a: _ctx.ok ? 1 : 0, b: _ctx.handle(_ctx.ok) ? 1 : 0, c: _ctx.ok > 1 ? 1 : 0, d: _ctx.j ? 1 : 0, e: _ctx.k, f: _ctx.l, g: _ctx.m ? 1 : 0, h: _n(_ctx.n), i: _n({ a: true }), j: _n({ b: _ctx.o }) }
return { a: _ctx.ok ? 1 : '', b: _ctx.handle(_ctx.ok) ? 1 : '', c: _ctx.ok > 1 ? 1 : '', d: _ctx.j ? 1 : '', e: _ctx.k, f: _ctx.l, g: _ctx.m ? 1 : '', h: _n(_ctx.n), i: _n({ a: true }), j: _n({ b: _ctx.o }) }
}`
)
assert(
`<view class="foo bar" :class="{ a: 1, b: 0, c: true, d: false, e: null, f: undefined, g: ok, h: handle(ok), i: ok>1, j, [k]:1, [l]:m, ...n, ...{a:true}, ...{b:o} }"/>`,
`<view class="{{['foo', 'bar', 'a', 'c', a && 'g', b && 'h', c && 'i', d && 'j', e, g && f, h, i, j]}}"/>`,
`(_ctx, _cache) => {
return { a: _ctx.ok ? 1 : 0, b: _ctx.handle(_ctx.ok) ? 1 : 0, c: _ctx.ok > 1 ? 1 : 0, d: _ctx.j ? 1 : 0, e: _ctx.k, f: _ctx.l, g: _ctx.m ? 1 : 0, h: _n(_ctx.n), i: _n({ a: true }), j: _n({ b: _ctx.o }) }
return { a: _ctx.ok ? 1 : '', b: _ctx.handle(_ctx.ok) ? 1 : '', c: _ctx.ok > 1 ? 1 : '', d: _ctx.j ? 1 : '', e: _ctx.k, f: _ctx.l, g: _ctx.m ? 1 : '', h: _n(_ctx.n), i: _n({ a: true }), j: _n({ b: _ctx.o }) }
}`
)
})
......
......@@ -6,7 +6,7 @@ describe('compiler: scope', () => {
`<view v-for="item in items" :key="item.id" :class="{red: item.isRed}" @longpress="longpress" @click="onClick(item)">{{item.title}}</view>`,
`<view wx:for="{{a}}" wx:for-item="item" wx:key="b" class="{{[item.c && 'red']}}" bindlongpress="{{b}}" bindtap="{{item.d}}">{{item.a}}</view>`,
`(_ctx, _cache) => {
return { a: _f(_ctx.items, (item, k0, i0) => { return { a: _t(item.title), b: item.id, c: item.isRed ? 1 : 0, d: _o($event => _ctx.onClick(item)) }; }), b: _o(_ctx.longpress) }
return { a: _f(_ctx.items, (item, k0, i0) => { return { a: _t(item.title), b: item.id, c: item.isRed ? 1 : '', d: _o($event => _ctx.onClick(item)) }; }), b: _o(_ctx.longpress) }
}`
)
})
......
......@@ -2,6 +2,7 @@
import { compile } from '../src'
import { CompilerOptions } from '../src/options'
import { miniProgram } from './testUtils'
function assert(
template: string,
......@@ -17,10 +18,7 @@ function assert(
concise: true,
},
miniProgram: {
slot: {
fallback: false,
},
directive: 'wx:',
...miniProgram,
emitFile({ source }) {
console.log(source)
// expect(source).toBe(templateCode)
......@@ -40,10 +38,10 @@ function assert(
describe('compiler', () => {
test('scope', () => {
assert(
`<view v-for="item in items"><view v-if="ok"></view></view>`,
`<view wx:if="{{a}}">{{b}}</view>`,
`<template slot="left"/>`,
`<block slot="left"/>`,
`(_ctx, _cache) => {
return { a: _f(_ctx.items, (item, k0, i0) => { return _ctx.ok ? {} : {}; }), b: _ctx.ok }
return {}
}`,
{
renderDataSpread: false,
......
import { MiniProgramCompilerOptions } from '@dcloudio/uni-cli-shared'
import { isCustomElement, isNativeTag } from '@dcloudio/uni-shared'
import { compile } from '../src/index'
import { CompilerOptions } from '../src/options'
export const miniProgram = {
export const miniProgram: MiniProgramCompilerOptions = {
class: {
array: true,
},
slot: {
fallback: false,
},
......@@ -30,10 +34,7 @@ export function assert(
concise: true,
},
miniProgram: {
slot: {
fallback: false,
},
directive: 'wx:',
...miniProgram,
emitFile({ source }) {
// console.log(source)
if (!options.onError) {
......
......@@ -73,6 +73,15 @@ describe('compiler: transform v-slot', () => {
`<view wx:for="{{a}}" wx:for-item="item"><custom wx:for="{{item.a}}" wx:for-item="item1" v-s="{{['default']}}" item="{{item1.b}}" v-i="{{item1.c}}"><view slot="default"><block wx:for="{{item1.a}}" wx:for-item="slotProps" wx:key="b"><view>{{slotProps.a}}</view></block></view></custom></view>`,
`(_ctx, _cache) => {
return { a: _f(_ctx.items, (item, k0, i0) => { return { a: _f(item.list, (item1, k1, i1) => { return { a: _w((slotProps, s2, i2) => { return { a: _t(slotProps.item), b: s2 }; }, { name: 'default', vueId: '2a9ec0b0-0' + '-' + i0 + '-' + i1 }), b: item1, c: '2a9ec0b0-0' + '-' + i0 + '-' + i1 }; }) }; }) }
}`
)
})
test('old syntax', () => {
assert(
`<template slot="left"/>`,
`<block slot="left"/>`,
`(_ctx, _cache) => {
return {}
}`
)
})
......
......@@ -88,6 +88,7 @@ export function baseCompile(template: string, options: CompilerOptions = {}) {
)
if (options.filename && options.miniProgram?.emitFile) {
genTemplate(ast, {
class: options.miniProgram.class,
scopeId: options.scopeId,
filename: options.filename,
directive: options.miniProgram.directive,
......
......@@ -48,6 +48,7 @@ interface SharedTransformCodegenOptions {
filename?: string
bindingMetadata?: BindingMetadata
prefixIdentifiers?: boolean
miniProgram?: MiniProgramCompilerOptions
}
export interface TransformOptions
......@@ -92,7 +93,6 @@ export interface CodegenOptions extends SharedTransformCodegenOptions {
runtimeModuleName?: string
runtimeGlobalName?: string
generatorOpts?: GeneratorOptions
miniProgram?: MiniProgramCompilerOptions
}
export interface TemplateCodegenOptions
......
......@@ -200,6 +200,10 @@ function genLazyElement(node: ElementNode, context: TemplateCodegenContext) {
function genElement(node: ElementNode, context: TemplateCodegenContext) {
const { children, isSelfClosing, props } = node
let tag = node.tag
// <template slot="left"/> => <block slot="left"/>
if (tag === 'template') {
tag = 'block'
}
if (node.tagType === ElementTypes.COMPONENT) {
tag = hyphenate(tag)
}
......
......@@ -247,6 +247,15 @@ export function createTransformContext(
renderDataSpread = false,
nodeTransforms = [],
directiveTransforms = {},
miniProgram = {
class: {
array: true,
},
slot: {
fallback: false,
},
directive: '',
},
isBuiltInComponent = NOOP,
isCustomElement = NOOP,
expressionPlugins = [],
......@@ -295,6 +304,7 @@ export function createTransformContext(
const context: TransformContext = {
// options
selfName: nameMatch && capitalize(camelize(nameMatch[1])),
miniProgram,
isTS,
inline,
hashId,
......
......@@ -19,6 +19,8 @@ import {
logicalExpression,
StringLiteral,
isTemplateLiteral,
parenthesizedExpression,
binaryExpression,
} from '@babel/types'
import {
DirectiveNode,
......@@ -40,7 +42,7 @@ import {
rewriteSpreadElement,
} from './utils'
export function isClassBinding({ arg, exp }: DirectiveNode) {
export function isClassBinding({ arg }: DirectiveNode) {
return (
arg && arg.type === NodeTypes.SIMPLE_EXPRESSION && arg.content === 'class'
)
......@@ -63,17 +65,17 @@ export function rewriteClass(
if (!expr) {
return
}
let classBidingExpr: Expression = expr
let classBindingExpr: Expression = expr
if (isObjectExpression(expr)) {
classBidingExpr = createClassBindingByObjectExpression(
classBindingExpr = createClassBindingByObjectExpression(
rewriteClassObjectExpression(expr, classBindingProp.loc, context)
)
} else if (isArrayExpression(expr)) {
classBidingExpr = createClassBindingByArrayExpression(
classBindingExpr = createClassBindingByArrayExpression(
rewriteClassArrayExpression(expr, context)
)
} else {
classBidingExpr = parseExpr(
classBindingExpr = parseExpr(
rewriteClassExpression(classBindingProp.exp, context).content,
context
) as Expression
......@@ -83,18 +85,49 @@ export function rewriteClass(
const staticClass = (props[staticClassPropIndex] as AttributeNode).value!
.content
if (staticClass) {
if (!isArrayExpression(classBidingExpr)) {
classBidingExpr = arrayExpression([classBidingExpr])
if (!isArrayExpression(classBindingExpr)) {
classBindingExpr = arrayExpression([classBindingExpr])
}
const staticClassLiterals = parseStaticClass(staticClass)
if (index > staticClassPropIndex) {
classBidingExpr.elements.unshift(...staticClassLiterals)
classBindingExpr.elements.unshift(...staticClassLiterals)
} else {
classBidingExpr.elements.push(...staticClassLiterals)
classBindingExpr.elements.push(...staticClassLiterals)
}
}
}
classBindingProp.exp = createSimpleExpression(genBabelExpr(classBidingExpr))
if (!context.miniProgram.class.array) {
classBindingExpr = parseClassBindingArrayExpr(classBindingExpr)
}
classBindingProp.exp = createSimpleExpression(genBabelExpr(classBindingExpr))
}
/**
* 目前 mp-toutiao, mp-alipay, mp-lark 不支持数组绑定class,故统一转换为字符串相加
* @param classBindingExpr
* @returns
*/
function parseClassBindingArrayExpr(classBindingExpr: Expression) {
if (!isArrayExpression(classBindingExpr)) {
return classBindingExpr
}
let binaryExpr!: Expression
classBindingExpr.elements.forEach((expr) => {
if (isArrayExpression(expr)) {
expr = parseClassBindingArrayExpr(expr)
}
if (!binaryExpr) {
binaryExpr = parenthesizedExpression(expr as Expression)
} else {
binaryExpr = binaryExpression(
'+',
binaryExpression('+', binaryExpr, stringLiteral(' ')),
expr as Expression
)
}
})
return binaryExpr
}
function parseStaticClass(staticClass: string): StringLiteral[] {
......
......@@ -9,6 +9,7 @@ import {
numericLiteral,
objectProperty,
SpreadElement,
stringLiteral,
} from '@babel/types'
import { isComponentTag } from '@dcloudio/uni-shared'
import {
......@@ -94,7 +95,7 @@ export function parseExprWithRewriteClass(
createSimpleExpression(code, false, loc),
context,
!isUndefined(node)
? conditionalExpression(node, numericLiteral(1), numericLiteral(0))
? conditionalExpression(node, numericLiteral(1), stringLiteral(''))
: node
),
context
......
......@@ -4,7 +4,7 @@ import { MPComponentOptions, MPComponentInstance } from './component'
import Component = WechatMiniprogram.Component
// const PROP_TYPES = [String, Number, Boolean, Object, Array, null]
const PROP_TYPES = [String, Number, Boolean, Object, Array, null]
function createObserver(name: string) {
return function observer(this: MPComponentInstance, newVal: unknown) {
......@@ -14,25 +14,34 @@ function createObserver(name: string) {
}
}
// function parsePropType(key: string, type: unknown, defaultValue: unknown) {
// // [String]=>String
// if (isArray(type) && type.length === 1) {
// return type[0]
// }
// if (__PLATFORM__ === 'mp-baidu') {
// if (
// // [String,Boolean]=>Boolean
// defaultValue === false &&
// isArray(type) &&
// type.length === 2 &&
// type.indexOf(String) !== -1 &&
// type.indexOf(Boolean) !== -1
// ) {
// return Boolean
// }
// }
// return type
// }
function parsePropType(type: unknown, defaultValue: unknown) {
// [String]=>String
if (isArray(type) && type.length === 1) {
return type[0]
}
if (__PLATFORM__ === 'mp-baidu') {
if (
// [String,Boolean]=>Boolean
defaultValue === false &&
isArray(type) &&
type.length === 2 &&
type.indexOf(String) !== -1 &&
type.indexOf(Boolean) !== -1
) {
return Boolean
}
}
return type
}
function normalizePropType(type: unknown, defaultValue: unknown) {
if (__PLATFORM__ === 'mp-weixin') {
// 不再生成具体的 type 类型,因为微信首次初始化,值为 undefined 时,会告警:property received type-uncompatible value
return null
}
const res = parsePropType(type, defaultValue)
return PROP_TYPES.indexOf(res) !== -1 ? res : null
}
function initDefaultProps(isBehavior: boolean = false) {
const properties: Component.PropertyOption = {}
......@@ -82,7 +91,7 @@ function createProperty(key: string, prop: any) {
}
/**
* 不再生成具体的 type 类型,因为微信首次初始化,值为 undefined 时,会告警:property received type-uncompatible value
*
* @param mpComponentOptions
* @param rawProps
* @param isBehavior
......@@ -109,17 +118,16 @@ export function initProps(
if (isFunction(value)) {
value = value()
}
// const type = (opts as any).type as any
// ;(opts as any).type = parsePropType(key, type, value)
const type = (opts as any).type as any
;(opts as any).type = normalizePropType(type, value)
properties[key] = createProperty(key, {
type: null, //PROP_TYPES.indexOf(type) !== -1 ? type : null,
type: (opts as any).type,
value,
})
} else {
// content:String
// const type = parsePropType(key, opts, null)
properties[key] = createProperty(key, {
type: null, //PROP_TYPES.indexOf(type) !== -1 ? type : null,
type: normalizePropType(opts, null),
})
}
})
......
......@@ -18,7 +18,15 @@ function initTriggerEvent(mpInstance: MPComponentInstance) {
}
}
function initHook(name: 'onLoad' | 'created', options: Record<string, any>) {
function initHook(
name: 'onLoad' | 'created',
options: Record<string, any>,
isComponent?: boolean
) {
if (__PLATFORM__ === 'mp-toutiao' && isComponent) {
// fix by Lxh 字节自定义组件Component构造器文档上写有created,但是实测只触发了lifetimes上的created
options = options.lifetimes
}
const oldHook = options[name]
if (!oldHook) {
options[name] = function (this: MPComponentInstance) {
......@@ -42,6 +50,6 @@ if (__PLATFORM__ === 'mp-baidu') {
;(Page as any).after = (MPPage as any).after
}
Component = function (options) {
initHook('created', options)
initHook('created', options, true)
return MPComponent(options)
}
......@@ -405,7 +405,7 @@ function findVmByVueId(instance, vuePid) {
}
}
// const PROP_TYPES = [String, Number, Boolean, Object, Array, null]
const PROP_TYPES = [String, Number, Boolean, Object, Array, null];
function createObserver(name) {
return function observer(newVal) {
if (this.$vm) {
......@@ -413,25 +413,17 @@ function createObserver(name) {
}
};
}
// function parsePropType(key: string, type: unknown, defaultValue: unknown) {
// // [String]=>String
// if (isArray(type) && type.length === 1) {
// return type[0]
// }
// if ("mp-kuaishou" === 'mp-baidu') {
// if (
// // [String,Boolean]=>Boolean
// defaultValue === false &&
// isArray(type) &&
// type.length === 2 &&
// type.indexOf(String) !== -1 &&
// type.indexOf(Boolean) !== -1
// ) {
// return Boolean
// }
// }
// return type
// }
function parsePropType(type, defaultValue) {
// [String]=>String
if (isArray(type) && type.length === 1) {
return type[0];
}
return type;
}
function normalizePropType(type, defaultValue) {
const res = parsePropType(type);
return PROP_TYPES.indexOf(res) !== -1 ? res : null;
}
function initDefaultProps(isBehavior = false) {
const properties = {};
if (!isBehavior) {
......@@ -461,7 +453,7 @@ function createProperty(key, prop) {
return prop;
}
/**
* 不再生成具体的 type 类型,因为微信首次初始化,值为 undefined 时,会告警:property received type-uncompatible value
*
* @param mpComponentOptions
* @param rawProps
* @param isBehavior
......@@ -484,18 +476,17 @@ function initProps(mpComponentOptions, rawProps, isBehavior = false) {
if (isFunction(value)) {
value = value();
}
// const type = (opts as any).type as any
// ;(opts as any).type = parsePropType(key, type, value)
const type = opts.type;
opts.type = normalizePropType(type);
properties[key] = createProperty(key, {
type: null,
type: opts.type,
value,
});
}
else {
// content:String
// const type = parsePropType(key, opts, null)
properties[key] = createProperty(key, {
type: null, //PROP_TYPES.indexOf(type) !== -1 ? type : null,
type: normalizePropType(opts),
});
}
});
......@@ -677,7 +668,7 @@ function initTriggerEvent(mpInstance) {
return oldTriggerEvent.apply(mpInstance, [customize(event), ...args]);
};
}
function initHook(name, options) {
function initHook(name, options, isComponent) {
const oldHook = options[name];
if (!oldHook) {
options[name] = function () {
......
[
{
"input": {
"src/plugin/index.ts": "dist/uni.compiler.js"
"src/compiler/index.ts": "dist/uni.compiler.js"
},
"output": {
"format": "cjs"
......
'use strict';
var uniCliShared = require('@dcloudio/uni-cli-shared');
var initMiniProgramPlugin = require('@dcloudio/uni-mp-vite');
var path = require('path');
var fs = require('fs-extra');
var uniCliShared = require('@dcloudio/uni-cli-shared');
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
......@@ -11,6 +11,27 @@ var initMiniProgramPlugin__default = /*#__PURE__*/_interopDefaultLegacy(initMini
var path__default = /*#__PURE__*/_interopDefaultLegacy(path);
var fs__default = /*#__PURE__*/_interopDefaultLegacy(fs);
let isFixed = false;
function fix2648(bundle) {
if (isFixed) {
return;
}
const appJsonAsset = bundle['app.json'];
if (!appJsonAsset) {
return;
}
try {
const { usingComponents } = JSON.parse(appJsonAsset.source.toString());
if (usingComponents && !Object.keys(usingComponents).length) {
fs__default["default"].outputFileSync(path__default["default"].resolve(process.env.UNI_OUTPUT_DIR, 'fix-2648.json'), `{"component":true}`);
fs__default["default"].outputFileSync(path__default["default"].resolve(process.env.UNI_OUTPUT_DIR, 'fix-2648.qml'), `<!-- https://github.com/dcloudio/uni-app/issues/2648 -->`);
fs__default["default"].outputFileSync(path__default["default"].resolve(process.env.UNI_OUTPUT_DIR, 'fix-2648.js'), `Component({})`);
}
isFixed = true;
}
catch (_a) { }
}
var description = "项目配置文件。";
var packOptions = {
ignore: [
......@@ -61,54 +82,13 @@ var source = {
condition: condition
};
let isFixed = false;
function fix2648(bundle) {
if (isFixed) {
return;
}
const appJsonAsset = bundle['app.json'];
if (!appJsonAsset) {
return;
}
try {
const { usingComponents } = JSON.parse(appJsonAsset.source.toString());
if (usingComponents && !Object.keys(usingComponents).length) {
fs__default["default"].outputFileSync(path__default["default"].resolve(process.env.UNI_OUTPUT_DIR, 'fix-2648.json'), `{"component":true}`);
fs__default["default"].outputFileSync(path__default["default"].resolve(process.env.UNI_OUTPUT_DIR, 'fix-2648.qml'), `<!-- https://github.com/dcloudio/uni-app/issues/2648 -->`);
fs__default["default"].outputFileSync(path__default["default"].resolve(process.env.UNI_OUTPUT_DIR, 'fix-2648.js'), `Component({})`);
}
isFixed = true;
}
catch (_a) { }
}
const uniMiniProgramQQPlugin = {
name: 'vite:uni-mp-qq',
config() {
return {
define: {
__VUE_CREATED_DEFERRED__: false,
},
build: {
// css 中不支持引用本地资源
assetsInlineLimit: 40 * 1024, // 40kb
},
};
},
writeBundle(_, bundle) {
fix2648(bundle);
},
};
const options = {
vite: {
inject: {
uni: [
uniCliShared.resolveBuiltIn('@dcloudio/uni-mp-qq/dist/uni.api.esm.js'),
'default',
],
uni: [path__default["default"].resolve(__dirname, 'uni.api.esm.js'), 'default'],
},
alias: {
'uni-mp-runtime': uniCliShared.resolveBuiltIn('@dcloudio/uni-mp-qq/dist/uni.mp.esm.js'),
'uni-mp-runtime': path__default["default"].resolve(__dirname, 'uni.mp.esm.js'),
},
copyOptions: {
assets: ['wxcomponents'],
......@@ -132,6 +112,9 @@ const options = {
source,
},
template: {
class: {
array: true,
},
filter: {
extname: '.qs',
lang: 'wxs',
......@@ -140,8 +123,8 @@ const options = {
return `<qs src="${filename}.qs" module="${filter.name}"/>`;
}
return `<qs module="${filter.name}">
${filter.code}
</qs>`;
${filter.code}
</qs>`;
},
},
slot: {
......@@ -156,6 +139,24 @@ ${filter.code}
style: {
extname: '.qss',
},
};
const uniMiniProgramQQPlugin = {
name: 'vite:uni-mp-qq',
config() {
return {
define: {
__VUE_CREATED_DEFERRED__: false,
},
build: {
// css 中不支持引用本地资源
assetsInlineLimit: 40 * 1024, // 40kb
},
};
},
writeBundle(_, bundle) {
fix2648(bundle);
},
};
var index = [uniMiniProgramQQPlugin, ...initMiniProgramPlugin__default["default"](options)];
......
......@@ -405,7 +405,7 @@ function findVmByVueId(instance, vuePid) {
}
}
// const PROP_TYPES = [String, Number, Boolean, Object, Array, null]
const PROP_TYPES = [String, Number, Boolean, Object, Array, null];
function createObserver(name) {
return function observer(newVal) {
if (this.$vm) {
......@@ -413,25 +413,17 @@ function createObserver(name) {
}
};
}
// function parsePropType(key: string, type: unknown, defaultValue: unknown) {
// // [String]=>String
// if (isArray(type) && type.length === 1) {
// return type[0]
// }
// if ("mp-qq" === 'mp-baidu') {
// if (
// // [String,Boolean]=>Boolean
// defaultValue === false &&
// isArray(type) &&
// type.length === 2 &&
// type.indexOf(String) !== -1 &&
// type.indexOf(Boolean) !== -1
// ) {
// return Boolean
// }
// }
// return type
// }
function parsePropType(type, defaultValue) {
// [String]=>String
if (isArray(type) && type.length === 1) {
return type[0];
}
return type;
}
function normalizePropType(type, defaultValue) {
const res = parsePropType(type);
return PROP_TYPES.indexOf(res) !== -1 ? res : null;
}
function initDefaultProps(isBehavior = false) {
const properties = {};
if (!isBehavior) {
......@@ -461,7 +453,7 @@ function createProperty(key, prop) {
return prop;
}
/**
* 不再生成具体的 type 类型,因为微信首次初始化,值为 undefined 时,会告警:property received type-uncompatible value
*
* @param mpComponentOptions
* @param rawProps
* @param isBehavior
......@@ -484,18 +476,17 @@ function initProps(mpComponentOptions, rawProps, isBehavior = false) {
if (isFunction(value)) {
value = value();
}
// const type = (opts as any).type as any
// ;(opts as any).type = parsePropType(key, type, value)
const type = opts.type;
opts.type = normalizePropType(type);
properties[key] = createProperty(key, {
type: null,
type: opts.type,
value,
});
}
else {
// content:String
// const type = parsePropType(key, opts, null)
properties[key] = createProperty(key, {
type: null, //PROP_TYPES.indexOf(type) !== -1 ? type : null,
type: normalizePropType(opts),
});
}
});
......@@ -677,7 +668,7 @@ function initTriggerEvent(mpInstance) {
return oldTriggerEvent.apply(mpInstance, [customize(event), ...args]);
};
}
function initHook(name, options) {
function initHook(name, options, isComponent) {
const oldHook = options[name];
if (!oldHook) {
options[name] = function () {
......
import { Plugin } from 'vite'
import initMiniProgramPlugin from '@dcloudio/uni-mp-vite'
import { fix2648 } from './fix2648'
import { options } from './options'
const uniMiniProgramQQPlugin: Plugin = {
name: 'vite:uni-mp-qq',
config() {
return {
define: {
__VUE_CREATED_DEFERRED__: false,
},
build: {
// css 中不支持引用本地资源
assetsInlineLimit: 40 * 1024, // 40kb
},
}
},
writeBundle(_, bundle) {
fix2648(bundle)
},
}
export default [uniMiniProgramQQPlugin, ...initMiniProgramPlugin(options)]
import { Plugin } from 'vite'
import { addComponentBindLink, resolveBuiltIn } from '@dcloudio/uni-cli-shared'
import initMiniProgramPlugin, {
UniMiniProgramPluginOptions,
} from '@dcloudio/uni-mp-vite'
import path from 'path'
import source from './project.config.json'
import { fix2648 } from './fix2648'
import { addComponentBindLink } from '@dcloudio/uni-cli-shared'
import { UniMiniProgramPluginOptions } from '@dcloudio/uni-mp-vite'
const uniMiniProgramQQPlugin: Plugin = {
name: 'vite:uni-mp-qq',
config() {
return {
define: {
__VUE_CREATED_DEFERRED__: false,
},
build: {
// css 中不支持引用本地资源
assetsInlineLimit: 40 * 1024, // 40kb
},
}
},
writeBundle(_, bundle) {
fix2648(bundle)
},
}
import source from './project.config.json'
const options: UniMiniProgramPluginOptions = {
export const options: UniMiniProgramPluginOptions = {
vite: {
inject: {
uni: [
resolveBuiltIn('@dcloudio/uni-mp-qq/dist/uni.api.esm.js'),
'default',
],
uni: [path.resolve(__dirname, 'uni.api.esm.js'), 'default'],
},
alias: {
'uni-mp-runtime': resolveBuiltIn(
'@dcloudio/uni-mp-qq/dist/uni.mp.esm.js'
),
'uni-mp-runtime': path.resolve(__dirname, 'uni.mp.esm.js'),
},
copyOptions: {
assets: ['wxcomponents'],
......@@ -60,6 +35,9 @@ const options: UniMiniProgramPluginOptions = {
source,
},
template: {
class: {
array: true,
},
filter: {
extname: '.qs',
lang: 'wxs',
......@@ -68,8 +46,8 @@ const options: UniMiniProgramPluginOptions = {
return `<qs src="${filename}.qs" module="${filter.name}"/>`
}
return `<qs module="${filter.name}">
${filter.code}
</qs>`
${filter.code}
</qs>`
},
},
slot: {
......@@ -85,5 +63,3 @@ ${filter.code}
extname: '.qss',
},
}
export default [uniMiniProgramQQPlugin, ...initMiniProgramPlugin(options)]
{
"input": {
"src/runtime/index.ts": "dist/uni.mp.esm.js",
"src/api/index.ts": "dist/uni.api.esm.js"
[
{
"input": {
"src/compiler/index.ts": "dist/uni.compiler.js"
},
"output": {
"format": "cjs"
},
"external": ["@dcloudio/uni-cli-shared", "@dcloudio/uni-mp-vite"]
},
"alias": {
"entries": [
{
"find": "@dcloudio/uni-platform",
"replacement": "packages/uni-mp-toutiao/src/platform/index.ts"
},
{
"find": "@dcloudio/uni-mp-platform",
"replacement": "packages/uni-mp-core/src/platform/index.ts"
}
]
},
"replacements": {
"__GLOBAL__": "tt",
"__PLATFORM__": "\"mp-toutiao\"",
"__PLATFORM_TITLE__": "字节跳动小程序"
},
"external": ["@dcloudio/uni-i18n", "@vue/shared", "vue"]
}
{
"input": {
"src/runtime/index.ts": "dist/uni.mp.esm.js",
"src/api/index.ts": "dist/uni.api.esm.js"
},
"alias": {
"entries": [
{
"find": "@dcloudio/uni-platform",
"replacement": "packages/uni-mp-toutiao/src/platform/index.ts"
},
{
"find": "@dcloudio/uni-mp-platform",
"replacement": "packages/uni-mp-core/src/platform/index.ts"
}
]
},
"replacements": {
"__GLOBAL__": "tt",
"__PLATFORM__": "\"mp-toutiao\"",
"__PLATFORM_TITLE__": "字节跳动小程序"
},
"external": ["@dcloudio/uni-i18n", "@vue/shared", "vue"]
}
]
'use strict';
var initMiniProgramPlugin = require('@dcloudio/uni-mp-vite');
var path = require('path');
var uniCliShared = require('@dcloudio/uni-cli-shared');
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
var initMiniProgramPlugin__default = /*#__PURE__*/_interopDefaultLegacy(initMiniProgramPlugin);
var path__default = /*#__PURE__*/_interopDefaultLegacy(path);
var setting = {
urlCheck: false,
es6: true,
postcss: false,
minified: false,
newFeature: true
};
var appid = "testAppId";
var projectname = "";
var condition = {
miniprogram: {
current: -1
}
};
var source = {
setting: setting,
appid: appid,
projectname: projectname,
condition: condition
};
const projectConfigFilename = 'project.config.json';
const options = {
vite: {
inject: {
uni: [path__default["default"].resolve(__dirname, 'uni.api.esm.js'), 'default'],
},
alias: {
'uni-mp-runtime': path__default["default"].resolve(__dirname, 'uni.mp.esm.js'),
},
copyOptions: {
assets: ['ttcomponents'],
},
},
global: 'tt',
app: {
darkmode: false,
subpackages: true,
},
project: {
filename: projectConfigFilename,
source,
},
template: {
class: {
array: false,
},
filter: {
extname: '.sjs',
lang: 'sjs',
generate(filter, filename) {
if (filename) {
return `<sjs src="${filename}.sjs" module="${filter.name}"/>`;
}
return `<sjs module="${filter.name}">
${filter.code}
</sjs>`;
},
},
slot: {
fallback: false,
},
extname: '.ttml',
directive: 'tt:',
compilerOptions: {
nodeTransforms: [uniCliShared.addComponentBindLink],
},
},
style: {
extname: '.ttss',
},
};
const uniMiniProgramToutiaoPlugin = {
name: 'vite:uni-mp-toutiao',
config() {
return {
define: {
__VUE_CREATED_DEFERRED__: true,
},
build: {
// 头条支持本地资源
assetsInlineLimit: 0,
},
};
},
};
var index = [uniMiniProgramToutiaoPlugin, ...initMiniProgramPlugin__default["default"](options)];
module.exports = index;
......@@ -408,7 +408,7 @@ function findVmByVueId(instance, vuePid) {
}
}
// const PROP_TYPES = [String, Number, Boolean, Object, Array, null]
const PROP_TYPES = [String, Number, Boolean, Object, Array, null];
function createObserver(name) {
return function observer(newVal) {
if (this.$vm) {
......@@ -416,25 +416,17 @@ function createObserver(name) {
}
};
}
// function parsePropType(key: string, type: unknown, defaultValue: unknown) {
// // [String]=>String
// if (isArray(type) && type.length === 1) {
// return type[0]
// }
// if ("mp-toutiao" === 'mp-baidu') {
// if (
// // [String,Boolean]=>Boolean
// defaultValue === false &&
// isArray(type) &&
// type.length === 2 &&
// type.indexOf(String) !== -1 &&
// type.indexOf(Boolean) !== -1
// ) {
// return Boolean
// }
// }
// return type
// }
function parsePropType(type, defaultValue) {
// [String]=>String
if (isArray(type) && type.length === 1) {
return type[0];
}
return type;
}
function normalizePropType(type, defaultValue) {
const res = parsePropType(type);
return PROP_TYPES.indexOf(res) !== -1 ? res : null;
}
function initDefaultProps(isBehavior = false) {
const properties = {};
if (!isBehavior) {
......@@ -470,7 +462,7 @@ function createProperty(key, prop) {
return prop;
}
/**
* 不再生成具体的 type 类型,因为微信首次初始化,值为 undefined 时,会告警:property received type-uncompatible value
*
* @param mpComponentOptions
* @param rawProps
* @param isBehavior
......@@ -493,18 +485,17 @@ function initProps(mpComponentOptions, rawProps, isBehavior = false) {
if (isFunction(value)) {
value = value();
}
// const type = (opts as any).type as any
// ;(opts as any).type = parsePropType(key, type, value)
const type = opts.type;
opts.type = normalizePropType(type);
properties[key] = createProperty(key, {
type: null,
type: opts.type,
value,
});
}
else {
// content:String
// const type = parsePropType(key, opts, null)
properties[key] = createProperty(key, {
type: null, //PROP_TYPES.indexOf(type) !== -1 ? type : null,
type: normalizePropType(opts),
});
}
});
......@@ -686,7 +677,11 @@ function initTriggerEvent(mpInstance) {
return oldTriggerEvent.apply(mpInstance, [customize(event), ...args]);
};
}
function initHook(name, options) {
function initHook(name, options, isComponent) {
if (isComponent) {
// fix by Lxh 字节自定义组件Component构造器文档上写有created,但是实测只触发了lifetimes上的created
options = options.lifetimes;
}
const oldHook = options[name];
if (!oldHook) {
options[name] = function () {
......@@ -705,7 +700,7 @@ Page = function (options) {
return MPPage(options);
};
Component = function (options) {
initHook('created', options);
initHook('created', options, true);
return MPComponent(options);
};
......@@ -794,36 +789,65 @@ function initInjections(instance) {
}
}
// 基础库 2.0 以上 attached 顺序错乱,按照 created 顺序强制纠正
const components = [];
function initLifetimes$1({ mocks, isPage, initRelation, vueOptions, }) {
return {
created() {
components.push(this);
},
attached() {
const properties = this.properties;
initVueIds(properties.vI, this);
const relationOptions = {
vuePid: this._$vuePid,
this.__lifetimes_attached = function () {
const properties = this.properties;
initVueIds(properties.vI, this);
const relationOptions = {
vuePid: this._$vuePid,
};
// 初始化 vue 实例
const mpInstance = this;
const mpType = isPage(mpInstance) ? 'page' : 'component';
if (mpType === 'page' && !mpInstance.route && mpInstance.__route__) {
mpInstance.route = mpInstance.__route__;
}
// 字节跳动小程序 properties
// 父组件在 attached 中 setData 设置了子组件的 props,在子组件的 attached 中,并不能立刻拿到
// 此时子组件的 properties 中获取到的值,除了一部分初始化就有的值,只要在模板上绑定了,动态设置的 prop 的值均会根据类型返回,不会应用 prop 自己的默认值
// 举例: easyinput 的 styles 属性,类型为 Object,`<easyinput :styles="styles"/>` 在 attached 中 styles 的值为 null
// 目前 null 值会影响 render 函数执行,临时解决方案,调整 properties 中的 null 值为 undefined,让 Vue 来补充为默认值
// 已知的其他隐患,当使用默认值时,可能组件行为不正确,比如 countdown 组件,默认值是0,导致直接就触发了 timeup 事件,这个应该是组件自身做处理?
// 难道要等父组件首次 setData 完成后,再去执行子组件的初始化?
Object.keys(properties).forEach((name) => {
if (properties[name] === null) {
properties[name] = undefined;
}
});
this.$vm = $createComponent({
type: vueOptions,
props: properties,
}, {
mpType,
mpInstance,
slots: properties.vS,
parentComponent: relationOptions.parent && relationOptions.parent.$,
onBeforeSetup(instance, options) {
initRefs(instance, mpInstance);
initMocks(instance, mpInstance, mocks);
initComponentInstance(instance, options);
},
});
// 处理父子关系
initRelation(this, relationOptions);
};
// 初始化 vue 实例
const mpInstance = this;
const mpType = isPage(mpInstance) ? 'page' : 'component';
if (mpType === 'page' && !mpInstance.route && mpInstance.__route__) {
mpInstance.route = mpInstance.__route__;
let component = this;
while (component &&
component.__lifetimes_attached &&
components[0] &&
component === components[0]) {
components.shift();
component.__lifetimes_attached();
delete component.__lifetimes_attached;
component = components[0];
}
this.$vm = $createComponent({
type: vueOptions,
props: properties,
}, {
mpType,
mpInstance,
slots: properties.vS,
parentComponent: relationOptions.parent && relationOptions.parent.$,
onBeforeSetup(instance, options) {
initRefs(instance, mpInstance);
initMocks(instance, mpInstance, mocks);
initComponentInstance(instance, options);
},
});
// 处理父子关系
initRelation(this, relationOptions);
},
detached() {
this.$vm && $destroyComponent(this.$vm);
......@@ -899,6 +923,9 @@ function initLifetimes(lifetimesOptions) {
return extend(initLifetimes$1(lifetimesOptions), {
ready() {
if (this.$vm && lifetimesOptions.isPage(this)) {
if (this.pageinstance) {
this.__webviewId__ = this.pageinstance.__pageId__;
}
this.$vm.$callCreatedHook();
this.$vm.$callHook('mounted');
this.$vm.$callHook(ON_READY);
......
{
"name": "@dcloudio/uni-mp-toutiao",
"version": "3.0.0-alpha-3021020211027001",
"version": "3.0.0-alpha-3021020211025001",
"description": "uni-app mp-toutiao",
"main": "dist/index.js",
"repository": {
......@@ -14,7 +14,9 @@
"license": "Apache-2.0",
"uni-app": {
"name": "mp-toutiao",
"title": "字节跳动小程序"
"title": "字节跳动小程序",
"apply": "mp-toutiao",
"main": "dist/uni.compiler.js"
},
"gitHead": "1efa8efd0a9eddeabdba75c020d015ebf31b8177"
}
import { Plugin } from 'vite'
import initMiniProgramPlugin from '@dcloudio/uni-mp-vite'
import { options } from './options'
const uniMiniProgramToutiaoPlugin: Plugin = {
name: 'vite:uni-mp-toutiao',
config() {
return {
define: {
__VUE_CREATED_DEFERRED__: true,
},
build: {
// 头条支持本地资源
assetsInlineLimit: 0,
},
}
},
}
export default [uniMiniProgramToutiaoPlugin, ...initMiniProgramPlugin(options)]
import path from 'path'
import { addComponentBindLink } from '@dcloudio/uni-cli-shared'
import { UniMiniProgramPluginOptions } from '@dcloudio/uni-mp-vite'
import source from './project.config.json'
const projectConfigFilename = 'project.config.json'
export const options: UniMiniProgramPluginOptions = {
vite: {
inject: {
uni: [path.resolve(__dirname, 'uni.api.esm.js'), 'default'],
},
alias: {
'uni-mp-runtime': path.resolve(__dirname, 'uni.mp.esm.js'),
},
copyOptions: {
assets: ['ttcomponents'],
},
},
global: 'tt',
app: {
darkmode: false,
subpackages: true,
},
project: {
filename: projectConfigFilename,
source,
},
template: {
class: {
array: false,
},
filter: {
extname: '.sjs',
lang: 'sjs',
generate(filter, filename) {
if (filename) {
return `<sjs src="${filename}.sjs" module="${filter.name}"/>`
}
return `<sjs module="${filter.name}">
${filter.code}
</sjs>`
},
},
slot: {
fallback: false,
},
extname: '.ttml',
directive: 'tt:',
compilerOptions: {
nodeTransforms: [addComponentBindLink],
},
},
style: {
extname: '.ttss',
},
}
{
"setting": {
"urlCheck": false,
"es6": true,
"postcss": false,
"minified": false,
"newFeature": true
},
"appid": "testAppId",
"projectname": "",
"condition": {
"miniprogram": {
"current": -1
}
}
}
......@@ -16,6 +16,9 @@ import {
initComponentInstance,
} from '@dcloudio/uni-mp-core'
// 基础库 2.0 以上 attached 顺序错乱,按照 created 顺序强制纠正
const components: MPComponentInstance[] = []
export function initLifetimes({
mocks,
isPage,
......@@ -23,41 +26,72 @@ export function initLifetimes({
vueOptions,
}: CreateLifetimesOptions) {
return {
created(this: MPComponentInstance) {
components.push(this)
},
attached(this: MPComponentInstance) {
const properties = this.properties
initVueIds(properties.vI, this)
const relationOptions: RelationOptions = {
vuePid: this._$vuePid,
}
// 初始化 vue 实例
const mpInstance = this
const mpType = isPage(mpInstance) ? 'page' : 'component'
if (mpType === 'page' && !mpInstance.route && mpInstance.__route__) {
mpInstance.route = mpInstance.__route__
}
this.$vm = $createComponent(
{
type: vueOptions,
props: properties,
},
{
mpType,
mpInstance,
slots: properties.vS, // vueSlots
parentComponent: relationOptions.parent && relationOptions.parent.$,
onBeforeSetup(
instance: ComponentInternalInstance,
options: CreateComponentOptions
) {
initRefs(instance, mpInstance)
initMocks(instance, mpInstance, mocks)
initComponentInstance(instance, options)
},
this.__lifetimes_attached = function () {
const properties = this.properties
initVueIds(properties.vI, this)
const relationOptions: RelationOptions = {
vuePid: this._$vuePid,
}
// 初始化 vue 实例
const mpInstance = this
const mpType = isPage(mpInstance) ? 'page' : 'component'
if (mpType === 'page' && !mpInstance.route && mpInstance.__route__) {
mpInstance.route = mpInstance.__route__
}
) as ComponentPublicInstance
// 处理父子关系
initRelation(this, relationOptions)
// 字节跳动小程序 properties
// 父组件在 attached 中 setData 设置了子组件的 props,在子组件的 attached 中,并不能立刻拿到
// 此时子组件的 properties 中获取到的值,除了一部分初始化就有的值,只要在模板上绑定了,动态设置的 prop 的值均会根据类型返回,不会应用 prop 自己的默认值
// 举例: easyinput 的 styles 属性,类型为 Object,`<easyinput :styles="styles"/>` 在 attached 中 styles 的值为 null
// 目前 null 值会影响 render 函数执行,临时解决方案,调整 properties 中的 null 值为 undefined,让 Vue 来补充为默认值
// 已知的其他隐患,当使用默认值时,可能组件行为不正确,比如 countdown 组件,默认值是0,导致直接就触发了 timeup 事件,这个应该是组件自身做处理?
// 难道要等父组件首次 setData 完成后,再去执行子组件的初始化?
Object.keys(properties).forEach((name) => {
if (properties[name] === null) {
properties[name] = undefined
}
})
this.$vm = $createComponent(
{
type: vueOptions,
props: properties,
},
{
mpType,
mpInstance,
slots: properties.vS, // vueSlots
parentComponent: relationOptions.parent && relationOptions.parent.$,
onBeforeSetup(
instance: ComponentInternalInstance,
options: CreateComponentOptions
) {
initRefs(instance, mpInstance)
initMocks(instance, mpInstance, mocks)
initComponentInstance(instance, options)
},
}
) as ComponentPublicInstance
// 处理父子关系
initRelation(this, relationOptions)
}
let component = this
while (
component &&
component.__lifetimes_attached &&
components[0] &&
component === components[0]
) {
components.shift()
component.__lifetimes_attached()
delete component.__lifetimes_attached
component = components[0]
}
},
detached(this: MPComponentInstance) {
this.$vm && $destroyComponent(this.$vm)
......
import { extend } from '@vue/shared'
import { ON_READY } from '@dcloudio/uni-shared'
import {
MPComponentInstance,
CreateLifetimesOptions,
......@@ -9,13 +9,12 @@ import { $destroyComponent } from '@dcloudio/uni-mp-core'
import { initLifetimes as initComponentLifetimes } from './componentLifetimes'
import { instances } from './parseComponentOptions'
import { ON_READY } from '@dcloudio/uni-shared'
export function initLifetimes(lifetimesOptions: CreateLifetimesOptions) {
return extend(initComponentLifetimes(lifetimesOptions), {
ready(this: MPComponentInstance) {
if (this.$vm && lifetimesOptions.isPage(this)) {
if (__PLATFORM__ === 'quickapp-webview' && this.pageinstance) {
if (this.pageinstance) {
this.__webviewId__ = (this.pageinstance as any).__pageId__
}
this.$vm.$callCreatedHook()
......
......@@ -6,6 +6,7 @@ import {
genNVueCssCode,
parseManifestJsonOnce,
findMiniProgramTemplateFiles,
MiniProgramCompilerOptions,
} from '@dcloudio/uni-cli-shared'
import type { CompilerOptions } from '@dcloudio/uni-mp-compiler'
......@@ -37,10 +38,8 @@ export interface UniMiniProgramPluginOptions {
template: {
extname: string
directive: string
slot: {
// 是否支持fallback content
fallback: boolean
}
class: MiniProgramCompilerOptions['class']
slot: MiniProgramCompilerOptions['slot']
filter?: {
lang: string
extname: string
......@@ -70,6 +69,7 @@ export function uniMiniProgramPlugin(
uni: uniOptions({
copyOptions,
miniProgram: {
class: template.class,
filter: template.filter ? { lang: template.filter.lang } : undefined,
directive: template.directive,
emitFile,
......
[
{
"input": {
"src/plugin/index.ts": "dist/uni.compiler.js"
"src/compiler/index.ts": "dist/uni.compiler.js"
},
"output": {
"format": "cjs"
......
'use strict';
var uniCliShared = require('@dcloudio/uni-cli-shared');
var initMiniProgramPlugin = require('@dcloudio/uni-mp-vite');
var path = require('path');
var uniCliShared = require('@dcloudio/uni-cli-shared');
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
var initMiniProgramPlugin__default = /*#__PURE__*/_interopDefaultLegacy(initMiniProgramPlugin);
var path__default = /*#__PURE__*/_interopDefaultLegacy(path);
var description = "项目配置文件。";
var packOptions = {
......@@ -56,31 +58,14 @@ var source = {
condition: condition
};
const uniMiniProgramWeixinPlugin = {
name: 'vite:uni-mp-weixin',
config() {
return {
define: {
__VUE_CREATED_DEFERRED__: false,
},
build: {
// css 中不支持引用本地资源
assetsInlineLimit: 40 * 1024, // 40kb
},
};
},
};
const projectConfigFilename = 'project.config.json';
const options = {
vite: {
inject: {
uni: [
uniCliShared.resolveBuiltIn('@dcloudio/uni-mp-weixin/dist/uni.api.esm.js'),
'default',
],
uni: [path__default["default"].resolve(__dirname, 'uni.api.esm.js'), 'default'],
},
alias: {
'uni-mp-runtime': uniCliShared.resolveBuiltIn('@dcloudio/uni-mp-weixin/dist/uni.mp.esm.js'),
'uni-mp-runtime': path__default["default"].resolve(__dirname, 'uni.mp.esm.js'),
},
copyOptions: {
assets: ['wxcomponents'],
......@@ -111,6 +96,9 @@ const options = {
source,
},
template: {
class: {
array: true,
},
filter: {
extname: '.wxs',
lang: 'wxs',
......@@ -135,6 +123,21 @@ ${filter.code}
style: {
extname: '.wxss',
},
};
const uniMiniProgramWeixinPlugin = {
name: 'vite:uni-mp-weixin',
config() {
return {
define: {
__VUE_CREATED_DEFERRED__: false,
},
build: {
// css 中不支持引用本地资源
assetsInlineLimit: 40 * 1024, // 40kb
},
};
},
};
var index = [uniMiniProgramWeixinPlugin, ...initMiniProgramPlugin__default["default"](options)];
......
......@@ -351,7 +351,6 @@ function findVmByVueId(instance, vuePid) {
}
}
// const PROP_TYPES = [String, Number, Boolean, Object, Array, null]
function createObserver(name) {
return function observer(newVal) {
if (this.$vm) {
......@@ -359,25 +358,12 @@ function createObserver(name) {
}
};
}
// function parsePropType(key: string, type: unknown, defaultValue: unknown) {
// // [String]=>String
// if (isArray(type) && type.length === 1) {
// return type[0]
// }
// if ("mp-weixin" === 'mp-baidu') {
// if (
// // [String,Boolean]=>Boolean
// defaultValue === false &&
// isArray(type) &&
// type.length === 2 &&
// type.indexOf(String) !== -1 &&
// type.indexOf(Boolean) !== -1
// ) {
// return Boolean
// }
// }
// return type
// }
function normalizePropType(type, defaultValue) {
{
// 不再生成具体的 type 类型,因为微信首次初始化,值为 undefined 时,会告警:property received type-uncompatible value
return null;
}
}
function initDefaultProps(isBehavior = false) {
const properties = {};
if (!isBehavior) {
......@@ -407,7 +393,7 @@ function createProperty(key, prop) {
return prop;
}
/**
* 不再生成具体的 type 类型,因为微信首次初始化,值为 undefined 时,会告警:property received type-uncompatible value
*
* @param mpComponentOptions
* @param rawProps
* @param isBehavior
......@@ -430,18 +416,17 @@ function initProps(mpComponentOptions, rawProps, isBehavior = false) {
if (isFunction(value)) {
value = value();
}
// const type = (opts as any).type as any
// ;(opts as any).type = parsePropType(key, type, value)
opts.type;
opts.type = normalizePropType();
properties[key] = createProperty(key, {
type: null,
type: opts.type,
value,
});
}
else {
// content:String
// const type = parsePropType(key, opts, null)
properties[key] = createProperty(key, {
type: null, //PROP_TYPES.indexOf(type) !== -1 ? type : null,
type: normalizePropType(),
});
}
});
......@@ -623,7 +608,7 @@ function initTriggerEvent(mpInstance) {
return oldTriggerEvent.apply(mpInstance, [customize(event), ...args]);
};
}
function initHook(name, options) {
function initHook(name, options, isComponent) {
const oldHook = options[name];
if (!oldHook) {
options[name] = function () {
......
import { Plugin } from 'vite'
import initMiniProgramPlugin from '@dcloudio/uni-mp-vite'
import { options } from './options'
const uniMiniProgramWeixinPlugin: Plugin = {
name: 'vite:uni-mp-weixin',
config() {
return {
define: {
__VUE_CREATED_DEFERRED__: false,
},
build: {
// css 中不支持引用本地资源
assetsInlineLimit: 40 * 1024, // 40kb
},
}
},
}
export default [uniMiniProgramWeixinPlugin, ...initMiniProgramPlugin(options)]
import { Plugin } from 'vite'
import { addComponentBindLink, resolveBuiltIn } from '@dcloudio/uni-cli-shared'
import initMiniProgramPlugin, {
UniMiniProgramPluginOptions,
} from '@dcloudio/uni-mp-vite'
import path from 'path'
import source from './project.config.json'
import { addComponentBindLink } from '@dcloudio/uni-cli-shared'
import { UniMiniProgramPluginOptions } from '@dcloudio/uni-mp-vite'
const uniMiniProgramWeixinPlugin: Plugin = {
name: 'vite:uni-mp-weixin',
config() {
return {
define: {
__VUE_CREATED_DEFERRED__: false,
},
build: {
// css 中不支持引用本地资源
assetsInlineLimit: 40 * 1024, // 40kb
},
}
},
}
import source from './project.config.json'
const projectConfigFilename = 'project.config.json'
const options: UniMiniProgramPluginOptions = {
export const options: UniMiniProgramPluginOptions = {
vite: {
inject: {
uni: [
resolveBuiltIn('@dcloudio/uni-mp-weixin/dist/uni.api.esm.js'),
'default',
],
uni: [path.resolve(__dirname, 'uni.api.esm.js'), 'default'],
},
alias: {
'uni-mp-runtime': resolveBuiltIn(
'@dcloudio/uni-mp-weixin/dist/uni.mp.esm.js'
),
'uni-mp-runtime': path.resolve(__dirname, 'uni.mp.esm.js'),
},
copyOptions: {
assets: ['wxcomponents'],
......@@ -65,6 +44,9 @@ const options: UniMiniProgramPluginOptions = {
source,
},
template: {
class: {
array: true,
},
filter: {
extname: '.wxs',
lang: 'wxs',
......@@ -90,5 +72,3 @@ ${filter.code}
extname: '.wxss',
},
}
export default [uniMiniProgramWeixinPlugin, ...initMiniProgramPlugin(options)]
......@@ -386,7 +386,7 @@ function initRefs(instance, mpInstance) {
});
}
// const PROP_TYPES = [String, Number, Boolean, Object, Array, null]
const PROP_TYPES = [String, Number, Boolean, Object, Array, null];
function createObserver(name) {
return function observer(newVal) {
if (this.$vm) {
......@@ -394,25 +394,17 @@ function createObserver(name) {
}
};
}
// function parsePropType(key: string, type: unknown, defaultValue: unknown) {
// // [String]=>String
// if (isArray(type) && type.length === 1) {
// return type[0]
// }
// if ("quickapp-webview" === 'mp-baidu') {
// if (
// // [String,Boolean]=>Boolean
// defaultValue === false &&
// isArray(type) &&
// type.length === 2 &&
// type.indexOf(String) !== -1 &&
// type.indexOf(Boolean) !== -1
// ) {
// return Boolean
// }
// }
// return type
// }
function parsePropType(type, defaultValue) {
// [String]=>String
if (isArray(type) && type.length === 1) {
return type[0];
}
return type;
}
function normalizePropType(type, defaultValue) {
const res = parsePropType(type);
return PROP_TYPES.indexOf(res) !== -1 ? res : null;
}
function initDefaultProps(isBehavior = false) {
const properties = {};
if (!isBehavior) {
......@@ -442,7 +434,7 @@ function createProperty(key, prop) {
return prop;
}
/**
* 不再生成具体的 type 类型,因为微信首次初始化,值为 undefined 时,会告警:property received type-uncompatible value
*
* @param mpComponentOptions
* @param rawProps
* @param isBehavior
......@@ -465,18 +457,17 @@ function initProps(mpComponentOptions, rawProps, isBehavior = false) {
if (isFunction(value)) {
value = value();
}
// const type = (opts as any).type as any
// ;(opts as any).type = parsePropType(key, type, value)
const type = opts.type;
opts.type = normalizePropType(type);
properties[key] = createProperty(key, {
type: null,
type: opts.type,
value,
});
}
else {
// content:String
// const type = parsePropType(key, opts, null)
properties[key] = createProperty(key, {
type: null, //PROP_TYPES.indexOf(type) !== -1 ? type : null,
type: normalizePropType(opts),
});
}
});
......@@ -658,7 +649,7 @@ function initTriggerEvent(mpInstance) {
return oldTriggerEvent.apply(mpInstance, [customize(event), ...args]);
};
}
function initHook(name, options) {
function initHook(name, options, isComponent) {
const oldHook = options[name];
if (!oldHook) {
options[name] = function () {
......@@ -766,36 +757,65 @@ function initInjections(instance) {
}
}
// 基础库 2.0 以上 attached 顺序错乱,按照 created 顺序强制纠正
const components = [];
function initLifetimes$1({ mocks, isPage, initRelation, vueOptions, }) {
return {
created() {
components.push(this);
},
attached() {
const properties = this.properties;
initVueIds(properties.vI, this);
const relationOptions = {
vuePid: this._$vuePid,
this.__lifetimes_attached = function () {
const properties = this.properties;
initVueIds(properties.vI, this);
const relationOptions = {
vuePid: this._$vuePid,
};
// 初始化 vue 实例
const mpInstance = this;
const mpType = isPage(mpInstance) ? 'page' : 'component';
if (mpType === 'page' && !mpInstance.route && mpInstance.__route__) {
mpInstance.route = mpInstance.__route__;
}
// 字节跳动小程序 properties
// 父组件在 attached 中 setData 设置了子组件的 props,在子组件的 attached 中,并不能立刻拿到
// 此时子组件的 properties 中获取到的值,除了一部分初始化就有的值,只要在模板上绑定了,动态设置的 prop 的值均会根据类型返回,不会应用 prop 自己的默认值
// 举例: easyinput 的 styles 属性,类型为 Object,`<easyinput :styles="styles"/>` 在 attached 中 styles 的值为 null
// 目前 null 值会影响 render 函数执行,临时解决方案,调整 properties 中的 null 值为 undefined,让 Vue 来补充为默认值
// 已知的其他隐患,当使用默认值时,可能组件行为不正确,比如 countdown 组件,默认值是0,导致直接就触发了 timeup 事件,这个应该是组件自身做处理?
// 难道要等父组件首次 setData 完成后,再去执行子组件的初始化?
Object.keys(properties).forEach((name) => {
if (properties[name] === null) {
properties[name] = undefined;
}
});
this.$vm = $createComponent({
type: vueOptions,
props: properties,
}, {
mpType,
mpInstance,
slots: properties.vS,
parentComponent: relationOptions.parent && relationOptions.parent.$,
onBeforeSetup(instance, options) {
initRefs(instance, mpInstance);
initMocks(instance, mpInstance, mocks);
initComponentInstance(instance, options);
},
});
// 处理父子关系
initRelation(this, relationOptions);
};
// 初始化 vue 实例
const mpInstance = this;
const mpType = isPage(mpInstance) ? 'page' : 'component';
if (mpType === 'page' && !mpInstance.route && mpInstance.__route__) {
mpInstance.route = mpInstance.__route__;
let component = this;
while (component &&
component.__lifetimes_attached &&
components[0] &&
component === components[0]) {
components.shift();
component.__lifetimes_attached();
delete component.__lifetimes_attached;
component = components[0];
}
this.$vm = $createComponent({
type: vueOptions,
props: properties,
}, {
mpType,
mpInstance,
slots: properties.vS,
parentComponent: relationOptions.parent && relationOptions.parent.$,
onBeforeSetup(instance, options) {
initRefs(instance, mpInstance);
initMocks(instance, mpInstance, mocks);
initComponentInstance(instance, options);
},
});
// 处理父子关系
initRelation(this, relationOptions);
},
detached() {
this.$vm && $destroyComponent(this.$vm);
......
'use strict';
var version = "3.0.0-alpha-3021020211025001";
var version = "3.0.0-alpha-3021020211027001";
const STAT_VERSION = version;
const STAT_URL = 'https://tongji.dcloud.io/uni/stat';
......
var version = "3.0.0-alpha-3021020211025001";
var version = "3.0.0-alpha-3021020211027001";
const STAT_VERSION = version;
const STAT_URL = 'https://tongji.dcloud.io/uni/stat';
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册