【UWP】使用 Vue/Vite 编写 WinJS/UWP
,由于 MSAppHost 是系统组件,所以只用打包 Web 资源就行了。WinJS 曾作为 WSA (Windows Store App) 的主推平台,甚至 Win8 应用商店都是 JS/HTML 开发的,不过在进入 Win10 之后,有了 .NET Native 的加持,C#/UWP 逐渐变为主流,MSAppHost 基本上只剩下了作为 PWA 的用途。然而随着 Edge HTML 的停更,Windows 再也没有了原生的 HTML 渲染平台,微软也在 VS 2019 中彻底删除了对 WinJS 的支持。
不过 MSAppHost 框架作为系统组件并没有被删除,利用 electron-windows-msix 插件,我们可以轻松打包一个 NPM 项目,我们只需要将清单改为 MSAppHost 模式即可。接下来我们将演示如何新建一个 Vue/UWP 项目。
首先我们根据 Vue 官方教程新建一个空白 Vue 项目:
npm create vue@latest |
进入项目文件夹后安装依赖:
npm i |
然后我们测试一下它是否可以正常运行:
npm run dev |
由于 MSAppHost 永远留在了 Edge HTML 18,所以我们需要把 JS 编译到 Edge 18 兼容的版本,安装 @vitejs/plugin-legacy:
npm i --save-dev @vitejs/plugin-legacy |
在vite.config.ts配置插件,由于vite使用到了新版 ESM 模块特性,所以 Edge 只能使用 Legacy 模式,注意base一定要设置为./,因为打包插件会把编译结果打包进app文件夹:
import legacy from '@vitejs/plugin-legacy' |
... |
export default defineConfig({ |
base: './', |
plugins: [ |
... |
legacy({ |
targets: 'Edge >= 18', |
polyfills: true, |
renderModernChunks: false |
}) |
], |
... |
}) |
验证可以正常运行后,我们安装 electron-windows-msix 插件:
npm i --save-dev electron-windows-msix |
然后编写打包脚本,可以参考 package.mjs:
import { packageMSIX } from "electron-windows-msix"; |
/** @type {import("electron-windows-msix").WindowsSignOptions} */ |
let windowsSignOptions = undefined; |
const certificateFileIndex = process.argv.indexOf("--certificateFile"); |
if (certificateFileIndex != -1) { |
windowsSignOptions = { |
certificateFile: process.argv[certificateFileIndex + 1] |
}; |
const certificatePasswordIndex = process.argv.indexOf("--certificatePassword"); |
if (certificatePasswordIndex != -1) { |
windowsSignOptions.certificatePassword = process.argv[certificatePasswordIndex + 1]; |
} |
const timestampServerIndex = process.argv.indexOf("--timestampServer"); |
if (timestampServerIndex != -1) { |
windowsSignOptions.timestampServer = process.argv[timestampServerIndex + 1]; |
} |
} |
const { msixPackage } = await packageMSIX({ |
appManifest: "AppxManifest.xml", |
appDir: "dist", |
packageAssets: "assets", |
outputDir: "appx", |
packageName: "VueForUWP.msix", |
windowsKitVersion: "10.0.26100.0", |
windowsSignOptions, |
sign: !!windowsSignOptions |
}); |
console.log(`MSIX package created at: ${msixPackage}`); |
其中appManifest是 Appx 清单的路径;appDir是vite编译结果文件夹;packageAssets是 Appx 资源文件夹,如果不设置会使用插件默认的资源,下面的 Appx 清单使用的就是默认资源;windowsKitVersion需要选择已安装的 Windows SDK 版本。
由于默认清单是 FullTrust Win32 打包项目,所以我们需要手动编写清单,新建 AppxManifest.xml 文件:
<?xml version="1.0" encoding="utf-8"?> |
<Package |
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" |
xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest" |
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" |
xmlns:uap5="http://schemas.microsoft.com/appx/manifest/uap/windows10/5" |
IgnorableNamespaces="uap uap5 mp"> |
<Identity Name="wherewhere.VueForUWP" |
Publisher="CN=where" |
Version="0.0.1.0" /> |
<mp:PhoneIdentity PhoneProductId="2d5eb3c5-2697-7f48-4085-ba24fba35ad1" |
PhonePublisherId="00000000-0000-0000-0000-000000000000" /> |
<Properties> |
<DisplayName>VueForUWP</DisplayName> |
<PublisherDisplayName>wherewhere</PublisherDisplayName> |
<Logo>assets\icon.png</Logo> |
</Properties> |
<Dependencies> |
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.18362.0" |
MaxVersionTested="10.0.26100.0" /> |
</Dependencies> |
<Resources> |
<Resource Language="en-us" /> |
</Resources> |
<Applications> |
<Application Id="VueForUWP" StartPage="ms-appx-web:///app/index.html"> |
<uap:VisualElements |
DisplayName="VueForUWP" |
Description="UWP running with vue.js 3.0" |
BackgroundColor="transparent" |
Square150x150Logo="assets\Square150x150Logo.png" |
Square44x44Logo="assets\Square44x44Logo.png"> |
<uap:DefaultTile |
Wide310x150Logo="assets\Wide310x150Logo.scale-200.png"> |
<uap:ShowNameOnTiles> |
<uap:ShowOn Tile="square150x150Logo" /> |
</uap:ShowNameOnTiles> |
</uap:DefaultTile> |
<uap:SplashScreen Image="assets\SplashScreen.scale-200.png" uap5:Optional="true" /> |
<uap:InitialRotationPreference> |
<uap:Rotation Preference="landscape" /> |
<uap:Rotation Preference="portrait" /> |
<uap:Rotation Preference="landscapeFlipped" /> |
<uap:Rotation Preference="portraitFlipped" /> |
</uap:InitialRotationPreference> |
</uap:VisualElements> |
<uap:ApplicationContentUriRules> |
<uap:Rule Match="ms-appx-web:///" Type="include" WindowsRuntimeAccess="all" /> |
</uap:ApplicationContentUriRules> |
</Application> |
</Applications> |
<Capabilities> |
<Capability Name="internetClient" /> |
</Capabilities> |
</Package> |
然后编写部署脚本,可以参考 deploy.mjs:
import { powershell } from "electron-windows-msix/lib/powershell.js"; |
const results = await powershell("Add-AppxPackage -Path appx/msix_layout/AppxManifest.xml -Register"); |
console.log(results); |
最后在package.json中添加打包和部署指令:
{ |
... |
"scripts": { |
... |
"pack": "npm run build && node package.mjs", |
"deploy": "node deploy.mjs" |
}, |
... |
} |
现在我们可以通过执行npm run pack打包项目,用npm run deploy部署项目了。
由于 MSAppHost 永远留在了 Edge HTML 18,所以新的 Vue 样式库基本上都无法使用,为了符合 Windows 样式,还是建议使用 WinJS 控件库,可以在这里找到示例:GitHub - wherewhere/VueForUWP: UWP running with vue.js 3.0 · GitHub
