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

feat: ssr

上级 67670fca
......@@ -9,6 +9,7 @@ declare var __GLOBAL__: Record<string, any>
// Global compile-time constants
declare var __DEV__: boolean
declare var __TEST__: boolean
declare var __NODE_JS__: boolean
// Feature flags
declare var __VUE_OPTIONS_API__: boolean
......
......@@ -18,7 +18,7 @@ import {
initHidpi
} from '../../helpers/hidpi'
/*#__PURE__*/ initHidpi()
!__NODE_JS__ && /*#__PURE__*/ initHidpi()
function resolveColor(color) {
color = color.slice(0)
......
......@@ -74,9 +74,11 @@ export default /*#__PURE__*/ defineComponent({
return (
<uni-image ref={rootRef}>
<div style={modeStyle} />
{imgSrc && <img src={imgSrc} draggable={props.draggable} />}
{FIX_MODES[mode as keyof typeof FIX_MODES] && (
{imgSrc ? <img src={imgSrc} draggable={props.draggable} /> : <img />}
{FIX_MODES[mode as keyof typeof FIX_MODES] ? (
<ResizeSensor onResize={fixSize} />
) : (
<span></span>
)}
</uni-image>
)
......@@ -181,7 +183,7 @@ function useImageLoader(
onBeforeUnmount(() => resetImage())
}
const isChrome = navigator.vendor === 'Google Inc.'
const isChrome = __NODE_JS__ ? false : navigator.vendor === 'Google Inc.'
function fixNumber(num: number) {
// fix: 解决 Chrome 浏览器上某些情况下导致 1px 缝隙的问题
if (isChrome && num > 10) {
......
......@@ -90,7 +90,11 @@ export default /*#__PURE__*/ defineComponent({
<div style={outerBarStyle} class="uni-progress-bar">
<div style={innerBarStyle} class="uni-progress-inner-bar" />
</div>
{showInfo ? <p class="uni-progress-info">{currentPercent}%</p> : ''}
{showInfo ? ( // {currentPercent}% 的写法会影响 SSR Hydration
<p class="uni-progress-info">{currentPercent + '%'}</p>
) : (
''
)}
</uni-progress>
)
}
......
import { hasOwn } from '@vue/shared'
export const pixelRatio = /*#__PURE__*/ (function () {
const canvas = document.createElement('canvas')
canvas.height = canvas.width = 0
const context = canvas.getContext('2d')
const backingStore =
context.backingStorePixelRatio ||
context.webkitBackingStorePixelRatio ||
context.mozBackingStorePixelRatio ||
context.msBackingStorePixelRatio ||
context.oBackingStorePixelRatio ||
context.backingStorePixelRatio ||
1
return (window.devicePixelRatio || 1) / backingStore
})()
export const pixelRatio = __NODE_JS__
? 1
: /*#__PURE__*/ (function () {
const canvas = document.createElement('canvas')
canvas.height = canvas.width = 0
const context = canvas.getContext('2d')
const backingStore =
context.backingStorePixelRatio ||
context.webkitBackingStorePixelRatio ||
context.mozBackingStorePixelRatio ||
context.msBackingStorePixelRatio ||
context.oBackingStorePixelRatio ||
context.backingStorePixelRatio ||
1
return (window.devicePixelRatio || 1) / backingStore
})()
export function wrapper(canvas) {
canvas.width = canvas.offsetWidth * pixelRatio
......
......@@ -365,9 +365,11 @@ export function useField(
useEvent(fieldRef, state, trigger, triggerInput, beforeInput)
// Safari 14 以上修正禁用状态颜色
const fixDisabledColor =
String(navigator.vendor).indexOf('Apple') === 0 &&
CSS.supports('image-orientation:from-image')
// TODO fixDisabledColor 可以调整到beforeMount或mounted做修正,确保不影响SSR
const fixDisabledColor = __NODE_JS__
? false
: String(navigator.vendor).indexOf('Apple') === 0 &&
CSS.supports('image-orientation:from-image')
return {
fieldRef,
......
......@@ -6,6 +6,9 @@ export function useListeners(
props: { id: string },
listeners: Record<string, Function>
) {
if (__NODE_JS__) {
return
}
_addListeners(props.id, listeners)
watch(
......
......@@ -26,9 +26,9 @@ interface PageCssVars {
'--window-margin'?: string
'--top-window-height'?: string
}
const style = document.documentElement.style
export function updateCssVar(cssVars: Record<string, any>) {
const style = document.documentElement.style
Object.keys(cssVars).forEach((name) => {
style.setProperty(name, cssVars[name])
})
......
......@@ -3,6 +3,9 @@ export function PolySymbol(name: string) {
}
export function rpx2px(str: string | number) {
if (__NODE_JS__) {
return parseInt(str + '')
}
if (typeof str === 'string') {
const res = parseInt(str) || 0
if (str.indexOf('rpx') !== -1 || str.indexOf('upx') !== -1) {
......
import { getEnvLocale } from '@dcloudio/uni-shared'
import { BuiltInLocale, initVueI18n } from '@dcloudio/uni-i18n'
let i18n: ReturnType<typeof initVueI18n>
export function useI18n() {
if (!i18n) {
let language: BuiltInLocale
if (__PLATFORM__ === 'h5') {
language = navigator.language as BuiltInLocale
if (__NODE_JS__) {
language = getEnvLocale() as BuiltInLocale
} else {
language = navigator.language as BuiltInLocale
}
} else if (__PLATFORM__ === 'app') {
// TODO 需替换为新API
language = plus.os.language as BuiltInLocale
......
......@@ -4,6 +4,9 @@ import { initOn } from './on'
import { initSubscribe } from './subscribe'
export * from './page'
export function initService(app: App) {
if (__NODE_JS__) {
return
}
initOn()
initSubscribe()
......
......@@ -4,6 +4,9 @@ import { initLongPress } from './longPress'
import { initAppConfig } from './appConfig'
export function initView(app: App) {
if (__NODE_JS__) {
return
}
if (__UNI_FEATURE_LONGPRESS__) {
initLongPress()
}
......
此差异已折叠。
此差异已折叠。
......@@ -25,17 +25,11 @@ import TabBar from './tabBar'
type KeepAliveRoute = ReturnType<typeof useKeepAliveRoute>
const DEFAULT_CSS_VAR_VALUE = '0px'
updateCssVar({
'--status-bar-height': DEFAULT_CSS_VAR_VALUE,
'--top-window-height': DEFAULT_CSS_VAR_VALUE,
'--window-left': DEFAULT_CSS_VAR_VALUE,
'--window-right': DEFAULT_CSS_VAR_VALUE,
'--window-margin': DEFAULT_CSS_VAR_VALUE,
'--tab-bar-height': DEFAULT_CSS_VAR_VALUE,
})
export default defineComponent({
name: 'Layout',
setup(_props, { emit }) {
!__NODE_JS__ && initCssVar()
const keepAliveRoute = (__UNI_FEATURE_PAGES__ &&
useKeepAliveRoute()) as KeepAliveRoute
const topWindow = __UNI_FEATURE_TOPWINDOW__ && useTopWindow()
......@@ -52,7 +46,12 @@ export default defineComponent({
rightWindow
)
const tabBarTsx = __UNI_FEATURE_TABBAR__ && createTabBarTsx(showTabBar)
return <uni-app class={clazz.value}>{[layoutTsx, tabBarTsx]}</uni-app>
return (
<uni-app class={clazz.value}>
{layoutTsx}
{tabBarTsx}
</uni-app>
)
}
},
})
......@@ -67,6 +66,17 @@ function useAppClass(showTabBar?: ComputedRef<boolean>) {
})
}
function initCssVar() {
updateCssVar({
'--status-bar-height': DEFAULT_CSS_VAR_VALUE,
'--top-window-height': DEFAULT_CSS_VAR_VALUE,
'--window-left': DEFAULT_CSS_VAR_VALUE,
'--window-right': DEFAULT_CSS_VAR_VALUE,
'--window-margin': DEFAULT_CSS_VAR_VALUE,
'--tab-bar-height': DEFAULT_CSS_VAR_VALUE,
})
}
function createLayoutTsx(
keepAliveRoute: KeepAliveRoute,
topWindow?: unknown,
......@@ -106,9 +116,10 @@ function useShowTabBar(emit: SetupContext<['change']>['emit']) {
const tabBar = useTabBar()!
// TODO meida query
const showTabBar = computed(() => route.meta.isTabBar && tabBar.shown)
updateCssVar({
'--tab-bar-height': tabBar.height!,
})
!__NODE_JS__ &&
updateCssVar({
'--tab-bar-height': tabBar.height!,
})
return showTabBar
}
......
......@@ -11,13 +11,12 @@ import {
import PageHead from './pageHead'
import PageBody from './pageBody'
import { providePageMeta } from '../../setup/provide'
import { getStateId } from '../../../helpers/dom'
export default defineComponent({
name: 'Page',
setup(_props, ctx) {
const { navigationBar } = providePageMeta(
(history.state && history.state.__id__) || 1
)
const { navigationBar } = providePageMeta(getStateId())
return () =>
createVNode(
'uni-page',
......
......@@ -16,7 +16,9 @@ export default defineComponent({
ref(null)) as Ref<null>
const pageRefresh =
__UNI_FEATURE_PULL_DOWN_REFRESH__ && pageMeta.enablePullDownRefresh
!__NODE_JS__ &&
__UNI_FEATURE_PULL_DOWN_REFRESH__ &&
pageMeta.enablePullDownRefresh
? usePageRefresh(refreshRef)
: null
......@@ -25,12 +27,12 @@ export default defineComponent({
__UNI_FEATURE_PULL_DOWN_REFRESH__ &&
createPageRefreshTsx(refreshRef, pageMeta)
return (
<>
<div>
{pageRefreshTsx}
<uni-page-wrapper {...pageRefresh}>
<uni-page-body>{renderSlot(ctx.slots, 'default')}</uni-page-body>
</uni-page-wrapper>
</>
</div>
)
}
},
......
......@@ -4,6 +4,7 @@ import {
createRouter,
createWebHistory,
createWebHashHistory,
createMemoryHistory,
} from 'vue-router'
import { getCurrentPages, normalizeRouteKey, removePage } from '../setup/page'
......@@ -44,6 +45,9 @@ function removeCurrentPages(delta: number = 1) {
}
function initHistory() {
if (__NODE_JS__) {
return createMemoryHistory()
}
const history =
__UNI_FEATURE_ROUTER_MODE__ === 'history'
? createWebHistory()
......
......@@ -60,7 +60,13 @@ export function setupPage(comp: any) {
//初始化时,状态肯定是激活
instance.__isActive = true
}
// node环境不触发Page生命周期
if (__NODE_JS__) {
return route.query
}
const pageMeta = usePageMeta()
onBeforeMount(() => {
onPageShow(instance, pageMeta)
const { onLoad, onShow } = instance
......@@ -88,6 +94,7 @@ export function setupPage(comp: any) {
onHide && invokeArrayFns(onHide)
}
})
return route.query
},
})
......@@ -98,6 +105,10 @@ export function setupApp(comp: any) {
init: initApp,
setup(instance) {
const route = usePageRoute()
// node环境不触发App生命周期
if (__NODE_JS__) {
return route.query
}
const onLaunch = () => {
const { onLaunch, onShow } = instance
const path = route.path.substr(1)
......
......@@ -17,6 +17,7 @@ import { ON_REACH_BOTTOM_DISTANCE } from '@dcloudio/uni-shared'
import { usePageMeta } from './provide'
import { NavigateType } from '../../service/api/route/utils'
import { updateCurPageCssVar } from '../../helpers/cssVar'
import { getStateId } from '../../helpers/dom'
const SEP = '$$'
......@@ -65,7 +66,7 @@ export function removePage(routeKey: string, removeRouteCaches = true) {
removeRouteCaches && removeRouteCache(routeKey)
}
let id = /*#__PURE__*/ (() => (history.state && history.state.__id__) || 1)()
let id = /*#__PURE__*/ getStateId()
export function createPageState(type: NavigateType, __id__?: number) {
return {
......@@ -116,9 +117,7 @@ export function normalizeRouteKey(path: string, id: number) {
export function useKeepAliveRoute() {
const route = useRoute()
const routeKey = computed(() =>
normalizeRouteKey(route.path, history.state.__id__ || 1)
)
const routeKey = computed(() => normalizeRouteKey(route.path, getStateId()))
const isTabBar = computed(() => route.meta.isTabBar)
return {
routeKey,
......
......@@ -94,7 +94,7 @@ function normalizePageMeta(pageMeta: UniApp.PageRouteMeta) {
let offset = rpx2px(refreshOptions.offset)
const { type } = navigationBar
if (type !== 'transparent' && type !== 'none') {
offset += NAVBAR_HEIGHT + safeAreaInsets.top
offset += NAVBAR_HEIGHT + (__NODE_JS__ ? 0 : safeAreaInsets.top)
}
refreshOptions.offset = offset
refreshOptions.height = rpx2px(refreshOptions.height)
......@@ -110,7 +110,7 @@ function normalizePageMeta(pageMeta: UniApp.PageRouteMeta) {
navigationBar.titleColor = titleColor || '#fff'
navigationBar.backgroundColor = backgroundColor || '#F7F7F7'
}
if (__UNI_FEATURE_PAGES__ && history.state) {
if (!__NODE_JS__ && __UNI_FEATURE_PAGES__ && history.state) {
// 首页执行了redirectTo
const type = history.state.__type__
if (
......
......@@ -12,3 +12,10 @@ export function checkMinWidth(minWidth: number) {
]
return Math.max.apply(null, sizes) > minWidth
}
export function getStateId() {
if (__NODE_JS__) {
return 1
}
return (history.state && history.state.__id__) || 1
}
......@@ -16,12 +16,16 @@ function cssSupports(css: string) {
)
}
export const cssVar = /*#__PURE__*/ cssSupports('--a:0')
export const cssEnv = /*#__PURE__*/ cssSupports('top:env(a)')
export const cssConstant = /*#__PURE__*/ cssSupports('top:constant(a)')
export const cssBackdropFilter = /*#__PURE__*/ cssSupports(
'backdrop-filter:blur(10px)'
)
export const cssVar = __NODE_JS__ ? true : /*#__PURE__*/ cssSupports('--a:0')
export const cssEnv = __NODE_JS__
? true
: /*#__PURE__*/ cssSupports('top:env(a)')
export const cssConstant = __NODE_JS__
? true
: /*#__PURE__*/ cssSupports('top:constant(a)')
export const cssBackdropFilter = __NODE_JS__
? true
: /*#__PURE__*/ cssSupports('backdrop-filter:blur(10px)')
const SCHEMA_CSS = {
'css.var': cssVar,
......
//#if _NODE_JS_
export * from './network/request'
//#else
export * from './base/canIUse'
export * from './context/createInnerAudioContext'
......@@ -58,3 +61,4 @@ export {
createMapContext,
onTabBarMidButtonTap,
} from '@dcloudio/uni-api'
//#endif
import { defineComponent, inject, onUnmounted, reactive } from 'vue'
import { useCustomEvent } from '@dcloudio/uni-components'
//#if !_NODE_JS_
import {
onCompassChange,
offCompassChange,
getLocation,
} from '../../../service/api'
//#endif
import { Map } from './qqMap/types'
import { QQMapsExt } from './qqMap'
import MapMarker from './MapMarker'
......@@ -39,49 +41,51 @@ const ICON_PATH =
export default /*#__PURE__*/ defineComponent({
name: 'MapLocation',
setup() {
const onMapReady: OnMapReady = inject('onMapReady') as OnMapReady
const state: State = reactive({
latitude: 0,
longitude: 0,
rotate: 0,
})
let timer: number
function compassChangeHandler(res: { direction: number }) {
state.rotate = res.direction
}
function updateLocation() {
getLocation({
type: 'gcj02',
success: (res) => {
state.latitude = res.latitude
state.longitude = res.longitude
},
complete: () => {
timer = setTimeout(updateLocation, 30000)
},
})
}
function removeLocation() {
if (timer) {
clearTimeout(timer)
if (!__NODE_JS__) {
const onMapReady: OnMapReady = inject('onMapReady') as OnMapReady
let timer: number
function compassChangeHandler(res: { direction: number }) {
state.rotate = res.direction
}
offCompassChange(compassChangeHandler)
}
onCompassChange(compassChangeHandler)
onMapReady(updateLocation)
onUnmounted(removeLocation)
const addMapChidlContext: AddMapChidlContext = inject(
'addMapChidlContext'
) as AddMapChidlContext
const removeMapChidlContext: RemoveMapChidlContext = inject(
'removeMapChidlContext'
) as RemoveMapChidlContext
const context: Context = {
id: CONTEXT_ID,
state,
function updateLocation() {
getLocation({
type: 'gcj02',
success: (res) => {
state.latitude = res.latitude
state.longitude = res.longitude
},
complete: () => {
timer = setTimeout(updateLocation, 30000)
},
})
}
function removeLocation() {
if (timer) {
clearTimeout(timer)
}
offCompassChange(compassChangeHandler)
}
onCompassChange(compassChangeHandler)
onMapReady(updateLocation)
onUnmounted(removeLocation)
const addMapChidlContext: AddMapChidlContext = inject(
'addMapChidlContext'
) as AddMapChidlContext
const removeMapChidlContext: RemoveMapChidlContext = inject(
'removeMapChidlContext'
) as RemoveMapChidlContext
const context: Context = {
id: CONTEXT_ID,
state,
}
addMapChidlContext(context)
onUnmounted(() => removeMapChidlContext(context))
}
addMapChidlContext(context)
onUnmounted(() => removeMapChidlContext(context))
return () => {
return state.latitude ? (
<MapMarker
......
......@@ -2,6 +2,7 @@ import path from 'path'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import jscc from 'rollup-plugin-jscc'
import replace from '@rollup/plugin-replace'
import { isCustomElement } from '../uni-shared'
......@@ -17,6 +18,8 @@ function resolve(file: string) {
return path.resolve(__dirname, file)
}
const FORMAT = process.env.FORMAT as 'es' | 'cjs'
export default defineConfig({
root: __dirname,
define: {
......@@ -24,7 +27,7 @@ export default defineConfig({
__DEV__: `(process.env.NODE_ENV !== 'production')`,
__TEST__: false,
__PLATFORM__: JSON.stringify('h5'),
__NODE_JS__: `import.meta.env.SSR`,
__NODE_JS__: FORMAT === 'cjs' ? true : false,
},
resolve: {
alias: [
......@@ -61,14 +64,14 @@ export default defineConfig({
vueJsx({ optimize: true, isCustomElement }),
],
build: {
emptyOutDir: FORMAT === 'es',
minify: false,
lib: {
entry: path.resolve(__dirname, 'src/index.ts'),
formats: ['es', 'cjs'],
formats: [FORMAT],
},
assetsDir: '.',
rollupOptions: {
// input: path.resolve(__dirname, 'src/index.ts'),
external(source) {
if (
[
......@@ -87,21 +90,24 @@ export default defineConfig({
},
preserveEntrySignatures: 'strict',
plugins: [
// replace({
// values: {
// // extend: `/*#__PURE__*/ extend`,
// // defineOnApi: `/*#__PURE__*/ defineOnApi`,
// // defineOffApi: `/*#__PURE__*/ defineOffApi`,
// // defineTaskApi: `/*#__PURE__*/ defineTaskApi`,
// // defineSyncApi: `/*#__PURE__*/ defineSyncApi`,
// // defineAsyncApi: `/*#__PURE__*/ defineAsyncApi`,
// },
// preventAssignment: true,
// }),
replace({
values: {
defineOnApi: `/*#__PURE__*/ defineOnApi`,
defineOffApi: `/*#__PURE__*/ defineOffApi`,
defineTaskApi: `/*#__PURE__*/ defineTaskApi`,
defineSyncApi: `/*#__PURE__*/ defineSyncApi`,
defineAsyncApi: `/*#__PURE__*/ defineAsyncApi`,
},
preventAssignment: true,
}),
jscc({
values: {
// 该插件限制了不能以__开头
_NODE_JS_: FORMAT === 'cjs' ? 1 : 0,
},
}),
],
// output: {
// dir: path.resolve(__dirname, 'dist'),
// },
},
},
})
......@@ -297,6 +297,12 @@ const RESPONSIVE_MIN_WIDTH = 768;
const COMPONENT_NAME_PREFIX = 'VUni';
const PRIMARY_COLOR = '#007aff';
function getEnvLocale() {
const { env } = process;
const lang = env.LC_ALL || env.LC_MESSAGES || env.LANG || env.LANGUAGE;
return (lang && lang.replace(/[.:].*/, '')) || 'en';
}
exports.BUILT_IN_TAGS = BUILT_IN_TAGS;
exports.COMPONENT_NAME_PREFIX = COMPONENT_NAME_PREFIX;
exports.COMPONENT_PREFIX = COMPONENT_PREFIX;
......@@ -312,6 +318,7 @@ exports.addFont = addFont;
exports.debounce = debounce;
exports.decode = decode;
exports.decodedQuery = decodedQuery;
exports.getEnvLocale = getEnvLocale;
exports.getLen = getLen;
exports.invokeArrayFns = invokeArrayFns;
exports.isBuiltInComponent = isBuiltInComponent;
......
......@@ -26,6 +26,8 @@ export declare function decode(text: string | number): string;
export declare function decodedQuery(query?: Record<string, any>): Record<string, string>;
export declare function getEnvLocale(): string;
export declare function getLen(str?: string): number;
export declare const invokeArrayFns: (fns: Function[], arg?: any) => any;
......
......@@ -293,4 +293,10 @@ const RESPONSIVE_MIN_WIDTH = 768;
const COMPONENT_NAME_PREFIX = 'VUni';
const PRIMARY_COLOR = '#007aff';
export { BUILT_IN_TAGS, COMPONENT_NAME_PREFIX, COMPONENT_PREFIX, COMPONENT_SELECTOR_PREFIX, NAVBAR_HEIGHT, ON_REACH_BOTTOM_DISTANCE, PLUS_RE, PRIMARY_COLOR, RESPONSIVE_MIN_WIDTH, TABBAR_HEIGHT, TAGS, addFont, debounce, decode, decodedQuery, getLen, invokeArrayFns, isBuiltInComponent, isCustomElement, isNativeTag, normalizeDataset, normalizeTarget, once, parseQuery, passive, plusReady, removeLeadingSlash, scrollTo, stringifyQuery, updateElementStyle };
function getEnvLocale() {
const { env } = process;
const lang = env.LC_ALL || env.LC_MESSAGES || env.LANG || env.LANGUAGE;
return (lang && lang.replace(/[.:].*/, '')) || 'en';
}
export { BUILT_IN_TAGS, COMPONENT_NAME_PREFIX, COMPONENT_PREFIX, COMPONENT_SELECTOR_PREFIX, NAVBAR_HEIGHT, ON_REACH_BOTTOM_DISTANCE, PLUS_RE, PRIMARY_COLOR, RESPONSIVE_MIN_WIDTH, TABBAR_HEIGHT, TAGS, addFont, debounce, decode, decodedQuery, getEnvLocale, getLen, invokeArrayFns, isBuiltInComponent, isCustomElement, isNativeTag, normalizeDataset, normalizeTarget, once, parseQuery, passive, plusReady, removeLeadingSlash, scrollTo, stringifyQuery, updateElementStyle };
......@@ -5,3 +5,5 @@ export * from './utils'
export * from './query'
export * from './debounce'
export * from './constants'
export * from './node/locale'
export function getEnvLocale() {
const { env } = process
const lang = env.LC_ALL || env.LC_MESSAGES || env.LANG || env.LANGUAGE
return (lang && lang.replace(/[.:].*/, '')) || 'en'
}
......@@ -29,6 +29,7 @@
"jsonc-parser": "^3.0.0",
"magic-string": "^0.25.7",
"mime": "^2.5.2",
"module-alias": "^2.2.2",
"postcss-selector-parser": "^6.0.4",
"rollup-plugin-copy": "^3.4.0",
"slash": "^3.0.0"
......@@ -41,6 +42,7 @@
},
"devDependencies": {
"@types/mime": "^2.0.3",
"@types/module-alias": "^2.0.0",
"@types/sass": "^1.16.0",
"@vue/compiler-sfc": "^3.0.11"
},
......
......@@ -8,13 +8,18 @@ import { initFeatures } from '../utils'
export function createDefine(
{ inputDir, platform }: VitePluginUniResolvedOptions,
{ server }: UserConfig,
{ command }: ConfigEnv
): UserConfig['define'] {
return initFeatures({
const features = initFeatures({
inputDir,
command,
platform,
pagesJson: parsePagesJsonOnce(inputDir, platform),
manifestJson: parseManifestJsonOnce(inputDir),
})
if (server && server.middlewareMode) {
Object.assign(globalThis, features)
}
return features
}
......@@ -28,7 +28,7 @@ export function createConfig(
options.platform = (process.env.UNI_PLATFORM as UniApp.PLATFORM) || 'h5'
options.inputDir = normalizeInputDir(config)
options.compiler.init()
const define = createDefine(options, env)
const define = createDefine(options, config, env)
return {
define: extend(define, options.compiler.define()),
resolve: createResolve(options, config),
......
import { ResolvedConfig } from 'vite'
import { parserOptions } from '@vue/compiler-dom'
import { isNativeTag } from '@dcloudio/uni-shared'
// import alias from 'module-alias'
export function initConfig(config: ResolvedConfig) {
if (config.server.middlewareMode) {
// TODO compiler-ssr时,传入的 isNativeTag 会被 @vue/compiler-dom 的 isNativeTag 覆盖
// https://github.com/vuejs/vue-next/blob/master/packages/compiler-ssr/src/index.ts#L36
parserOptions.isNativeTag = isNativeTag
}
// let ssr = (config as any).ssr as SSROptions
// if (!ssr) {
// ssr = {}
// }
// if (ssr.external) {
// const index = ssr.external.findIndex((name) => name === 'vue')
// if (index !== -1) {
// ssr.external.splice(index, 1)
// }
// }
// if (!ssr.noExternal) {
// ssr.noExternal = ['vue']
// } else if (!ssr.noExternal.includes('vue')) {
// ssr.noExternal.push('vue')
// }
}
......@@ -4,15 +4,16 @@ import { VitePluginUniResolvedOptions } from '..'
import { initEnv } from './env'
import { initLogger } from './logger'
import { initConfig } from './config'
import { initOptions } from './options'
import { initPlugins } from './plugins'
export function createConfigResolved(options: VitePluginUniResolvedOptions) {
return ((config) => {
initEnv(config)
initConfig(config)
initOptions(options, config)
initPlugins(config, options)
if (options.command === 'serve') {
initLogger(config)
}
......
......@@ -145,7 +145,7 @@ export function initPlugins(
addPlugin(plugins, uniPageVuePlugin(options), 'vite:vue')
addPlugin(plugins, uniJsonPlugin(options), 'vite:json', 'pre')
addPlugin(plugins, uniStaticPlugin(options, config), 'vite:asset', 'pre')
if (command === 'build') {
if (command === 'build' && !config.build.ssr) {
addPlugin(plugins, uniCopyPlugin(options), plugins.length)
}
if (process.env.DEBUG) {
......
......@@ -15,7 +15,7 @@ export function uniMainJsPlugin(options: VitePluginUniResolvedOptions): Plugin {
let wrapperCode = `function createApp(rootComponent,rootProps){return createVueApp(rootComponent, rootProps).use(plugin)}`
if (code.includes('createSSRApp')) {
code = code.replace('createSSRApp', 'createVueSSRApp')
wrapperCode = `function createSSRApp(rootComponent,rootProps){return createVueSSRApp(rootComponent, rootProps).use(plugin)}`
wrapperCode = `function createSSRApp(App){return createVueSSRApp(App).use(plugin)}`
} else {
code = code.replace('createApp', 'createVueApp')
}
......
......@@ -29,13 +29,17 @@ export function uniPagesJsonPlugin(
return pagesJsonPath + '.js'
}
},
transform(code, id) {
transform(code, id, ssr) {
if (id.endsWith(PAGES_JSON_JS)) {
return {
code:
(config.define!.__UNI_FEATURE_RPX__ ? registerGlobalCode : '') +
(options.command === 'serve' ? registerDevServerGlobalCode : '') +
generatePagesJsonCode(code, config, options),
(config.define!.__UNI_FEATURE_RPX__
? registerGlobalCode(ssr)
: '') +
(options.command === 'serve'
? registerDevServerGlobalCode(ssr)
: '') +
generatePagesJsonCode(ssr, code, config, options),
map: { mappings: '' },
}
}
......@@ -55,14 +59,16 @@ interface PageRouteOptions {
}
function generatePagesJsonCode(
ssr: boolean | undefined,
jsonStr: string,
config: ResolvedConfig,
options: VitePluginUniResolvedOptions
) {
const globalName = getGlobal(ssr)
const pagesJson = normalizePagesJson(jsonStr, options.platform)
const definePagesCode = generatePagesDefineCode(pagesJson, config)
const uniRoutesCode = generateRoutes(pagesJson)
const uniConfigCode = generateConfig(pagesJson, options)
const uniRoutesCode = generateRoutes(globalName, pagesJson)
const uniConfigCode = generateConfig(globalName, pagesJson, options)
const manifestJsonPath = slash(
path.resolve(options.inputDir, 'manifest.json.js')
)
......@@ -90,17 +96,26 @@ const hmrCode = `if(import.meta.hot){
})
}`
const registerGlobalCode = `import {upx2px} from '@dcloudio/uni-h5'
window.rpx2px = upx2px
`
function getGlobal(ssr?: boolean) {
return ssr ? 'global' : 'window'
}
const registerDevServerGlobalCode = `import {uni,getCurrentPages,getApp,UniServiceJSBridge,UniViewJSBridge} from '@dcloudio/uni-h5'
window.getApp = getApp
window.getCurrentPages = getCurrentPages
window.uni = uni
window.UniViewJSBridge = UniViewJSBridge
window.UniServiceJSBridge = UniServiceJSBridge
function registerGlobalCode(ssr?: boolean) {
const name = getGlobal(ssr)
return `import {upx2px} from '@dcloudio/uni-h5'
${name}.rpx2px = upx2px
`
}
function registerDevServerGlobalCode(ssr?: boolean) {
const name = getGlobal(ssr)
return `import {uni,getCurrentPages,getApp,UniServiceJSBridge,UniViewJSBridge} from '@dcloudio/uni-h5'
${name}.getApp = getApp
${name}.getCurrentPages = getCurrentPages
${name}.uni = uni
${name}.UniViewJSBridge = UniViewJSBridge
${name}.UniServiceJSBridge = UniServiceJSBridge
`
}
function normalizePageIdentifier(path: string) {
return capitalize(camelize(path.replace(/\//g, '-')))
......@@ -220,17 +235,18 @@ function generatePagesRoute(pagesRouteOptions: PageRouteOptions[]) {
return pagesRouteOptions.map((pageOptions) => generatePageRoute(pageOptions))
}
function generateRoutes(pagesJson: UniApp.PagesJson) {
function generateRoutes(globalName: string, pagesJson: UniApp.PagesJson) {
return `
function renderPage(component){
return (openBlock(), createBlock(PageComponent, null, {page: withCtx(() => [createVNode(component, { ref: "page" }, null, 512 /* NEED_PATCH */)]), _: 1 /* STABLE */}))
}
window.__uniRoutes=[${[
${globalName}.__uniRoutes=[${[
...generatePagesRoute(normalizePagesRoute(pagesJson)),
].join(',')}]`
}
function generateConfig(
globalName: string,
pagesJson: Record<string, any>,
options: VitePluginUniResolvedOptions
) {
......@@ -241,10 +257,10 @@ function generateConfig(
return (
(options.command === 'serve'
? ''
: `window['____'+appid+'____']=true
delete window['____'+appid+'____']
: `${globalName}['____'+appid+'____']=true
delete ${globalName}['____'+appid+'____']
`) +
`window.__uniConfig=Object.assign(${JSON.stringify(pagesJson)},{
`${globalName}.__uniConfig=Object.assign(${JSON.stringify(pagesJson)},{
async,
debug,
networkTimeout,
......
function serializeDefine(define: Record<string, any>): string {
let res = `{`
for (const key in define) {
const val = define[key]
res += `${JSON.stringify(key)}: ${
typeof val === 'string' ? `(${val})` : JSON.stringify(val)
}, `
}
return res + `}`
}
export function generateSSREnvCode(define: Record<string, any>): string {
return envCode.replace('__DEFINES__', serializeDefine(define))
}
const envCode = `const context = (() => {
if (typeof globalThis !== 'undefined') {
return globalThis;
}
else if (typeof self !== 'undefined') {
return self;
}
else if (typeof window !== 'undefined') {
return window;
}
else {
return Function('return this')();
}
})();
// assign defines
const defines = __DEFINES__;
Object.keys(defines).forEach((key) => {
const segments = key.split('.');
let target = context;
for (let i = 0; i < segments.length; i++) {
const segment = segments[i];
if (i === segments.length - 1) {
target[segment] = defines[key];
}
else {
target = target[segment] || (target[segment] = {});
}
}
});`
......@@ -85,7 +85,7 @@ function createConfig(entryFile, output, plugins = []) {
namedExports: false,
}),
tsPlugin,
createReplacePlugin(buildOptions),
createReplacePlugin(buildOptions, output.format),
...plugins,
],
output,
......@@ -113,10 +113,11 @@ function createAliasPlugin(buildOptions) {
return alias(buildOptions.alias || {})
}
function createReplacePlugin(buildOptions) {
function createReplacePlugin(buildOptions, format) {
const replacements = {
__DEV__: `(process.env.NODE_ENV !== 'production')`,
__TEST__: false,
__NODE_JS__: format === 'cjs',
}
if (buildOptions.replacements) {
Object.assign(replacements, buildOptions.replacements)
......
......@@ -56,11 +56,20 @@ async function build(target) {
const env = devOnly ? 'development' : 'production'
if (bundler === 'vite') {
await execa(
'vite',
['build', '--config', path.resolve(pkgDir, 'vite.config.ts')],
{
stdio: 'inherit',
env: Object.assign({ FORMAT: 'es' }, process.env),
}
)
return await execa(
'vite',
['build', '--config', path.resolve(pkgDir, 'vite.config.ts')],
{
stdio: 'inherit',
env: Object.assign({ FORMAT: 'cjs' }, process.env),
}
)
} else if (bundler === 'tsc') {
......
......@@ -543,6 +543,16 @@
"@types/yargs" "^15.0.0"
chalk "^4.0.0"
"@jsbits/escape-regex-str@^1.0.2":
version "1.0.3"
resolved "https://registry.yarnpkg.com/@jsbits/escape-regex-str/-/escape-regex-str-1.0.3.tgz#d35a2d21dfdc81a0e5ebeb68b6a16e17ca36ad20"
integrity sha512-0800vYI2fg1nuUq/T9Tqv8DMOLLNiRAltxFbKIbR7szrvW6qTuI2+zGK51hV7NAAmUr4G83Kvpj2R6Yyg07iIw==
"@jsbits/get-package-version@^1.0.2", "@jsbits/get-package-version@^1.0.3":
version "1.0.3"
resolved "https://registry.yarnpkg.com/@jsbits/get-package-version/-/get-package-version-1.0.3.tgz#a47dfd077420beee435580c3bc197931fe3c694c"
integrity sha512-IJy1jRL01x7p6UEpgKa1lVLstMUx8EiIR8pPoS5sBfsHEoeLkzYiNpAfxPx8zLDUJyS1yBbChJjcWdPqyH285w==
"@microsoft/api-extractor-model@7.13.0":
version "7.13.0"
resolved "https://registry.yarnpkg.com/@microsoft/api-extractor-model/-/api-extractor-model-7.13.0.tgz#11327c1ab32939a375596859a27ec256eb17d68e"
......@@ -869,6 +879,11 @@
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.4.tgz#f0ec25dbf2f0e4b18647313ac031134ca5b24b21"
integrity sha512-1z8k4wzFnNjVK/tlxvrWuK5WMt6mydWWP7+zvH5eFep4oj+UkrfiJTRtjCeBXNpwaA/FYqqtb4/QS4ianFpIRA==
"@types/module-alias@^2.0.0":
version "2.0.0"
resolved "https://registry.yarnpkg.com/@types/module-alias/-/module-alias-2.0.0.tgz#882668f8b8cdbda44812c3b592c590909e18849e"
integrity sha512-e3sW4oEH0qS1QxSfX7PT6xIi5qk/YSMsrB9Lq8EtkhQBZB+bKyfkP+jpLJRySanvBhAQPSv2PEBe81M8Iy/7yg==
"@types/node@*":
version "15.0.1"
resolved "https://registry.yarnpkg.com/@types/node/-/node-15.0.1.tgz#ef34dea0881028d11398be5bf4e856743e3dc35a"
......@@ -3838,6 +3853,17 @@ jsbn@~0.1.0:
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM=
jscc@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/jscc/-/jscc-1.1.1.tgz#fb329325773a80bcf3e3db3acec6a3f21e61ed0e"
integrity sha512-anpZkTXwZbxfxLEBMciKxXMHx2xOLK2qhynIhTnoSyC+wGOEPrAoofxnADgblbarn0kijVMt1U71cQGmRF/1Og==
dependencies:
"@jsbits/escape-regex-str" "^1.0.2"
"@jsbits/get-package-version" "^1.0.2"
magic-string "^0.25.1"
perf-regexes "^1.0.1"
skip-regex "^1.0.2"
jsdom@^16.4.0:
version "16.5.3"
resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.5.3.tgz#13a755b3950eb938b4482c407238ddf16f0d2136"
......@@ -4241,7 +4267,7 @@ magic-string@^0.22.5:
dependencies:
vlq "^0.2.2"
magic-string@^0.25.7:
magic-string@^0.25.1, magic-string@^0.25.7:
version "0.25.7"
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.7.tgz#3f497d6fd34c669c6798dcb821f2ef31f5445051"
integrity sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==
......@@ -4772,6 +4798,11 @@ pend@~1.2.0:
resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50"
integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA=
perf-regexes@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/perf-regexes/-/perf-regexes-1.0.1.tgz#6da1d62f5a94bf9353a0451bccacf69068b75d0b"
integrity sha512-L7MXxUDtqr4PUaLFCDCXBfGV/6KLIuSEccizDI7JxT+c9x1G1v04BQ4+4oag84SHaCdrBgQAIs/Cqn+flwFPng==
performance-now@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
......@@ -5268,6 +5299,15 @@ rollup-plugin-copy@^3.4.0:
globby "10.0.1"
is-plain-object "^3.0.0"
rollup-plugin-jscc@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/rollup-plugin-jscc/-/rollup-plugin-jscc-2.0.0.tgz#1ad2f74ab3248dcaaa5ebff0b838418e22243ce6"
integrity sha512-5jG9q79K2u5uRBTKA+GA4gqt1zA7qHQRpcabZMoVs913gr75s428O7K3r58n2vADDzwIhiOKMo7rCMhOyks6dw==
dependencies:
"@jsbits/get-package-version" "^1.0.3"
jscc "^1.1.1"
rollup-pluginutils "^2.8.2"
rollup-plugin-node-builtins@^2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/rollup-plugin-node-builtins/-/rollup-plugin-node-builtins-2.1.2.tgz#24a1fed4a43257b6b64371d8abc6ce1ab14597e9"
......@@ -5512,6 +5552,11 @@ size-limit@^4.10.1:
ora "^5.4.0"
read-pkg-up "^7.0.1"
skip-regex@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/skip-regex/-/skip-regex-1.0.2.tgz#ac655d77e7c771ac2b9f37585fea37bff56ad65b"
integrity sha512-pEjMUbwJ5Pl/6Vn6FsamXHXItJXSRftcibixDmNCWbWhic0hzHrwkMZo0IZ7fMRH9KxcWDFSkzhccB4285PutA==
slash@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册