Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Velpro187
uni-app
提交
05995c97
U
uni-app
项目概览
Velpro187
/
uni-app
与 Fork 源项目一致
Fork自
DCloud / uni-app
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
U
uni-app
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
05995c97
编写于
10月 18, 2021
作者:
fxy060608
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
wip(mp): usingComponents
上级
e858f31c
变更
23
隐藏空白更改
内联
并排
Showing
23 changed file
with
773 addition
and
136 deletion
+773
-136
packages/uni-cli-shared/__tests__/transformImports.spec.ts
packages/uni-cli-shared/__tests__/transformImports.spec.ts
+194
-0
packages/uni-cli-shared/src/constants.ts
packages/uni-cli-shared/src/constants.ts
+1
-0
packages/uni-cli-shared/src/json/app/pages/nvue.ts
packages/uni-cli-shared/src/json/app/pages/nvue.ts
+1
-1
packages/uni-cli-shared/src/json/mp/index.ts
packages/uni-cli-shared/src/json/mp/index.ts
+1
-0
packages/uni-cli-shared/src/json/mp/jsonFile.ts
packages/uni-cli-shared/src/json/mp/jsonFile.ts
+52
-6
packages/uni-cli-shared/src/mp/index.ts
packages/uni-cli-shared/src/mp/index.ts
+1
-1
packages/uni-cli-shared/src/mp/transformImports.ts
packages/uni-cli-shared/src/mp/transformImports.ts
+196
-0
packages/uni-cli-shared/src/utils.ts
packages/uni-cli-shared/src/utils.ts
+36
-6
packages/uni-mp-compiler/__tests__/transformElement.spec.ts
packages/uni-mp-compiler/__tests__/transformElement.spec.ts
+33
-5
packages/uni-mp-compiler/__tests__/vShow.spec.ts
packages/uni-mp-compiler/__tests__/vShow.spec.ts
+13
-0
packages/uni-mp-compiler/__tests__/vSlot.spec.ts
packages/uni-mp-compiler/__tests__/vSlot.spec.ts
+32
-0
packages/uni-mp-compiler/src/codegen.ts
packages/uni-mp-compiler/src/codegen.ts
+50
-10
packages/uni-mp-compiler/src/template/codegen.ts
packages/uni-mp-compiler/src/template/codegen.ts
+21
-4
packages/uni-mp-compiler/src/transform.ts
packages/uni-mp-compiler/src/transform.ts
+8
-0
packages/uni-mp-vite/src/index.ts
packages/uni-mp-vite/src/index.ts
+9
-4
packages/uni-mp-vite/src/plugin/build.ts
packages/uni-mp-vite/src/plugin/build.ts
+1
-1
packages/uni-mp-vite/src/plugins/component.ts
packages/uni-mp-vite/src/plugins/component.ts
+0
-42
packages/uni-mp-vite/src/plugins/entry.ts
packages/uni-mp-vite/src/plugins/entry.ts
+11
-2
packages/uni-mp-vite/src/plugins/pagesJson.ts
packages/uni-mp-vite/src/plugins/pagesJson.ts
+27
-22
packages/uni-mp-vite/src/plugins/usingComponents.ts
packages/uni-mp-vite/src/plugins/usingComponents.ts
+54
-0
packages/vite-plugin-uni/src/index.ts
packages/vite-plugin-uni/src/index.ts
+2
-1
packages/vite-plugin-uni/src/utils/plugin.ts
packages/vite-plugin-uni/src/utils/plugin.ts
+28
-7
packages/vite-plugin-uni/src/vue/options.ts
packages/vite-plugin-uni/src/vue/options.ts
+2
-24
未找到文件。
packages/uni-cli-shared/__tests__/transformImports.spec.ts
0 → 100644
浏览文件 @
05995c97
import
path
from
'
path
'
import
{
ResolvedId
}
from
'
rollup
'
import
{
transformVueComponentImports
}
from
'
../src/mp/transformImports
'
const
root
=
'
/usr/xxx/projects/test/src
'
const
importer
=
'
/usr/xxx/projects/test/src/pages/index/index.vue
'
async
function
resolve
(
id
:
string
,
importer
?:
string
)
{
return
{
id
:
importer
?
path
.
resolve
(
path
.
dirname
(
importer
),
id
)
:
id
,
}
as
ResolvedId
}
function
dynamicImport
(
name
:
string
,
source
:
string
)
{
return
`const
${
name
}
= ()=>import('
${
source
}
')`
}
describe
(
'
transformVueComponentImports
'
,
()
=>
{
test
(
`basic`
,
async
()
=>
{
const
source
=
`import test1 from "
${
root
}
/components/test1.vue";
const _sfc_main = {
components: {
test1
}
};
const __BINDING_COMPONENTS__ = '{"test1":{"name":"_component_test1","type":"unknown"}}';
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
return {};
}
import "
${
importer
}
?vue&type=style&index=0&lang.css";
import _export_sfc from "plugin-vue:export-helper";
export default /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render]]);
`
const
{
code
,
usingComponents
}
=
await
transformVueComponentImports
(
source
,
importer
,
{
root
,
resolve
,
dynamicImport
,
}
)
expect
(
code
).
toContain
(
`const test1 = ()=>import('
${
root
}
/components/test1.vue')`
)
expect
(
usingComponents
).
toMatchObject
({
test1
:
'
/components/test1
'
})
})
test
(
`easycom`
,
async
()
=>
{
const
source
=
`import test1 from "../../components/test1.vue";
import MyComponentName from "../../components/test1.vue";
const _sfc_main = {
components: {
test1,
MyComponentName
}
};
const __BINDING_COMPONENTS__ = '{"test":{"name":"_easycom_test","type":"unknown"},"test1":{"name":"_component_test1","type":"unknown"},"MyComponentName":{"name":"_component_MyComponentName","type":"unknown"},"my-component-name":{"name":"_component_my_component_name","type":"unknown"}}';
import _easycom_test from "
${
root
}
/components/test/test.vue";
if (!Math) {
Math.max.call(Max, _easycom_test);
}
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
return {};
}
import "
${
root
}
/pages/index/index.vue?vue&type=style&index=0&lang.css";
import _export_sfc from "plugin-vue:export-helper";
export default /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render]]);
`
const
{
code
,
usingComponents
}
=
await
transformVueComponentImports
(
source
,
importer
,
{
root
,
resolve
,
dynamicImport
,
}
)
expect
(
code
).
toContain
(
`const _easycom_test = ()=>import('
${
root
}
/components/test/test.vue')`
)
expect
(
usingComponents
).
toMatchObject
({
test
:
'
/components/test/test
'
,
test1
:
'
/components/test1
'
,
'
my-component-name
'
:
'
/components/test1
'
,
})
})
test
(
`PascalCase`
,
async
()
=>
{
const
source
=
`import test1 from "../../components/test1.vue";
import MyComponentName from "../../components/test1.vue";
const _sfc_main = {
components: {
test1,
MyComponentName
}
};
const __BINDING_COMPONENTS__ = '{"test1":{"name":"_component_test1","type":"unknown"},"MyComponentName":{"name":"_component_MyComponentName","type":"unknown"},"my-component-name":{"name":"_component_my_component_name","type":"unknown"}}';
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
return {};
}
import "
${
root
}
/pages/index/index.vue?vue&type=style&index=0&lang.css";
import _export_sfc from "plugin-vue:export-helper";
export default /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render]]);
`
const
{
code
,
usingComponents
}
=
await
transformVueComponentImports
(
source
,
importer
,
{
root
,
resolve
,
dynamicImport
,
}
)
expect
(
code
).
toContain
(
`const MyComponentName = ()=>import('
${
root
}
/components/test1.vue')`
)
expect
(
usingComponents
).
toMatchObject
({
test1
:
'
/components/test1
'
,
'
my-component-name
'
:
'
/components/test1
'
,
})
})
test
(
`setup`
,
async
()
=>
{
const
source
=
`import { defineComponent as _defineComponent } from "vue";
const __BINDING_COMPONENTS__ = '{"test1":{"name":"test1","type":"setup"},"MyComponentName":{"name":"MyComponentName","type":"setup"},"my-component-name":{"name":"MyComponentName","type":"setup"}}';
if (!Math) {
Math.max.call(Max, test1, MyComponentName, MyComponentName);
}
import test1 from "../../components/test1.vue";
import MyComponentName from "../../components/test1.vue";
const _sfc_main = /* @__PURE__ */ _defineComponent({
setup(__props) {
return (_ctx, _cache) => {
return {};
};
}
});
import "
${
root
}
/pages/index/index.vue?vue&type=style&index=0&lang.css";
export default _sfc_main;
`
const
{
code
,
usingComponents
}
=
await
transformVueComponentImports
(
source
,
importer
,
{
root
,
resolve
,
dynamicImport
,
}
)
expect
(
code
).
toContain
(
`const MyComponentName = ()=>import('
${
root
}
/components/test1.vue')`
)
expect
(
usingComponents
).
toMatchObject
({
test1
:
'
/components/test1
'
,
'
my-component-name
'
:
'
/components/test1
'
,
})
})
test
(
`setup with easycom`
,
async
()
=>
{
const
source
=
`import { defineComponent as _defineComponent } from "vue";
const __BINDING_COMPONENTS__ = '{"test":{"name":"_easycom_test","type":"unknown"},"test1":{"name":"test1","type":"setup"},"MyComponentName":{"name":"MyComponentName","type":"setup"},"my-component-name":{"name":"MyComponentName","type":"setup"}}';
import _easycom_test from "
${
root
}
/components/test/test.vue";
if (!Math) {
Math.max.call(Max, _easycom_test, test1, MyComponentName, MyComponentName);
}
import test1 from "../../components/test1.vue";
import MyComponentName from "../../components/test1.vue";
const _sfc_main = /* @__PURE__ */ _defineComponent({
setup(__props) {
return (_ctx, _cache) => {
return {};
};
}
});
import "
${
root
}
/pages/index/index.vue?vue&type=style&index=0&lang.css";
export default _sfc_main;
`
const
{
code
,
usingComponents
}
=
await
transformVueComponentImports
(
source
,
importer
,
{
root
,
resolve
,
dynamicImport
,
}
)
expect
(
code
).
toContain
(
`const _easycom_test = ()=>import('
${
root
}
/components/test/test.vue')`
)
expect
(
usingComponents
).
toMatchObject
({
test
:
'
/components/test/test
'
,
test1
:
'
/components/test1
'
,
'
my-component-name
'
:
'
/components/test1
'
,
})
})
})
packages/uni-cli-shared/src/constants.ts
浏览文件 @
05995c97
...
...
@@ -4,6 +4,7 @@ export const EXTNAME_VUE = ['.vue', '.nvue']
export
const
EXTNAME_VUE_RE
=
/
\.(
vue|nvue
)
$/
export
const
EXTNAME_JS_RE
=
/
\.[
jt
]
sx
?
$/
export
const
BINDING_COMPONENTS
=
'
__BINDING_COMPONENTS__
'
// APP 平台解析页面后缀的优先级
export
const
PAGE_EXTNAME_APP
=
[
'
.nvue
'
,
'
.vue
'
,
'
.tsx
'
,
'
.jsx
'
,
'
.js
'
]
// 其他平台解析页面后缀的优先级
...
...
packages/uni-cli-shared/src/json/app/pages/nvue.ts
浏览文件 @
05995c97
...
...
@@ -17,7 +17,7 @@ export function initWebpackNVueEntry(pages: UniApp.PagesJsonPageOptions[]) {
if
(
!
path
)
{
return
}
const
subNVuePath
=
removeExt
(
path
.
split
(
'
?
'
)[
0
]
)
const
subNVuePath
=
removeExt
(
normalizePath
(
path
.
split
(
'
?
'
)[
0
])
)
process
.
UNI_NVUE_ENTRY
[
subNVuePath
]
=
genWebpackBase64Code
(
genNVueEntryCode
(
subNVuePath
)
)
...
...
packages/uni-cli-shared/src/json/mp/index.ts
浏览文件 @
05995c97
export
*
from
'
./jsonFile
'
export
{
AppJson
}
from
'
./types
'
export
{
parseMiniProgramPagesJson
}
from
'
./pages
'
export
{
parseMiniProgramProjectJson
}
from
'
./project
'
packages/uni-cli-shared/src/json/mp/jsonFile.ts
浏览文件 @
05995c97
import
{
extend
}
from
'
@vue/shared
'
import
{
ComponentJson
,
PageWindowOptions
,
UsingComponents
}
from
'
./types
'
import
{
normalizeNodeModules
}
from
'
../../utils
'
export
const
jsonPagesCache
=
new
Map
<
string
,
PageWindowOptions
>
()
export
const
jsonComponentsCache
=
new
Map
<
string
,
ComponentJson
>
()
export
const
jsonUsingComponentsCache
=
new
Map
<
string
,
UsingComponents
>
()
let
appJsonCache
:
Record
<
string
,
any
>
=
{}
const
jsonFilesCache
=
new
Map
<
string
,
string
>
()
const
jsonPagesCache
=
new
Map
<
string
,
PageWindowOptions
>
()
const
jsonComponentsCache
=
new
Map
<
string
,
ComponentJson
>
()
const
jsonUsingComponentsCache
=
new
Map
<
string
,
UsingComponents
>
()
export
function
addPageJson
(
filename
:
string
,
json
:
PageWindowOptions
)
{
export
function
normalizeJsonFilename
(
filename
:
string
)
{
return
normalizeNodeModules
(
filename
)
}
export
function
findChangedJsonFiles
()
{
const
changedJsonFiles
=
new
Map
<
string
,
string
>
()
function
findChangedFile
(
name
:
string
,
json
:
Record
<
string
,
any
>
)
{
const
newJson
=
extend
({},
json
)
if
(
!
newJson
.
usingComponents
)
{
newJson
.
usingComponents
=
{}
}
extend
(
newJson
.
usingComponents
,
jsonUsingComponentsCache
.
get
(
name
))
const
jsonStr
=
JSON
.
stringify
(
newJson
,
null
,
2
)
if
(
jsonFilesCache
.
get
(
name
)
!==
jsonStr
)
{
changedJsonFiles
.
set
(
name
,
jsonStr
)
jsonFilesCache
.
set
(
name
,
jsonStr
)
}
}
function
findChangedFiles
(
jsonsCache
:
Map
<
string
,
any
>
)
{
for
(
const
name
of
jsonsCache
.
keys
())
{
findChangedFile
(
name
,
jsonsCache
.
get
(
name
))
}
}
findChangedFile
(
'
app
'
,
appJsonCache
)
findChangedFiles
(
jsonPagesCache
)
findChangedFiles
(
jsonComponentsCache
)
return
changedJsonFiles
}
export
function
addMiniProgramAppJson
(
appJson
:
Record
<
string
,
any
>
)
{
appJsonCache
=
appJson
}
export
function
addMiniProgramPageJson
(
filename
:
string
,
json
:
PageWindowOptions
)
{
jsonPagesCache
.
set
(
filename
,
json
)
}
export
function
addComponentJson
(
filename
:
string
,
json
:
ComponentJson
)
{
export
function
addMiniProgramComponentJson
(
filename
:
string
,
json
:
ComponentJson
)
{
jsonComponentsCache
.
set
(
filename
,
json
)
}
export
function
addUsingComponents
(
filename
:
string
,
json
:
UsingComponents
)
{
export
function
addMiniProgramUsingComponents
(
filename
:
string
,
json
:
UsingComponents
)
{
jsonUsingComponentsCache
.
set
(
filename
,
json
)
}
packages/uni-cli-shared/src/mp/index.ts
浏览文件 @
05995c97
export
*
from
'
./event
'
export
{
findVueComponentImports
}
from
'
./i
mports
'
export
{
transformVueComponentImports
}
from
'
./transformI
mports
'
packages/uni-cli-shared/src/mp/transformImports.ts
0 → 100644
浏览文件 @
05995c97
import
{
parse
,
ParserPlugin
}
from
'
@babel/parser
'
import
{
ImportDeclaration
,
isIdentifier
,
isImportDeclaration
,
isObjectExpression
,
isObjectProperty
,
isStringLiteral
,
isVariableDeclaration
,
ObjectProperty
,
Program
,
Statement
,
StringLiteral
,
}
from
'
@babel/types
'
import
{
camelize
,
capitalize
,
hyphenate
}
from
'
@vue/shared
'
import
{
walk
}
from
'
estree-walker
'
import
MagicString
from
'
magic-string
'
import
{
PluginContext
}
from
'
rollup
'
import
{
BINDING_COMPONENTS
}
from
'
../constants
'
import
{
normalizeMiniProgramFilename
,
removeExt
}
from
'
../utils
'
interface
TransformVueComponentImportsOptions
{
root
:
string
resolve
:
PluginContext
[
'
resolve
'
]
dynamicImport
:
(
name
:
string
,
source
:
string
)
=>
string
babelParserPlugins
?:
ParserPlugin
[]
}
export
async
function
transformVueComponentImports
(
code
:
string
,
importer
:
string
,
{
root
,
resolve
,
dynamicImport
,
babelParserPlugins
,
}:
TransformVueComponentImportsOptions
):
Promise
<
{
code
:
string
usingComponents
:
Record
<
string
,
string
>
}
>
{
if
(
!
code
.
includes
(
BINDING_COMPONENTS
))
{
return
{
code
,
usingComponents
:
{}
}
}
const
s
=
new
MagicString
(
code
)
const
scriptAst
=
parse
(
code
,
{
plugins
:
[...(
babelParserPlugins
||
[])],
sourceType
:
'
module
'
,
}).
program
const
imports
=
findVueComponentImports
(
scriptAst
.
body
,
parseComponents
(
scriptAst
,
findBindingComponents
(
scriptAst
.
body
))
)
const
usingComponents
:
Record
<
string
,
string
>
=
{}
for
(
let
i
=
0
;
i
<
imports
.
length
;
i
++
)
{
const
{
tag
,
import
:
{
start
,
end
,
specifiers
:
[
specifier
],
source
,
},
}
=
imports
[
i
]
const
resolveId
=
await
resolve
(
source
.
value
,
importer
)
if
(
resolveId
)
{
s
.
overwrite
(
start
!
,
end
!
,
dynamicImport
(
specifier
.
local
.
name
,
resolveId
.
id
)
+
'
;
'
)
const
componentName
=
hyphenate
(
tag
)
if
(
!
usingComponents
[
componentName
])
{
usingComponents
[
componentName
]
=
'
/
'
+
removeExt
(
normalizeMiniProgramFilename
(
resolveId
.
id
,
root
))
}
}
}
return
{
code
:
s
.
toString
(),
usingComponents
}
}
type
BindingComponents
=
Record
<
string
,
{
tag
:
string
;
type
:
'
unknown
'
|
'
setup
'
|
'
self
'
}
>
/**
* 解析编译器生成的 bindingComponents
* @param ast
* @returns
*/
function
findBindingComponents
(
ast
:
Statement
[]):
BindingComponents
{
for
(
const
node
of
ast
)
{
if
(
!
isVariableDeclaration
(
node
))
{
continue
}
const
declarator
=
node
.
declarations
[
0
]
if
(
isIdentifier
(
declarator
.
id
)
&&
declarator
.
id
.
name
===
BINDING_COMPONENTS
)
{
const
bindingComponents
=
JSON
.
parse
(
(
declarator
.
init
as
StringLiteral
).
value
)
as
Record
<
string
,
{
name
:
string
;
type
:
'
unknown
'
|
'
setup
'
|
'
self
'
}
>
return
Object
.
keys
(
bindingComponents
).
reduce
<
BindingComponents
>
(
(
bindings
,
tag
)
=>
{
const
binding
=
bindingComponents
[
tag
]
bindings
[
binding
.
name
]
=
{
tag
,
type
:
binding
.
type
,
}
return
bindings
},
{}
)
}
}
return
{}
}
/**
* 从 components 中查找定义的组件,修改 bindingComponents
* @param ast
* @param bindingComponents
*/
function
parseComponents
(
ast
:
Program
,
bindingComponents
:
BindingComponents
)
{
;(
walk
as
any
)(
ast
,
{
enter
(
child
:
Node
)
{
if
(
!
isObjectExpression
(
child
))
{
return
}
const
componentsProp
=
child
.
properties
.
find
(
(
prop
)
=>
isObjectProperty
(
prop
)
&&
isIdentifier
(
prop
.
key
)
&&
prop
.
key
.
name
===
'
components
'
)
as
ObjectProperty
if
(
!
componentsProp
)
{
return
}
const
componentsExpr
=
componentsProp
.
value
if
(
!
isObjectExpression
(
componentsExpr
))
{
return
}
componentsExpr
.
properties
.
forEach
((
prop
)
=>
{
if
(
!
isObjectProperty
(
prop
))
{
return
}
if
(
!
isIdentifier
(
prop
.
key
)
&&
!
isStringLiteral
(
prop
.
key
))
{
return
}
if
(
!
isIdentifier
(
prop
.
value
))
{
return
}
const
tag
=
isIdentifier
(
prop
.
key
)
?
prop
.
key
.
name
:
prop
.
key
.
value
const
name
=
findBindingComponent
(
tag
,
bindingComponents
)
if
(
name
)
{
bindingComponents
[
prop
.
value
.
name
]
=
bindingComponents
[
name
]
}
})
},
})
return
bindingComponents
}
function
findBindingComponent
(
tag
:
string
,
bindingComponents
:
BindingComponents
)
{
return
Object
.
keys
(
bindingComponents
).
find
((
name
)
=>
{
const
componentTag
=
bindingComponents
[
name
].
tag
const
camelName
=
camelize
(
componentTag
)
const
PascalName
=
capitalize
(
camelName
)
return
tag
===
componentTag
||
tag
===
camelName
||
tag
===
PascalName
})
}
function
findVueComponentImports
(
ast
:
Statement
[],
bindingComponents
:
BindingComponents
)
{
const
imports
:
{
tag
:
string
;
import
:
ImportDeclaration
}[]
=
[]
for
(
let
i
=
0
;
i
<
ast
.
length
;
i
++
)
{
const
node
=
ast
[
i
]
if
(
!
isImportDeclaration
(
node
))
{
continue
}
if
(
node
.
specifiers
.
length
!==
1
)
{
continue
}
const
{
name
}
=
node
.
specifiers
[
0
].
local
if
(
!
bindingComponents
[
name
])
{
continue
}
imports
.
push
({
tag
:
bindingComponents
[
name
].
tag
,
import
:
node
})
}
return
imports
}
packages/uni-cli-shared/src/utils.ts
浏览文件 @
05995c97
...
...
@@ -6,6 +6,7 @@ import { once } from '@dcloudio/uni-shared'
export
{
default
as
hash
}
from
'
hash-sum
'
import
{
PAGE_EXTNAME
,
PAGE_EXTNAME_APP
}
from
'
./constants
'
import
{
SFCTemplateCompileOptions
}
from
'
@vue/compiler-sfc
'
export
const
isWindows
=
os
.
platform
()
===
'
win32
'
export
function
normalizePath
(
id
:
string
):
string
{
return
isWindows
?
id
.
replace
(
/
\\
/g
,
'
/
'
)
:
id
...
...
@@ -42,12 +43,8 @@ export function normalizePagePath(pagePath: string, platform: UniApp.PLATFORM) {
console
.
error
(
`
${
pagePath
}
not found`
)
}
export
function
removeExt
(
str
:
string
,
ext
?:
string
)
{
if
(
ext
)
{
const
reg
=
new
RegExp
(
ext
.
replace
(
/
\.
/
,
'
\\
.
'
)
+
'
$
'
)
return
normalizePath
(
str
.
replace
(
reg
,
''
))
}
return
normalizePath
(
str
.
replace
(
/
\.\w
+$/g
,
''
))
export
function
removeExt
(
str
:
string
)
{
return
str
.
split
(
'
?
'
)[
0
].
replace
(
/
\.\w
+$/g
,
''
)
}
const
NODE_MODULES_REGEX
=
/
(\.\.\/)?
node_modules/g
...
...
@@ -61,3 +58,36 @@ export function normalizeNodeModules(str: string) {
}
return
str
}
export
function
normalizeMiniProgramFilename
(
filename
:
string
,
inputDir
?:
string
)
{
if
(
!
inputDir
)
{
return
normalizeNodeModules
(
filename
)
}
return
normalizeNodeModules
(
path
.
relative
(
inputDir
,
filename
))
}
export
function
createUniVueTransformAssetUrls
(
base
:
string
):
SFCTemplateCompileOptions
[
'
transformAssetUrls
'
]
{
return
{
base
,
tags
:
{
audio
:
[
'
src
'
],
video
:
[
'
src
'
,
'
poster
'
],
img
:
[
'
src
'
],
image
:
[
'
src
'
],
'
cover-image
'
:
[
'
src
'
],
// h5
'
v-uni-audio
'
:
[
'
src
'
],
'
v-uni-video
'
:
[
'
src
'
,
'
poster
'
],
'
v-uni-image
'
:
[
'
src
'
],
'
v-uni-cover-image
'
:
[
'
src
'
],
// nvue
'
u-image
'
:
[
'
src
'
],
'
u-video
'
:
[
'
src
'
,
'
poster
'
],
},
}
}
packages/uni-mp-compiler/__tests__/transformElement.spec.ts
浏览文件 @
05995c97
import
{
BindingTypes
,
ElementNode
,
RootNode
}
from
'
@vue/compiler-core
'
import
{
compileTemplate
,
TemplateCompiler
}
from
'
@vue/compiler-sfc
'
import
{
compile
}
from
'
../src
'
import
*
as
MPCompiler
from
'
../src
'
import
{
MPErrorCodes
}
from
'
../src/errors
'
import
{
CodegenRootNode
,
CompilerOptions
}
from
'
../src/options
'
import
{
BindingComponentTypes
}
from
'
../src/transform
'
import
{
createUniVueTransformAssetUrls
}
from
'
@dcloudio/uni-cli-shared
'
function
parseWithElementTransform
(
template
:
string
,
...
...
@@ -24,12 +27,33 @@ function parseWithElementTransform(
}
describe
(
'
compiler: element transform
'
,
()
=>
{
test
(
`transformAssetUrls`
,
()
=>
{
const
result
=
compileTemplate
({
source
:
`<image src="/static/logo.png"/>`
,
filename
:
'
foo.vue
'
,
id
:
'
foo
'
,
compiler
:
MPCompiler
as
unknown
as
TemplateCompiler
,
compilerOptions
:
{
mode
:
'
module
'
,
},
transformAssetUrls
:
{
includeAbsolute
:
true
,
...(
createUniVueTransformAssetUrls
(
'
/
'
)
as
Record
<
string
,
any
>
),
},
})
expect
(
result
.
code
).
toBe
(
`import _imports_0 from '/static/logo.png'
export function render(_ctx, _cache) {
return { a: _imports_0 }
}`
)
})
test
(
'
import + resolve component
'
,
()
=>
{
const
{
root
}
=
parseWithElementTransform
(
`<Foo/>`
)
expect
((
root
as
CodegenRootNode
).
bindingComponents
).
toEqual
({
Foo
:
{
name
:
'
_component_Foo
'
,
type
:
BindingComponentTypes
.
UNKNOWN
},
})
// expect(code).toContain(`if (!Math) {
Math.max.call(Max, _component_Foo)
}`)
// expect(code).toContain(`if (!Math) {
Math.max.call(Max, _component_Foo)
}`)
})
test
(
'
import + resolve component multi
'
,
()
=>
{
...
...
@@ -48,7 +72,9 @@ describe('compiler: element transform', () => {
Example
:
{
name
:
'
$setup["Example"]
'
,
type
:
BindingComponentTypes
.
SETUP
},
Test
:
{
name
:
'
_component_Test
'
,
type
:
BindingComponentTypes
.
SELF
},
})
expect
(
code
).
toContain
(
`if (!Math) {Math.max.call(Max, $setup["Example"])}`
)
expect
(
code
).
toContain
(
`if (!Math) { Math.max.call(Max, $setup["Example"]) }`
)
})
test
(
'
resolve implcitly self-referencing component
'
,
()
=>
{
...
...
@@ -69,7 +95,9 @@ describe('compiler: element transform', () => {
expect
((
root
as
CodegenRootNode
).
bindingComponents
).
toEqual
({
Example
:
{
name
:
'
$setup["Example"]
'
,
type
:
BindingComponentTypes
.
SETUP
},
})
expect
(
code
).
toContain
(
`if (!Math) {Math.max.call(Max, $setup["Example"])}`
)
expect
(
code
).
toContain
(
`if (!Math) { Math.max.call(Max, $setup["Example"]) }`
)
})
test
(
'
resolve component from setup bindings (inline)
'
,
()
=>
{
...
...
@@ -83,7 +111,7 @@ describe('compiler: element transform', () => {
Example
:
{
name
:
'
_unref(Example)
'
,
type
:
BindingComponentTypes
.
SETUP
},
})
expect
(
preamble
).
toContain
(
`if (!Math) {
Math.max.call(Max, _unref(Example))
}`
`if (!Math) {
Math.max.call(Max, _unref(Example))
}`
)
})
...
...
@@ -97,7 +125,7 @@ describe('compiler: element transform', () => {
expect
((
root
as
CodegenRootNode
).
bindingComponents
).
toEqual
({
Example
:
{
name
:
'
Example
'
,
type
:
BindingComponentTypes
.
SETUP
},
})
expect
(
preamble
).
toContain
(
`if (!Math) {
Math.max.call(Max, Example)
}`
)
expect
(
preamble
).
toContain
(
`if (!Math) {
Math.max.call(Max, Example)
}`
)
})
test
(
'
resolve namespaced component from setup bindings
'
,
()
=>
{
...
...
packages/uni-mp-compiler/__tests__/vShow.spec.ts
0 → 100644
浏览文件 @
05995c97
import
{
assert
}
from
'
./testUtils
'
describe
(
'
compiler: transform v-show
'
,
()
=>
{
test
(
'
basic
'
,
()
=>
{
assert
(
`<view v-show="show"/>`
,
`<view hidden="{{!a}}"/>`
,
`(_ctx, _cache) => {
return { a: _ctx.show }
}`
)
})
})
packages/uni-mp-compiler/__tests__/vSlot.spec.ts
0 → 100644
浏览文件 @
05995c97
import
{
assert
}
from
'
./testUtils
'
describe
(
'
compiler: transform v-slot
'
,
()
=>
{
test
(
'
default slot
'
,
()
=>
{
assert
(
`<template v-slot/>`
,
`<block />`
,
`(_ctx, _cache) => {
return {}
}`
)
})
test
(
'
named slot
'
,
()
=>
{
assert
(
`<template v-slot:header/><template v-slot:default/><template v-slot:footer/>`
,
`<block slot="header"/><block slot="default"/><block slot="footer"/>`
,
`(_ctx, _cache) => {
return {}
}`
)
})
// TODO 还未实现scoped slot
test
(
'
named slot
'
,
()
=>
{
assert
(
`<template v-slot:default="slotProps"><view>{{ slotProps.item }}</view></template>`
,
`<block slot="default"><view>{{a}}</view></block>`
,
`(_ctx, _cache) => {
return { a: _toDisplayString(_ctx.slotProps.item), b: slotProps }
}`
)
})
})
packages/uni-mp-compiler/src/codegen.ts
浏览文件 @
05995c97
...
...
@@ -16,7 +16,11 @@ import { addImportDeclaration, matchEasycom } from '@dcloudio/uni-cli-shared'
import
{
CodegenOptions
,
CodegenRootNode
}
from
'
./options
'
import
{
createObjectExpression
}
from
'
./ast
'
import
{
BindingComponentTypes
,
TransformContext
}
from
'
./transform
'
import
{
BindingComponentTypes
,
ImportItem
,
TransformContext
,
}
from
'
./transform
'
interface
CodegenContext
extends
CodegenOptions
{
code
:
string
...
...
@@ -148,28 +152,44 @@ function createCodegenContext(
function
genComponentImports
(
bindingComponents
:
TransformContext
[
'
bindingComponents
'
],
{
push
}:
CodegenContext
{
push
,
newline
}:
CodegenContext
)
{
const
tags
=
Object
.
keys
(
bindingComponents
)
const
importDeclarations
:
string
[]
=
[]
// 仅记录easycom和setup组件
const
components
:
string
[]
=
[]
Object
.
keys
(
bindingComponents
)
.
forEach
((
tag
)
=>
{
tags
.
forEach
((
tag
)
=>
{
const
{
name
,
type
}
=
bindingComponents
[
tag
]
if
(
type
===
BindingComponentTypes
.
UNKNOWN
)
{
const
source
=
matchEasycom
(
tag
)
if
(
source
)
{
components
.
push
(
name
)
addImportDeclaration
(
importDeclarations
,
name
,
source
)
// 调整为easycom命名
const
easycomName
=
name
.
replace
(
'
component
'
,
'
easycom
'
)
bindingComponents
[
tag
].
name
=
easycomName
components
.
push
(
easycomName
)
addImportDeclaration
(
importDeclarations
,
easycomName
,
source
)
}
}
else
if
(
type
===
BindingComponentTypes
.
SETUP
)
{
components
.
push
(
name
)
}
})
importDeclarations
.
forEach
((
str
)
=>
push
(
str
))
if
(
components
.
length
)
{
push
(
`if (!Math) {`
)
push
(
`Math.max.call(Max,
${
components
.
map
((
name
)
=>
name
).
join
(
'
,
'
)}
)`
)
push
(
`}`
)
if
(
tags
.
length
)
{
push
(
`const __BINDING_COMPONENTS__ = '`
+
JSON
.
stringify
(
bindingComponents
)
+
`'`
)
newline
()
importDeclarations
.
forEach
((
str
)
=>
push
(
str
))
if
(
importDeclarations
.
length
)
{
newline
()
}
if
(
components
.
length
)
{
push
(
`if (!Math) {`
)
push
(
` Math.max.call(Max,
${
components
.
map
((
name
)
=>
name
).
join
(
'
,
'
)}
) `
)
push
(
`}`
)
newline
()
}
}
}
...
...
@@ -210,6 +230,11 @@ function genModulePreamble(
.
join
(
'
,
'
)}
} from
${
JSON
.
stringify
(
runtimeModuleName
)}
\n`
)
}
if
(
ast
.
imports
.
length
)
{
genImports
(
ast
.
imports
,
context
)
}
genComponentImports
(
bindingComponents
,
context
)
newline
()
if
(
!
inline
)
{
...
...
@@ -217,6 +242,21 @@ function genModulePreamble(
}
}
function
genImports
(
importsOptions
:
ImportItem
[],
{
push
,
newline
}:
CodegenContext
)
{
if
(
!
importsOptions
.
length
)
{
return
}
importsOptions
.
forEach
((
imports
)
=>
{
push
(
`import `
)
push
(
genExpr
(
imports
.
exp
))
push
(
` from '
${
imports
.
path
}
'`
)
newline
()
})
}
type
CodegenNode
=
|
SimpleExpressionNode
|
CompoundExpressionNode
...
...
packages/uni-mp-compiler/src/template/codegen.ts
浏览文件 @
05995c97
import
{
hyphenate
}
from
'
@vue/shared
'
import
{
formatMiniProgramEvent
}
from
'
@dcloudio/uni-cli-shared
'
import
{
AttributeNode
,
DirectiveNode
,
ElementNode
,
ElementTypes
,
ExpressionNode
,
findProp
,
NodeTypes
,
...
...
@@ -95,7 +97,10 @@ const tagMap: Record<string, string> = {
}
export
function
genElement
(
node
:
ElementNode
,
context
:
TemplateCodegenContext
)
{
const
{
children
,
isSelfClosing
,
props
}
=
node
const
tag
=
tagMap
[
node
.
tag
]
||
node
.
tag
let
tag
=
tagMap
[
node
.
tag
]
||
node
.
tag
if
(
node
.
tagType
===
ElementTypes
.
COMPONENT
)
{
tag
=
hyphenate
(
tag
)
}
const
{
push
}
=
context
push
(
`<
${
tag
}
`
)
if
(
isIfElementNode
(
node
))
{
...
...
@@ -166,7 +171,19 @@ function genDirectiveNode(
prop
:
DirectiveNode
,
{
push
}:
TemplateCodegenContext
)
{
const
arg
=
(
prop
.
arg
as
SimpleExpressionNode
).
content
const
exp
=
(
prop
.
exp
as
SimpleExpressionNode
).
content
push
(
`
${
arg
}
="{{
${
exp
}
}}"`
)
if
(
prop
.
name
===
'
slot
'
)
{
if
(
prop
.
arg
)
{
push
(
`slot="
${(
prop
.
arg
as
SimpleExpressionNode
).
content
}
"`
)
}
}
else
if
(
prop
.
name
===
'
model
'
)
{
// TODO
}
else
if
(
prop
.
name
===
'
show
'
)
{
push
(
`hidden="{{!
${(
prop
.
exp
as
SimpleExpressionNode
).
content
}
}}"`
)
}
else
if
(
prop
.
arg
&&
prop
.
exp
)
{
const
arg
=
(
prop
.
arg
as
SimpleExpressionNode
).
content
const
exp
=
(
prop
.
exp
as
SimpleExpressionNode
).
content
push
(
`
${
arg
}
="{{
${
exp
}
}}"`
)
}
else
{
throw
new
Error
(
`unknown directive`
+
JSON
.
stringify
(
prop
))
}
}
packages/uni-mp-compiler/src/transform.ts
浏览文件 @
05995c97
...
...
@@ -38,6 +38,11 @@ import {
TransformOptions
,
}
from
'
./options
'
export
interface
ImportItem
{
exp
:
string
|
ExpressionNode
path
:
string
}
export
type
NodeTransform
=
(
node
:
RootNode
|
TemplateChildNode
,
context
:
TransformContext
...
...
@@ -73,6 +78,7 @@ export interface TransformContext
childIndex
:
number
helpers
:
Map
<
symbol
,
number
>
components
:
Set
<
string
>
imports
:
ImportItem
[]
bindingComponents
:
Record
<
string
,
{
type
:
BindingComponentTypes
;
name
:
string
}
...
...
@@ -117,6 +123,7 @@ export function transform(root: RootNode, options: TransformOptions) {
// finalize meta information
root
.
helpers
=
[...
context
.
helpers
.
keys
()]
root
.
components
=
[...
context
.
components
]
root
.
imports
=
context
.
imports
root
.
cached
=
context
.
cached
return
context
}
...
...
@@ -278,6 +285,7 @@ export function createTransformContext(
childIndex
:
0
,
helpers
:
new
Map
(),
components
:
new
Set
(),
imports
:
[],
bindingComponents
:
Object
.
create
(
null
),
cached
:
0
,
identifiers
,
...
...
packages/uni-mp-vite/src/index.ts
浏览文件 @
05995c97
import
{
uniMiniProgramPlugin
,
UniMiniProgramPluginOptions
}
from
'
./plugin
'
import
{
uni
ComponentPlugin
}
from
'
./plugins/component
'
import
{
uni
UsingComponentsPlugin
}
from
'
./plugins/usingComponents
'
import
{
uniMainJsPlugin
}
from
'
./plugins/mainJs
'
import
{
uniManifestJsonPlugin
}
from
'
./plugins/manifestJson
'
import
{
uniPagesJsonPlugin
}
from
'
./plugins/pagesJson
'
import
{
uniVirtualPlugin
}
from
'
./plugins/virtual
'
import
{
uniEntryPlugin
}
from
'
./plugins/entry
'
import
{
SFCScriptCompileOptions
}
from
'
@vue/compiler-sfc
'
export
{
UniMiniProgramPluginOptions
}
from
'
./plugin
'
export
default
(
options
:
UniMiniProgramPluginOptions
)
=>
{
return
[
uniMainJsPlugin
(
options
),
uniManifestJsonPlugin
(
options
),
uniPagesJsonPlugin
(
options
),
uni
Virtual
Plugin
(
options
),
uni
Entry
Plugin
(
options
),
uniMiniProgramPlugin
(
options
),
uniComponentPlugin
(),
(
options
:
{
vueOptions
?:
{
script
?:
Partial
<
SFCScriptCompileOptions
>
}
})
=>
{
return
uniUsingComponentsPlugin
(
options
.
vueOptions
?.
script
)
},
]
}
packages/uni-mp-vite/src/plugin/build.ts
浏览文件 @
05995c97
...
...
@@ -14,7 +14,7 @@ import {
isUniPageUrl
,
parseVirtualComponentPath
,
parseVirtualPagePath
,
}
from
'
../plugins/
virtual
'
}
from
'
../plugins/
entry
'
export
function
buildOptions
():
UserConfig
[
'
build
'
]
{
const
inputDir
=
process
.
env
.
UNI_INPUT_DIR
...
...
packages/uni-mp-vite/src/plugins/component.ts
已删除
100644 → 0
浏览文件 @
e858f31c
import
path
from
'
path
'
import
{
Plugin
}
from
'
vite
'
import
{
EXTNAME_VUE
,
parseVueRequest
,
findVueComponentImports
,
}
from
'
@dcloudio/uni-cli-shared
'
import
MagicString
from
'
magic-string
'
import
{
virtualComponentPath
}
from
'
./virtual
'
export
function
uniComponentPlugin
():
Plugin
{
return
{
name
:
'
vite:uni-mp-component
'
,
async
transform
(
code
,
id
)
{
const
{
filename
,
query
}
=
parseVueRequest
(
id
)
if
(
query
.
vue
)
{
return
null
}
if
(
!
EXTNAME_VUE
.
includes
(
path
.
extname
(
filename
)))
{
return
null
}
const
vueComponentImports
=
await
findVueComponentImports
(
code
,
id
,
this
.
resolve
)
if
(
!
vueComponentImports
.
length
)
{
return
null
}
const
s
=
new
MagicString
(
code
)
const
rewriteImports
:
string
[]
=
[]
vueComponentImports
.
forEach
(({
n
,
ss
,
se
,
i
})
=>
{
s
.
remove
(
ss
,
se
)
rewriteImports
.
push
(
`const
${
i
}
= ()=>import('
${
virtualComponentPath
(
n
!
)}
')`
)
})
s
.
prepend
(
rewriteImports
.
join
(
'
;
'
)
+
'
;
\n
'
)
return
s
.
toString
()
},
}
}
packages/uni-mp-vite/src/plugins/
virtual
.ts
→
packages/uni-mp-vite/src/plugins/
entry
.ts
浏览文件 @
05995c97
import
path
from
'
path
'
import
{
normalizePath
}
from
'
@dcloudio/uni-cli-shared
'
import
{
addMiniProgramComponentJson
,
normalizeMiniProgramFilename
,
normalizePath
,
removeExt
,
}
from
'
@dcloudio/uni-cli-shared
'
import
{
Plugin
}
from
'
vite
'
import
{
UniMiniProgramPluginOptions
}
from
'
../plugin
'
...
...
@@ -37,7 +42,7 @@ export function isUniComponentUrl(id: string) {
return
id
.
startsWith
(
uniComponentPrefix
)
}
export
function
uni
Virtual
Plugin
({
export
function
uni
Entry
Plugin
({
global
,
}:
UniMiniProgramPluginOptions
):
Plugin
{
const
inputDir
=
process
.
env
.
UNI_INPUT_DIR
...
...
@@ -64,6 +69,10 @@ ${global}.createPage(Page)`,
path
.
resolve
(
inputDir
,
parseVirtualComponentPath
(
id
))
)
this
.
addWatchFile
(
filepath
)
addMiniProgramComponentJson
(
removeExt
(
normalizeMiniProgramFilename
(
filepath
,
inputDir
)),
{
component
:
true
}
)
return
{
code
:
`import Component from '
${
filepath
}
'
${
global
}
.createComponent(Component)`
,
...
...
packages/uni-mp-vite/src/plugins/pagesJson.ts
浏览文件 @
05995c97
import
fs
from
'
fs
'
import
path
from
'
path
'
import
debug
from
'
debug
'
import
{
Plugin
}
from
'
vite
'
import
{
...
...
@@ -7,17 +8,20 @@ import {
defineUniPagesJsonPlugin
,
getLocaleFiles
,
normalizePagePath
,
normalizeNodeModules
,
parseManifestJsonOnce
,
parseMiniProgramPagesJson
,
addMiniProgramPageJson
,
addMiniProgramAppJson
,
findChangedJsonFiles
,
}
from
'
@dcloudio/uni-cli-shared
'
import
{
virtualPagePath
}
from
'
./
virtual
'
import
{
virtualPagePath
}
from
'
./
entry
'
import
{
UniMiniProgramPluginOptions
}
from
'
../plugin
'
const
debugPagesJson
=
debug
(
'
vite:uni:pages-json
'
)
export
function
uniPagesJsonPlugin
(
options
:
UniMiniProgramPluginOptions
):
Plugin
{
let
appJson
:
AppJson
return
defineUniPagesJsonPlugin
((
opts
)
=>
{
return
{
name
:
'
vite:uni-mp-pages-json
'
,
...
...
@@ -32,21 +36,21 @@ export function uniPagesJsonPlugin(
this
.
addWatchFile
(
filepath
)
})
const
manifestJson
=
parseManifestJsonOnce
(
inputDir
)
const
res
=
parseMiniProgramPagesJson
(
code
,
process
.
env
.
UNI_PLATFORM
,
{
debug
:
!!
manifestJson
.
debug
,
darkmode
:
options
.
app
.
darkmode
&&
fs
.
existsSync
(
path
.
resolve
(
inputDir
,
'
theme.json
'
))
,
networkTimeout
:
manifestJson
.
networkTimeout
,
subpackages
:
options
.
app
.
subpackages
,
})
appJson
=
res
.
appJson
Object
.
keys
(
res
.
pageJsons
).
forEach
((
name
)
=>
{
this
.
emitFile
({
fileName
:
normalizeNodeModules
(
name
)
+
'
.json
'
,
type
:
'
asset
'
,
source
:
JSON
.
stringify
(
res
.
pageJsons
[
name
],
null
,
2
),
}
)
const
{
appJson
,
pageJsons
}
=
parseMiniProgramPagesJson
(
code
,
process
.
env
.
UNI_PLATFORM
,
{
debug
:
!!
manifestJson
.
debug
,
darkmode
:
options
.
app
.
darkmode
&&
fs
.
existsSync
(
path
.
resolve
(
inputDir
,
'
theme.json
'
)),
networkTimeout
:
manifestJson
.
networkTimeout
,
subpackages
:
options
.
app
.
subpackages
,
}
)
addMiniProgramAppJson
(
appJson
)
Object
.
keys
(
pageJsons
).
forEach
((
name
)
=>
{
addMiniProgramPageJson
(
name
,
pageJsons
[
name
]
)
})
return
{
code
:
`import './manifest.json.js'\n`
+
importPagesCode
(
appJson
),
...
...
@@ -54,13 +58,14 @@ export function uniPagesJsonPlugin(
}
},
generateBundle
()
{
if
(
appJson
)
{
findChangedJsonFiles
().
forEach
((
value
,
key
)
=>
{
debugPagesJson
(
'
json.changed
'
,
key
)
this
.
emitFile
({
fileName
:
`app.json`
,
type
:
'
asset
'
,
source
:
JSON
.
stringify
(
appJson
,
null
,
2
),
fileName
:
key
+
'
.json
'
,
source
:
value
,
})
}
}
)
},
}
})
...
...
packages/uni-mp-vite/src/plugins/usingComponents.ts
0 → 100644
浏览文件 @
05995c97
import
path
from
'
path
'
import
{
Plugin
}
from
'
vite
'
import
{
SFCScriptCompileOptions
}
from
'
@vue/compiler-sfc
'
import
{
EXTNAME_VUE
,
parseVueRequest
,
transformVueComponentImports
,
normalizeMiniProgramFilename
,
addMiniProgramUsingComponents
,
removeExt
,
}
from
'
@dcloudio/uni-cli-shared
'
import
{
virtualComponentPath
}
from
'
./entry
'
export
function
uniUsingComponentsPlugin
(
options
:
Partial
<
SFCScriptCompileOptions
>
=
{}
):
Plugin
{
return
{
name
:
'
vite:uni-mp-using-component
'
,
async
transform
(
source
,
id
)
{
const
{
filename
,
query
}
=
parseVueRequest
(
id
)
if
(
query
.
vue
)
{
return
null
}
if
(
!
EXTNAME_VUE
.
includes
(
path
.
extname
(
filename
)))
{
return
null
}
const
inputDir
=
process
.
env
.
UNI_INPUT_DIR
const
{
code
,
usingComponents
}
=
await
transformVueComponentImports
(
source
,
id
,
{
root
:
inputDir
,
resolve
:
this
.
resolve
,
dynamicImport
,
babelParserPlugins
:
options
.
babelParserPlugins
,
}
)
addMiniProgramUsingComponents
(
removeExt
(
normalizeMiniProgramFilename
(
id
,
inputDir
)),
usingComponents
)
return
{
code
,
map
:
this
.
getCombinedSourcemap
(),
}
},
}
}
function
dynamicImport
(
name
:
string
,
value
:
string
)
{
return
`const
${
name
}
= ()=>import('
${
virtualComponentPath
(
value
)}
')`
}
packages/vite-plugin-uni/src/index.ts
浏览文件 @
05995c97
...
...
@@ -93,7 +93,8 @@ export default function uniPlugin(
const
uniPlugins
=
initExtraPlugins
(
process
.
env
.
UNI_CLI_CONTEXT
||
process
.
cwd
(),
(
process
.
env
.
UNI_PLATFORM
as
UniApp
.
PLATFORM
)
||
'
h5
'
(
process
.
env
.
UNI_PLATFORM
as
UniApp
.
PLATFORM
)
||
'
h5
'
,
options
)
debugUni
(
uniPlugins
)
...
...
packages/vite-plugin-uni/src/utils/plugin.ts
浏览文件 @
05995c97
...
...
@@ -8,6 +8,7 @@ import type {
UniVitePlugin
,
}
from
'
@dcloudio/uni-cli-shared
'
import
{
TemplateCompiler
}
from
'
@vue/compiler-sfc
'
import
{
VitePluginUniResolvedOptions
}
from
'
..
'
interface
PluginConfig
{
id
:
string
...
...
@@ -68,20 +69,40 @@ export function initPluginUniOptions(UniVitePlugins: UniVitePlugin[]) {
}
}
export
function
initExtraPlugins
(
cliRoot
:
string
,
platform
:
UniApp
.
PLATFORM
)
{
return
initPlugins
(
resolvePlugins
(
cliRoot
,
platform
))
export
function
initExtraPlugins
(
cliRoot
:
string
,
platform
:
UniApp
.
PLATFORM
,
options
:
VitePluginUniResolvedOptions
)
{
return
initPlugins
(
resolvePlugins
(
cliRoot
,
platform
),
options
)
}
function
initPlugin
({
id
,
config
:
{
main
}
}:
PluginConfig
):
Plugin
|
void
{
const
plugin
=
require
(
path
.
join
(
id
,
main
||
'
/lib/uni.plugin.js
'
))
return
plugin
.
default
||
plugin
function
initPlugin
(
{
id
,
config
:
{
main
}
}:
PluginConfig
,
options
:
VitePluginUniResolvedOptions
):
Plugin
|
void
{
let
plugin
=
require
(
path
.
join
(
id
,
main
||
'
/lib/uni.plugin.js
'
))
plugin
=
plugin
.
default
||
plugin
if
(
isFunction
(
plugin
))
{
plugin
=
plugin
(
options
)
}
return
plugin
}
function
initPlugins
(
plugins
:
PluginConfig
[]):
Plugin
[]
{
function
initPlugins
(
plugins
:
PluginConfig
[],
options
:
VitePluginUniResolvedOptions
):
Plugin
[]
{
return
plugins
.
map
((
plugin
)
=>
initPlugin
(
plugin
))
.
map
((
plugin
)
=>
initPlugin
(
plugin
,
options
))
.
flat
()
.
filter
<
Plugin
>
(
Boolean
as
any
)
.
map
((
plugin
)
=>
{
if
(
isFunction
(
plugin
))
{
return
plugin
(
options
)
}
return
plugin
})
}
function
resolvePlugins
(
cliRoot
:
string
,
platform
:
UniApp
.
PLATFORM
)
{
...
...
packages/vite-plugin-uni/src/vue/options.ts
浏览文件 @
05995c97
import
{
extend
,
hasOwn
,
isArray
,
isPlainObject
}
from
'
@vue/shared
'
import
{
SFCTemplateCompileOptions
,
TemplateCompiler
}
from
'
@vue/compiler-sfc
'
import
{
TemplateCompiler
}
from
'
@vue/compiler-sfc
'
import
{
isCustomElement
}
from
'
@dcloudio/uni-shared
'
import
{
EXTNAME_VUE_RE
,
UniVitePlugin
,
uniPostcssScopedPlugin
,
createUniVueTransformAssetUrls
,
}
from
'
@dcloudio/uni-cli-shared
'
import
{
VitePluginUniResolvedOptions
}
from
'
..
'
...
...
@@ -12,29 +13,6 @@ import { transformMatchMedia } from './transforms/transformMatchMedia'
import
{
createTransformEvent
}
from
'
./transforms/transformEvent
'
// import { transformContext } from './transforms/transformContext'
function
createUniVueTransformAssetUrls
(
base
:
string
):
SFCTemplateCompileOptions
[
'
transformAssetUrls
'
]
{
return
{
base
,
tags
:
{
audio
:
[
'
src
'
],
video
:
[
'
src
'
,
'
poster
'
],
img
:
[
'
src
'
],
image
:
[
'
src
'
],
'
cover-image
'
:
[
'
src
'
],
// h5
'
v-uni-audio
'
:
[
'
src
'
],
'
v-uni-video
'
:
[
'
src
'
,
'
poster
'
],
'
v-uni-image
'
:
[
'
src
'
],
'
v-uni-cover-image
'
:
[
'
src
'
],
// nvue
'
u-image
'
:
[
'
src
'
],
'
u-video
'
:
[
'
src
'
,
'
poster
'
],
},
}
}
export
function
initPluginVueOptions
(
options
:
VitePluginUniResolvedOptions
,
UniVitePlugins
:
UniVitePlugin
[],
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录