Skip to content

Commit

Permalink
Merge branch 'master' into perf_ts_define
Browse files Browse the repository at this point in the history
  • Loading branch information
hiyuki authored Dec 13, 2023
2 parents bf7cb5c + 17f424e commit 17bcf0b
Show file tree
Hide file tree
Showing 11 changed files with 187 additions and 95 deletions.
2 changes: 1 addition & 1 deletion lerna.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
"packages": [
"packages/*"
],
"version": "2.9.7"
"version": "2.9.8"
}
59 changes: 26 additions & 33 deletions packages/core/@types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,30 +24,33 @@ type UnionToIntersection<U> = (U extends any
? (k: U) => void
: never) extends ((k: infer I) => void)
? I
: never;
: never

type ArrayType<T extends any[]> = T extends Array<infer R> ? R : never;
type ArrayType<T extends any[]> = T extends Array<infer R> ? R : never

// Mpx types
type Data = object | (() => object)

export type PropType<T> = T & (
T extends string
export type PropType<T> = {
__type: T
} & (
T extends String
? StringConstructor
: T extends number
: T extends number
? NumberConstructor
: T extends boolean
? BooleanConstructor
: T extends any[]
? ArrayConstructor
: T extends object
: T extends object
? ObjectConstructor
: never )
: never
)

type FullPropType<T> = {
type: PropType<T>;
value?: T;
optionalTypes?: PropType<T>[];
type: PropType<T>
value?: T
optionalTypes?: WechatMiniprogram.Component.ShortProperty[]
}

interface Properties {
Expand Down Expand Up @@ -80,27 +83,17 @@ interface WatchField {

type GetDataType<T> = T extends () => any ? ReturnType<T> : T

type PropValueType<Def> = Def extends FullPropType<infer T>
? T
: Def extends PropType<infer T>
? T
: Def extends {
type: (...args: any[]) => infer T;
optionalType?: ((...args: any[]) => infer T)[];
value?: infer T;
}
? T
: Def extends (...args: any[]) => infer T
? T
: any;

type GetPropsType<T> = {
readonly [K in keyof T]: PropValueType<T[K]>
type GetPropsType<T extends Properties> = {
readonly [K in keyof T]: T[K] extends FullPropType<infer V>
? V
: T[K] extends PropType<infer V>
? V
: WechatMiniprogram.Component.PropertyToData<T[K]>
}

type RequiredPropertyNames<T> = {
[K in keyof T]-?: T[K] extends undefined ? never : K
}[keyof T];
}[keyof T]

type RequiredPropertiesForUnion<T> = T extends object ? Pick<T, RequiredPropertyNames<T>> : never

Expand Down Expand Up @@ -131,7 +124,7 @@ interface Context {
createIntersectionObserver: WechatMiniprogram.Component.InstanceMethods<Record<string, any>>['createIntersectionObserver']
}

interface ComponentOpt<D, P, C, M, Mi extends Array<any>, S extends Record<any, any>> extends Partial<WechatMiniprogram.Component.Lifetimes & WechatMiniprogram.Component.OtherOption> {
interface ComponentOpt<D extends Data, P extends Properties, C, M extends Methods, Mi extends Array<any>, S extends Record<any, any>> extends Partial<WechatMiniprogram.Component.Lifetimes & WechatMiniprogram.Component.OtherOption> {
data?: D
properties?: P
computed?: C
Expand All @@ -149,7 +142,7 @@ interface ComponentOpt<D, P, C, M, Mi extends Array<any>, S extends Record<any,
[index: string]: any
}

type PageOpt<D, P, C, M, Mi extends Array<any>, S extends Record<any, any>> =
type PageOpt<D extends Data, P extends Properties, C, M extends Methods, Mi extends Array<any>, S extends Record<any, any>> =
ComponentOpt<D, P, C, M, Mi, S>
& Partial<WechatMiniprogram.Page.ILifetime>

Expand Down Expand Up @@ -286,11 +279,11 @@ interface ImplementOptions {

export function toPureObject<T extends object> (obj: T): T

declare type PluginInstallFunction = (app: Mpx, ...options: any[]) => any;
declare type PluginInstallFunction = (app: Mpx, ...options: any[]) => any

export type Plugin = PluginInstallFunction | {
install: PluginInstallFunction;
};
install: PluginInstallFunction
}

export type PluginFunction<T extends Plugin> = T extends PluginInstallFunction ? T : T extends { install: infer U } ? U : never;

Expand Down Expand Up @@ -679,7 +672,7 @@ export const ONHIDE: string
export const ONRESIZE: string

declare global {
const defineProps: (<T>(props: T) => Readonly<GetPropsType<T>>) & (<T>() => Readonly<T>)
const defineProps: (<T extends Properties = {}>(props: T) => Readonly<GetPropsType<T>>) & (<T>() => Readonly<T>)
const defineOptions: <D extends Data = {}, P extends Properties = {}, C = {}, M extends Methods = {}, Mi extends Array<any> = [], S extends AnyObject = {}, O extends AnyObject = {}> (opt: ThisTypedComponentOpt<D, P, C, M, Mi, S, O>) => void
const defineExpose: <E extends AnyObject = AnyObject>(exposed?: E) => void
const useContext: () => Context
Expand Down
1 change: 0 additions & 1 deletion packages/store/@types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ type UnboxDepField<D, F> = F extends keyof D ? D[F] : {}
type GetReturnOrSelf<T> = T extends (...args: any)=> infer R ? R : T

interface compContext {
__mpxProxy: object;
[key: string]: any
}

Expand Down
81 changes: 46 additions & 35 deletions packages/webpack-plugin/lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ const EntryPlugin = require('webpack/lib/EntryPlugin')
const JavascriptModulesPlugin = require('webpack/lib/javascript/JavascriptModulesPlugin')
const FlagEntryExportAsUsedPlugin = require('webpack/lib/FlagEntryExportAsUsedPlugin')
const FileSystemInfo = require('webpack/lib/FileSystemInfo')
const ImportDependency = require('webpack/lib/dependencies/ImportDependency')
const AsyncDependenciesBlock = require('webpack/lib/AsyncDependenciesBlock')
const normalize = require('./utils/normalize')
const toPosix = require('./utils/to-posix')
const addQuery = require('./utils/add-query')
Expand Down Expand Up @@ -325,36 +327,31 @@ class MpxWebpackPlugin {
compiler.options.resolve.plugins.push(packageEntryPlugin)
compiler.options.resolve.plugins.push(new FixDescriptionInfoPlugin())

let splitChunksPlugin
let splitChunksOptions

if (this.options.mode !== 'web') {
const optimization = compiler.options.optimization
optimization.runtimeChunk = {
name: (entrypoint) => {
for (const packageName in mpx.independentSubpackagesMap) {
if (hasOwn(mpx.independentSubpackagesMap, packageName) && isChunkInPackage(entrypoint.name, packageName)) {
return `${packageName}/bundle`
}
const optimization = compiler.options.optimization
optimization.runtimeChunk = {
name: (entrypoint) => {
for (const packageName in mpx.independentSubpackagesMap) {
if (hasOwn(mpx.independentSubpackagesMap, packageName) && isChunkInPackage(entrypoint.name, packageName)) {
return `${packageName}/bundle`
}
return 'bundle'
}
return 'bundle'
}
splitChunksOptions = Object.assign({
defaultSizeTypes: ['javascript', 'unknown'],
chunks: 'all',
usedExports: optimization.usedExports === true,
minChunks: 1,
minSize: 1000,
enforceSizeThreshold: Infinity,
maxAsyncRequests: 30,
maxInitialRequests: 30,
automaticNameDelimiter: '-'
}, optimization.splitChunks)
delete optimization.splitChunks
splitChunksPlugin = new SplitChunksPlugin(splitChunksOptions)
splitChunksPlugin.apply(compiler)
}
const splitChunksOptions = Object.assign({
defaultSizeTypes: ['javascript', 'unknown'],
chunks: 'all',
usedExports: optimization.usedExports === true,
minChunks: 1,
minSize: 1000,
enforceSizeThreshold: Infinity,
maxAsyncRequests: 30,
maxInitialRequests: 30,
automaticNameDelimiter: '-'
}, optimization.splitChunks)
delete optimization.splitChunks
const splitChunksPlugin = new SplitChunksPlugin(splitChunksOptions)
splitChunksPlugin.apply(compiler)

// 代理writeFile
if (this.options.writeMode === 'changed') {
Expand Down Expand Up @@ -635,7 +632,7 @@ class MpxWebpackPlugin {
useRelativePath: this.options.useRelativePath,
removedChunks: [],
forceProxyEventRules: this.options.forceProxyEventRules,
enableRequireAsync: this.options.mode === 'wx' || (this.options.mode === 'ali' && this.options.enableAliRequireAsync),
supportRequireAsync: this.options.mode === 'wx' || this.options.mode === 'web' || (this.options.mode === 'ali' && this.options.enableAliRequireAsync),
partialCompile: this.options.partialCompile,
collectDynamicEntryInfo: ({ resource, packageName, filename, entryType }) => {
const curInfo = mpx.dynamicEntryInfo[packageName] = mpx.dynamicEntryInfo[packageName] || {
Expand Down Expand Up @@ -1093,15 +1090,29 @@ class MpxWebpackPlugin {
// 删除root query
if (queryObj.root) request = addQuery(request, {}, false, ['root'])
// 目前仅wx和ali支持require.async,ali需要开启enableAliRequireAsync,其余平台使用CommonJsAsyncDependency进行模拟抹平
if (mpx.enableRequireAsync) {
const dep = new DynamicEntryDependency(request, 'export', '', tarRoot, '', context, range, {
isRequireAsync: true,
retryRequireAsync: !!this.options.retryRequireAsync
})
if (mpx.supportRequireAsync) {
if (mpx.mode === 'web') {
const depBlock = new AsyncDependenciesBlock(
{
name: tarRoot
},
expr.loc,
request
)
const dep = new ImportDependency(request, expr.range)
dep.loc = expr.loc
depBlock.addDependency(dep)
parser.state.current.addBlock(depBlock)
} else {
const dep = new DynamicEntryDependency(request, 'export', '', tarRoot, '', context, range, {
isRequireAsync: true,
retryRequireAsync: !!this.options.retryRequireAsync
})

parser.state.current.addPresentationalDependency(dep)
// 包含require.async的模块不能被concatenate,避免DynamicEntryDependency中无法获取模块chunk以计算相对路径
parser.state.module.buildInfo.moduleConcatenationBailout = 'require async'
parser.state.current.addPresentationalDependency(dep)
// 包含require.async的模块不能被concatenate,避免DynamicEntryDependency中无法获取模块chunk以计算相对路径
parser.state.module.buildInfo.moduleConcatenationBailout = 'require async'
}
} else {
const range = expr.range
const dep = new CommonJsAsyncDependency(request, range)
Expand Down
13 changes: 8 additions & 5 deletions packages/webpack-plugin/lib/json-compiler/helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ module.exports = function createJSONHelper ({ loaderContext, emitWarning, custom
const pathHash = mpx.pathHash
const getOutputPath = mpx.getOutputPath
const mode = mpx.mode
const enableRequireAsync = mpx.enableRequireAsync
const supportRequireAsync = mpx.supportRequireAsync
const asyncSubpackageRules = mpx.asyncSubpackageRules

const isUrlRequest = r => isUrlRequestRaw(r, root, externals)
Expand Down Expand Up @@ -51,15 +51,15 @@ module.exports = function createJSONHelper ({ loaderContext, emitWarning, custom
resolve(context, component, loaderContext, (err, resource, info) => {
if (err) return callback(err)
const { resourcePath, queryObj } = parseRequest(resource)
let placeholder = null
let placeholder = ''
if (queryObj.root) {
// 删除root query
resource = addQuery(resource, {}, false, ['root'])
// 目前只有微信支持分包异步化
if (enableRequireAsync) {
if (supportRequireAsync) {
tarRoot = queryObj.root
}
} else if (!queryObj.root && asyncSubpackageRules && enableRequireAsync) {
} else if (!queryObj.root && asyncSubpackageRules && supportRequireAsync) {
for (const item of asyncSubpackageRules) {
if (matchCondition(resourcePath, item)) {
tarRoot = item.root
Expand Down Expand Up @@ -97,7 +97,10 @@ module.exports = function createJSONHelper ({ loaderContext, emitWarning, custom
}

const entry = getDynamicEntry(resource, 'component', outputPath, tarRoot, relativePath)
callback(null, entry, tarRoot, placeholder)
callback(null, entry, {
tarRoot,
placeholder
})
})
}

Expand Down
4 changes: 2 additions & 2 deletions packages/webpack-plugin/lib/json-compiler/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -211,14 +211,14 @@ module.exports = function (content) {
const processComponents = (components, context, callback) => {
if (components) {
async.eachOf(components, (component, name, callback) => {
processComponent(component, context, { relativePath }, (err, entry, root, placeholder) => {
processComponent(component, context, { relativePath }, (err, entry, { tarRoot, placeholder } = {}) => {
if (err === RESOLVE_IGNORED_ERR) {
delete components[name]
return callback()
}
if (err) return callback(err)
components[name] = entry
if (root) {
if (tarRoot) {
if (placeholder) {
placeholder = normalizePlaceholder(placeholder)
if (placeholder.resource) {
Expand Down
30 changes: 22 additions & 8 deletions packages/webpack-plugin/lib/template-compiler/bind-this.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,12 +96,11 @@ function checkDelAndGetPath (path) {
} else {
delPath = current.parentPath
}
} else if (t.isLogicalExpression(current.container)) { // case: a || ''
} else if (t.isLogicalExpression(current.container)) { // 只处理case: a || '' or '123' || a
const key = current.key === 'left' ? 'right' : 'left'
if (t.isLiteral(current.parent[key])) {
delPath = current.parentPath
} else {
canDel = false
break
}
} else if (current.key === 'expression' && t.isExpressionStatement(current.parentPath)) { // dealRemove删除节点时需要
Expand All @@ -116,11 +115,23 @@ function checkDelAndGetPath (path) {
// 确定是否可删除
while (!t.isBlockStatement(current) && canDel) {
const { key, container } = current
if (t.isIfStatement(container) && key === 'test') { // if (a) {}
canDel = false
break
}

if (t.isLogicalExpression(container)) { // case: a || ((b || c) && d)
ignore = true
break
}

// case: a ??= b
if (
t.isLogicalExpression(container) || // a && b
(t.isIfStatement(container) && key === 'test') // if (a) {}
key === 'right' &&
t.isAssignmentExpression(container) &&
['??=', '||=', '&&='].includes(container.operator)
) {
canDel = false
ignore = true
break
}

Expand Down Expand Up @@ -166,13 +177,16 @@ function dealRemove (path, replace) {
if (replace) {
path.replaceWith(t.stringLiteral(''))
} else {
t.validate(path, path.key, null)
if (path.inList) {
t.validate(path.parent, path.key, [null])
} else {
t.validate(path.parent, path.key, null)
}
path.remove()
}
delete path.needBind
delete path.collectInfo
} catch (e) {
}
} catch (e) {}
}

module.exports = {
Expand Down
7 changes: 4 additions & 3 deletions packages/webpack-plugin/lib/web/processJSON.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ module.exports = function (json, {
customGetDynamicEntry (resource, type, outputPath, packageRoot) {
return {
resource,
outputPath: toPosix(path.join(packageRoot, outputPath)),
// 输出web时组件outputPath不需要拼接packageRoot
outputPath: type === 'page' ? toPosix(path.join(packageRoot, outputPath)) : outputPath,
packageRoot
}
}
Expand Down Expand Up @@ -297,7 +298,7 @@ module.exports = function (json, {
const processComponents = (components, context, callback) => {
if (components) {
async.eachOf(components, (component, name, callback) => {
processComponent(component, context, {}, (err, { resource, outputPath } = {}) => {
processComponent(component, context, {}, (err, { resource, outputPath } = {}, { tarRoot } = {}) => {
if (err) return callback(err === RESOLVE_IGNORED_ERR ? null : err)
const { resourcePath, queryObj } = parseRequest(resource)
componentsMap[resourcePath] = outputPath
Expand All @@ -307,7 +308,7 @@ module.exports = function (json, {
isComponent: true,
outputPath
}),
async: queryObj.async
async: queryObj.async || tarRoot
}
callback()
})
Expand Down
Loading

0 comments on commit 17bcf0b

Please sign in to comment.