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

feat(v3): mp runtime

上级 4cd5ee7b
module.exports = {
input: 'src/core/runtime/mp/wxs.js',
output: {
file: 'packages/uni-mp-weixin/dist/wxs.js',
format: 'es'
}
}
......@@ -21,7 +21,8 @@
"build:mp-baidu": "cross-env UNI_PLATFORM=mp-baidu rollup -c build/rollup.config.mp.js",
"build:mp-alipay": "cross-env UNI_PLATFORM=mp-alipay rollup -c build/rollup.config.mp.js",
"build:mp-toutiao": "cross-env UNI_PLATFORM=mp-toutiao rollup -c build/rollup.config.mp.js",
"build:mp-weixin:mp": "npm run lint && cross-env UNI_PLATFORM=mp-weixin UNI_MP=true rollup -c build/rollup.config.mp.js",
"build:mp-weixin:mp": "npm run lint && cross-env UNI_PLATFORM=mp-weixin UNI_MP=true rollup -c build/rollup.config.mp.js",
"build:mp-weixin:wxs": "rollup -c build/rollup.config.wxs.js",
"build:runtime": "npm run lint && npm run build:mp-weixin && npm run build:mp-qq && npm run build:mp-alipay && npm run build:mp-baidu && npm run build:mp-toutiao && npm run build:app-plus",
"build:stat": "npm run lint && rollup -c build/rollup.config.stat.js",
"build:web-view": "npm run lint && rollup -c build/rollup.config.web-view.js",
......
......@@ -12099,7 +12099,9 @@ var serviceContext = (function () {
Object.keys(dataset).forEach(name => {
try {
ret[name] = JSON.parse(dataset[name]);
} catch (e) {}
} catch (e) { // dataset 存在两种,一种是被JSON.stringify的,一种是原始的
ret[name] = dataset[name];
}
});
return ret
}
......
const {
generateUsingComponentsCode,
generateGlobalUsingComponentsCode
} = require('../lib/pages')
describe('shared:pages', () => {
it('generate usingComponents', () => {
expect(generateUsingComponentsCode()).toBe('')
expect(generateUsingComponentsCode({})).toBe('')
expect(generateUsingComponentsCode({
'van-button': '/wxcomponents/vant/button/index',
'van-card': '../../wxcomponents/vant/card/index'
})).toBe(
`import VanButton from '@/wxcomponents/vant/button/index.vue';import VanCard from '../../wxcomponents/vant/card/index.vue';global['__wxVueOptions'] = {components:{'van-button':VanButton,'van-card':VanCard}};`
)
})
it('generate global usingComponents', () => {
expect(generateGlobalUsingComponentsCode()).toBe('')
expect(generateGlobalUsingComponentsCode({})).toBe('')
expect(generateGlobalUsingComponentsCode({
'van-button': '/wxcomponents/vant/button/index',
'van-cell': 'wxcomponents/vant/cell/index',
'van-cell-group': './wxcomponents/vant/cell-group/index'
})).toBe(
`import VanButton from '@/wxcomponents/vant/button/index.vue';import VanCell from './wxcomponents/vant/cell/index.vue';import VanCellGroup from './wxcomponents/vant/cell-group/index.vue';Vue.component('van-button',VanButton);Vue.component('van-cell',VanCell);Vue.component('van-cell-group',VanCellGroup);`
)
})
})
const fs = require('fs')
const path = require('path')
const stripJsonComments = require('strip-json-comments')
const preprocessor = require('@dcloudio/vue-cli-plugin-uni/packages/webpack-preprocess-loader/preprocess')
const {
jsPreprocessOptions
} = require('./platform')
function parseJson (content, preprocess = false) {
if (typeof content === 'string') {
if (preprocess) {
const preprocessor = require('@dcloudio/vue-cli-plugin-uni/packages/webpack-preprocess-loader/preprocess')
const {
jsPreprocessOptions
} = require('./platform')
content = preprocessor.preprocess(content, jsPreprocessOptions.context, {
type: jsPreprocessOptions.type
})
}
content = JSON.parse(stripJsonComments(content))
}
......
......@@ -3,7 +3,9 @@ const path = require('path')
const {
removeExt,
normalizePath
normalizePath,
camelize,
capitalize
} = require('./util')
const {
......@@ -244,6 +246,87 @@ function parseEntry (pagesJson) {
}
}
function parseUsingComponents (usingComponents = {}) {
const components = []
Object.keys(usingComponents).forEach(name => {
const identifier = capitalize(camelize(name))
let source = usingComponents[name]
if (source.indexOf('/') === 0) { // 绝对路径
source = '@' + source
} else if (source.indexOf('.') !== 0) { // 相对路径
source = './' + source
}
components.push({
name,
identifier,
source
})
})
return components
}
function generateUsingComponentsCode (usingComponents) {
const components = parseUsingComponents(usingComponents)
const importCode = []
const componentsCode = []
components.forEach(({
name,
identifier,
source
}) => {
importCode.push(`import ${identifier} from '${source}.vue'`)
componentsCode.push(`'${name}':${identifier}`)
})
if (!importCode.length) {
return ''
}
return `${importCode.join(';')};global['__wxVueOptions'] = {components:{${componentsCode.join(',')}}};`
}
function generateGlobalUsingComponentsCode (usingComponents) {
const components = parseUsingComponents(usingComponents)
const importCode = []
const componentsCode = []
components.forEach(({
name,
identifier,
source
}) => {
importCode.push(`import ${identifier} from '${source}.vue'`)
componentsCode.push(`Vue.component('${name}',${identifier})`)
})
if (!importCode.length) {
return ''
}
return `${importCode.join(';')};${componentsCode.join(';')};`
}
function getGlobalUsingComponentsCode () {
const pagesJson = getPagesJson()
const usingComponents = pagesJson.globalStyle && pagesJson.globalStyle.usingComponents
if (!usingComponents) {
return ''
}
return generateGlobalUsingComponentsCode(usingComponents)
}
function getUsingComponentsCode (pagePath) {
const usingComponents = usingComponentsPages[pagePath]
if (!usingComponents) {
return ''
}
return generateUsingComponentsCode(usingComponents)
}
const usingComponentsPages = Object.create(null)
function addPageUsingComponents (pagePath, usingComponents) {
if (usingComponents && Object.keys(usingComponents).length) {
console.log(pagePath + ':' + JSON.stringify(usingComponents))
usingComponentsPages[pagePath] = usingComponents
}
}
module.exports = {
getMainEntry,
getNVueMainEntry,
......@@ -251,5 +334,10 @@ module.exports = {
parseEntry,
getPagesJson,
parsePagesJson,
pagesJsonJsFileName
pagesJsonJsFileName,
addPageUsingComponents,
getUsingComponentsCode,
generateUsingComponentsCode,
getGlobalUsingComponentsCode,
generateGlobalUsingComponentsCode
}
......@@ -48,7 +48,11 @@ const camelizeRE = /-(\w)/g
const camelize = cached((str) => {
return str.replace(camelizeRE, (_, c) => c ? c.toUpperCase() : '')
})
})
function capitalize (str) {
return str.charAt(0).toUpperCase() + str.slice(1)
}
const hyphenateRE = /\B([A-Z])/g
......@@ -106,7 +110,8 @@ module.exports = {
},
hashify,
removeExt,
camelize,
camelize,
capitalize,
hyphenate,
normalizePath,
convertStaticStyle,
......
......@@ -9,37 +9,37 @@ describe('wxml:compiler', () => {
it('generate event', () => {
assertCodegen(
`<view bindtouchstart="startDrag" catchtouchmove="{{ catchMove ? 'noop' : '' }}"/>`,
`<view @touchstart="startDrag" @touchmove.stop.prevent="catchMove ? 'noop' : ''"></view>`
`<uni-shadow-root><view @touchstart="startDrag" @touchmove.stop.prevent="catchMove ? 'noop' : ''"></view></uni-shadow-root>`
)
assertCodegen(
`<uni-transition bind:click="click" bindtouchstart="startDrag" catchtouchmove="{{ catchMove ? 'noop' : '' }}"/>`,
`<uni-transition @click="click" @touchstart.native="startDrag" @touchmove.native.stop.prevent="catchMove ? 'noop' : ''"></uni-transition>`
`<uni-shadow-root><uni-transition @click="click" @touchstart.native="startDrag" @touchmove.native.stop.prevent="catchMove ? 'noop' : ''"></uni-transition></uni-shadow-root>`
)
})
it('generate class', () => {
assertCodegen(
`<view class="van-notice-bar__content {{ !scrollable && !wrapable ? 'van-ellipsis' : '' }}"></view>`,
`<view :class="'van-notice-bar__content '+(!scrollable && !wrapable ? 'van-ellipsis' : '')"></view>`
`<uni-shadow-root><view :class="'van-notice-bar__content '+(!scrollable && !wrapable ? 'van-ellipsis' : '')"></view></uni-shadow-root>`
)
})
it('generate v-if', () => {
assertCodegen(
'<block wx:if="{{ !loading }}" loading loading-text="">{{ item.name }}</block>',
`<block v-if="(!loading)" loading loading-text>{{ item.name }}</block>`
`<uni-shadow-root><block v-if="(!loading)" loading loading-text>{{ item.name }}</block></uni-shadow-root>`
)
})
it('generate v-for', () => {
assertCodegen(
'<view wx:for="{{ isSimple(columns) ? [columns] : columns }}" wx:for-item="item1" wx:key="{{ index }}"/>',
`<view v-for="(item1,index) in (isSimple(columns) ? [columns] : columns)" :key="item1.index"></view>`
`<uni-shadow-root><view v-for="(item1,index) in (isSimple(columns) ? [columns] : columns)" :key="item1.index"></view></uni-shadow-root>`
)
assertCodegen(
'<view wx:for="{{ columns }}" wx:for-item="item1" wx:key="item1"/>',
`<view v-for="(item1,index) in (columns)" :key="item1"></view>`
`<uni-shadow-root><view v-for="(item1,index) in (columns)" :key="item1"></view></uni-shadow-root>`
)
assertCodegen(
'<view wx:for="{{ columns }}" wx:for-item="index" wx:key="*this"/>',
`<view v-for="(index,___i___) in (columns)" :key="index"></view>`
`<uni-shadow-root><view v-for="(index,___i___) in (columns)" :key="index"></view></uni-shadow-root>`
)
})
it('generate root element', () => {
......@@ -51,7 +51,7 @@ describe('wxml:compiler', () => {
assertCodegen(
`<view></view>
<wxs></wxs>`,
`<view></view>`
`<uni-shadow-root><view></view></uni-shadow-root>`
)
......
const patch = require('./patch')
module.exports = {
options: {
extname: {
template: '.wxml',
style: '.wxss'
},
shouldWrapper(filepath) {
return patch.wrapper(filepath)
}
},
transform: require('./transform'),
......
......@@ -65,26 +65,7 @@ function patchVue(file) {
}
}
const VANT_WRAPPERS = [
function test(filepath) {
return filepath.indexOf('/cell/index') !== -1
},
function test(filepath) {
return filepath.indexOf('/sticky/index') !== -1
}
]
const PATCH_WRAPPERS = [
...VANT_WRAPPERS
]
function patchWrapper(filepath) {
filepath = normalizePath(filepath)
return !!PATCH_WRAPPERS.find(test => test(filepath))
}
module.exports = {
vue: patchVue,
asset: patchAsset,
wrapper: patchWrapper
asset: patchAsset
}
......@@ -57,30 +57,6 @@ function genWxs(wxs, state) {
return [wxsCode.join('').trim(), wxsFiles]
}
function shouldWrapper(node, state) {
if (state.shouldWrapper(state.filepath)) {
return true
}
node.children = node.children.filter(child => { // remove \n
if (child.type === 'text' && !child.data.trim()) {
return false
}
return true
})
if (node.children.length > 1) { // multi root
return true
}
const rootNode = node.children[0]
if (rootNode && rootNode.name === 'slot') { // slot root
return true
}
return false
}
module.exports = function generate(node, state) {
// [`<uni-shadow-root>${genChildren(node).trim()}</uni-shadow-root>`, ...genWxs(state.wxs, state)]
// if (shouldWrapper(node, state)) {
return [`<uni-shadow-root>${genChildren(node).trim()}</uni-shadow-root>`, ...genWxs(state.wxs, state)]
// }
// return [genChildren(node).trim(), ...genWxs(state.wxs, state)]
return [`<uni-shadow-root>${genChildren(node).trim()}</uni-shadow-root>`, ...genWxs(state.wxs, state)]
}
......@@ -769,24 +769,6 @@ var polyfill = {
}
};
/**
* wxs getRegExp
*/
function getRegExp () {
const args = Array.prototype.slice.call(arguments);
args.unshift(RegExp);
return new (Function.prototype.bind.apply(RegExp, args))()
}
/**
* wxs getDate
*/
function getDate () {
const args = Array.prototype.slice.call(arguments);
args.unshift(Date);
return new (Function.prototype.bind.apply(Date, args))()
}
global['__wxRoute'] = '';
global['__wxComponents'] = Object.create(null);
global['__wxVueOptions'] = Object.create(null);
......@@ -823,4 +805,4 @@ function Behavior (options) {
const nextTick = Vue.nextTick;
export default uni;
export { Behavior, Component, Page, getDate, getRegExp, nextTick };
export { Behavior, Component, Page, nextTick };
......@@ -7,6 +7,10 @@ const {
getPlatformCompiler
} = require('@dcloudio/uni-cli-shared')
const {
getGlobalUsingComponentsCode
} = require('@dcloudio/uni-cli-shared/lib/pages')
const {
isUnaryTag,
getPartialIdentifier
......@@ -17,17 +21,23 @@ const {
// } = require('../cache-loader')
const runtimePath = '@dcloudio/uni-mp-weixin/dist/mp.js'
function getProvides () {
return {
'__f__': [path.resolve(__dirname, '../format-log.js'), 'default'],
'wx': [runtimePath, 'default'],
'wx.nextTick': [runtimePath, 'nextTick'],
'Page': [runtimePath, 'Page'],
'Component': [runtimePath, 'Component'],
'Behavior': [runtimePath, 'Behavior'],
'getDate': [runtimePath, 'getDate'],
'getRegExp': [runtimePath, 'getRegExp']
const wxsPath = '@dcloudio/uni-mp-weixin/dist/wxs.js'
function getProvides (isAppService) {
if (isAppService) {
return { // app-service
'__f__': [path.resolve(__dirname, '../format-log.js'), 'default'],
'wx': [runtimePath, 'default'],
'wx.nextTick': [runtimePath, 'nextTick'],
'Page': [runtimePath, 'Page'],
'Component': [runtimePath, 'Component'],
'Behavior': [runtimePath, 'Behavior'],
'getDate': [wxsPath, 'getDate'],
'getRegExp': [wxsPath, 'getRegExp']
}
}
return { // app-view
'getDate': [wxsPath, 'getDate'],
'getRegExp': [wxsPath, 'getRegExp']
}
}
......@@ -66,15 +76,21 @@ const v3 = {
const rules = []
const scriptLoaders = []
if (isAppView) {
rules.push({ // 解析组件,css 等
resourceQuery: /vue&type=script/,
use: [{
loader: path.resolve(__dirname,
'../../packages/webpack-uni-app-loader/view/script')
}]
scriptLoaders.push({
loader: path.resolve(__dirname,
'../../packages/webpack-uni-app-loader/view/script')
})
}
scriptLoaders.push({
loader: path.resolve(__dirname,
'../../packages/webpack-uni-app-loader/using-components')
})
rules.push({ // 解析组件,css 等
resourceQuery: /vue&type=script/,
use: scriptLoaders
})
// TODO 临时方案,将 wxs 也编译至 service
rules.push({
resourceQuery: [/lang=wxs/, /blockType=wxs/],
......@@ -124,7 +140,7 @@ const v3 = {
options: {
compiler: getPlatformCompiler(),
before: [
beforeCode + statCode
beforeCode + statCode + getGlobalUsingComponentsCode()
]
}
}]
......@@ -146,7 +162,7 @@ const v3 = {
]
},
plugins: [
new webpack.ProvidePlugin(getProvides())
new webpack.ProvidePlugin(getProvides(isAppService))
]
}
},
......
const fs = require('fs')
const path = require('path')
const webpack = require('webpack')
const webpack = require('webpack')
const {
getMainEntry,
getH5Options
} = require('@dcloudio/uni-cli-shared')
const {
getGlobalUsingComponentsCode
} = require('@dcloudio/uni-cli-shared/lib/pages')
const modifyVueLoader = require('../vue-loader')
const WebpackHtmlAppendPlugin = require('../../packages/webpack-html-append-plugin')
......@@ -23,14 +27,14 @@ const {
} = getH5Options()
const runtimePath = '@dcloudio/uni-mp-weixin/dist/mp.js'
const wxsPath = '@dcloudio/uni-mp-weixin/dist/wxs.js'
function getProvides () {
return {
'Page': [runtimePath, 'Page'],
'Component': [runtimePath, 'Component'],
'Behavior': [runtimePath, 'Behavior'],
'getDate': [runtimePath, 'getDate'],
'getRegExp': [runtimePath, 'getRegExp']
'getDate': [wxsPath, 'getDate'],
'getRegExp': [wxsPath, 'getRegExp']
}
}
......@@ -105,7 +109,7 @@ module.exports = {
loader: 'wrap-loader',
options: {
before: [
beforeCode + statCode
beforeCode + statCode + getGlobalUsingComponentsCode()
]
}
}]
......
const path = require('path')
const {
removeExt,
normalizePath
} = require('@dcloudio/uni-cli-shared')
const {
getUsingComponentsCode
} = require('@dcloudio/uni-cli-shared/lib/pages')
module.exports = function(content, map) {
this.cacheable && this.cacheable()
const resourcePath = removeExt(
normalizePath(path.relative(process.env.UNI_INPUT_DIR, this.resourcePath))
)
console.log('resourcePath:' + resourcePath)
return getUsingComponentsCode(resourcePath) + content
}
......@@ -9,6 +9,10 @@ const {
paths: [require.resolve('vue-loader')]
})) // 确保使用的与 vue-loader 一致
const {
getGlobalUsingComponentsCode
} = require('@dcloudio/uni-cli-shared/lib/pages')
const traverse = require('@dcloudio/webpack-uni-mp-loader/lib/babel/global-component-traverse')
const genStylesCode = require('../../vue-loader/lib/codegen/styleInjection')
......@@ -92,6 +96,9 @@ function getStylesCode(loaderContext) {
}
module.exports = function(source, map) {
// 追加小程序全局自定义组件(仅v3)
source = getGlobalUsingComponentsCode() + source
return `
import 'uni-pages?${JSON.stringify({type:'view'})}'
function initView(){
......
......@@ -9,6 +9,10 @@ const {
getFlexDirection
} = require('@dcloudio/uni-cli-shared')
const {
addPageUsingComponents
} = require('@dcloudio/uni-cli-shared/lib/pages')
const {
parseStyle
} = require('../../util')
......@@ -476,6 +480,8 @@ module.exports = function (pagesJson, userManifestJson) {
appJson.page = Object.create(null)
const addPage = function (pagePath, windowOptions, nvue) {
// 缓存页面级usingComponents
addPageUsingComponents(pagePath, windowOptions.usingComponents)
delete windowOptions.usingComponents
appJson.page[pagePath] = {
window: windowOptions,
......@@ -514,4 +520,4 @@ module.exports = function (pagesJson, userManifestJson) {
return [manifest, definePages(appJson), appConfigService(appJson)]
}
return [app, manifest]
}
}
......@@ -14,8 +14,6 @@ import {
import polyfill from './polyfill/index'
export * from './wxs'
global['__wxRoute'] = ''
global['__wxComponents'] = Object.create(null)
global['__wxVueOptions'] = Object.create(null)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册