当前位置: 首页 > news >正文

我的qq中心网页版广东网站seo营销

我的qq中心网页版,广东网站seo营销,毕业论文 网站开发,在哪个国家做垂直网站好前言 开门见山,现代前端 Rust 构建基本分三大类,即 构建 .wasm 、构建 .node 二进制 、构建 swc 插件。 入门详见 《 前端Rust开发WebAssembly与Swc插件快速入门 》 。 对于单独开发某一类的流程,在上述参考文章中已有介绍,但对于…

前言

开门见山,现代前端 Rust 构建基本分三大类,即 构建 .wasm 、构建 .node 二进制 、构建 swc 插件。

入门详见 《 前端Rust开发WebAssembly与Swc插件快速入门 》 。

对于单独开发某一类的流程,在上述参考文章中已有介绍,但对于一次开发后全平台构建发布,上述文章并未涉猎,基于此,本文将快速介绍一个最简的 全平台构建 (包括二进制 .node.wasm ) 前端 Rust 包的开发流程是怎样的。

注:我们默认读者已掌握构建三大类前端 Rust 包的知识。

正文

Rust workspace

以 workspace 组织代码仓库,核心逻辑全部独立为一个子包,参考如下:

 - crates- binding_node  # 基于 napi 分发 `.node` 二进制- binding_wasm  # 基于 wasm-pack 分发 `.wasm`- core          # 核心逻辑- ...           # 其他解耦
binding_node

其中 binding_node 为 node 构建出口,引用核心逻辑后暴露 API ,简式参考如下:

// binding_node/src/lib.rs#[macro_use]
extern crate napi_derive;use napi::{bindgen_prelude::AsyncTask, Env, Task};
use core::{core_process, IInput, IResult};// ⬇️ 同步部分
#[napi]
pub fn method_sync(input: IInput) -> Result<IResult, anyhow::Error> {core_process(input)
}// ⬇️ 异步部分
pub struct TaskExecutor {input: IInput,
}pub struct ProcessTask {task: TaskExecutor,
}impl Task for ProcessTask {type Output = IResult;type JsValue = IResult;fn compute(&mut self) -> napi::Result<Self::Output> {self.task.process().map_err(|err| napi::Error::from_reason(&err.to_string()))}fn resolve(&mut self, _env: Env, output: Self::Output) -> napi::Result<Self::JsValue> {Ok(output)}
}impl TaskExecutor {pub fn process(&self) -> Result<IResult, anyhow::Error> {core_process(self.input.clone())}
}#[napi(ts_return_type="Promise<IResult>")]
pub fn method(input: IInput) -> AsyncTask<ProcessTask> {AsyncTask::new(ProcessTask {task: TaskExecutor { input },})
}

注:此处为最简函数式示例,涉及 异步信号、错误处理、错误打印、导出多方法的复杂类 等情况时请自行处理。

通常情况提供最普通的 同步函数 方法已足够。

类型处理

为了尽可能减少工作量,让 napi 自动生成 .d.ts 类型,需给结构对象加上 #[napi] 宏才能生成类型,但所有结构声明在 crates/core 核心逻辑包中,而我们的 napi 出口在 crates/binding_node

一种解法是条件编译,提供 feature = "node" 的特定模式,参考如下:

# core/Cargo.toml[features]
default = []
node = ["napi", "napi-derive"][dependencies]
napi = { ..., optional = true }
napi-derive = { ..., optional = true }
// 条件编译宏#[macro_export]
#[cfg(feature = "node")]
macro_rules! multi_env {($($items:item)*) => {use napi_derive::napi;$(#[napi(object)]$items)*};
}

使用参考:

multi_env! {pub struct IInput {pub input: ...,}pub struct IResult {pub output: ...,}// ...
}

综上,通过特定 node feature 方式,在引用时条件添加 #[napi] 来做到自动生成类型。

人工应对复杂类型

如 想自行管理导出方法类型的暴露情况、涉及 class 等复杂的类型 、无法自动识别生成 等情况,可以人工编写整份 .d.ts 文件,但十分耗费精力。

对于 异步情况等 引发的动态值转换,而无法自动识别类型的,可尝试 napi 默认自带的类型选项,如 #[napi(ts_return_type="...")] 等选项来辅助修改生成的类型,省时省力。

构建

对于多平台,我们通常需要依赖 GitHub Actions 来进行多平台构建,在 CI 中构建、测试后发布到 npm 。

现代常用构建对象 napi 列表如下:

    "triples": {"defaults": false,"additional": ["x86_64-apple-darwin","aarch64-apple-darwin","x86_64-pc-windows-msvc","aarch64-pc-windows-msvc","x86_64-unknown-linux-gnu","aarch64-unknown-linux-gnu","x86_64-unknown-linux-musl","aarch64-unknown-linux-musl"]},

最常用的即如上 8 个平台,酌情构建 armv7-unknown-linux-gnueabihf ,必要时采用 wasm 兜底即可。

此部分过于冗长且模板化,可参考 swc 等项目的构建 CI 来取用。

binding_wasm

其中 binding_wasm 为 wasm 构建出口,引用核心逻辑后暴露 API ,简式参考如下:

use wasm_bindgen::prelude::*;use core::{core_process, IInput, IResult};#[wasm_bindgen(js_name = "methodSync")]
pub fn method_sync(input: IInput) -> Result<IResult, JsError> {core_process(input).map_err(|err| JsError::new(&err.to_string()))
}#[wasm_bindgen(typescript_custom_section)]
const INTERFACE_DEFINITIONS: &'static str = r#"
export function method(config: IInput): Promise<IResult>;
"#;#[wasm_bindgen(skip_typescript)]
pub fn method(input: IInput) -> js_sys::Promise {wasm_bindgen_futures::future_to_promise(async {core_process(input).map(|r| serde_wasm_bindgen::to_value(&r).unwrap()).map_err(|err| JsValue::from_str(&err.to_string()))})
}

注:此处为最简函数式示例,涉及 异步、错误处理、错误打印 等情况时请自行修订处理。

通过 serde-wasm-bindgen 来动态转换 JS 值与 Rust 中的结构。

通常情况提供最普通的 同步函数 方法已足够。

类型处理

为了尽可能减少工作量,我们使用 tsify 做自动类型生成,同上文中相同,采用条件编译,提供 feature = "wasm" 模式:

# core/Cargo.toml[features]
default = []
wasm = ["tsify", "wasm-bindgen"][dependencies]
tsify = { ..., optional = true }
wasm-bindgen = { ..., optional = true}
// 条件编译宏#[macro_export]
#[cfg(feature = "wasm")]
macro_rules! multi_env {($($items:item)*) => {use tsify::Tsify;use serde::{Deserialize, Serialize};use wasm_bindgen::prelude::*;$(#[derive(Tsify, Serialize, Deserialize)]#[tsify(into_wasm_abi, from_wasm_abi)]$items)*};
}// 兜底用
#[macro_export]
#[cfg(all(not(feature = "wasm"), not(feature = "node"),))]
macro_rules! multi_env {($($tokens:tt)*) => {$($tokens)*};
}

人工应对复杂类型

如 想自行管理导出方法类型的暴露情况、无法自动识别生成 等情况,可以人工编写整份 .d.ts 文件。

对于 异步情况等 引发的动态值转换,而无法自动识别类型的,尝试 #[wasm_bindgen(skip_typescript)] 跳过自动生成类型后,使用 #[wasm_bindgen(typescript_custom_section)] 人工插入少量类型声明来解决,节省编写时间。

构建

由于 wasm 无需依赖本机环境,根据情况可选在云构建或本地构建均可,主要包含 web 用途与 nodejs 用途的 wasm 产物构建。

web 用途

web 用途的 wasm 产物主要用于网页应用,playground 等,构建命令参考:

  # web 用途cd crates/binding_wasm && wasm-pack build --verbose --out-dir ./output/wasm_web --out-name index --release

web 用途的构建产物包含 ESM 格式胶水代码 ,可直接将产物整体用在 webpack 项目导入,对于 webpack 5 可直接开启 async webassembly 特性直接适配项目:

// webpack.config.jsexperiments: {asyncWebAssembly: true,},
import * as wasm from '/path/to/wasm-output'
// 或使用异步 await import() 延时、按需加载

nodejs 用途

nodejs 用途主要用于非主流平台兜底,如 边缘函数、serverless 等环境,构建命令参考:

  # nodejs 用途cd crates/binding_wasm && wasm-pack build --target nodejs --verbose --out-dir ./output/wasm --out-name index --release

和 web 用途构建命令区别在于特定了 --target nodejs ,这会得到 CJS 格式产物代码,可直接用于 nodejs 。

使用与安装时机

对于两种 wasm 包,通常命名为 @scope/wasm ( nodejs 用途) 、@scope/wasm-web ( web 用途),在对应平台下,可直接安装该包来使用。

同时,对非主流架构环境,我们一般在主包的 postinstall 时进行脚本检测,并在需要时自动安装 @scope/wasm 包来兜底,具体逻辑较冗长且模板化,可参考 swc 等项目取用即可。

如何安装指定平台包

最新版本的 pnpm v8 支持配置 pnpm.supportedArchitectures 来安装想要的平台包,即使你不在某个平台上,这通常用于 wasm 安装校验:

# .npmrc
# 关闭 postinstall 缓存
side-effects-cache=false
# 打印 postinstall 日志
reporter=append-only
// package.json// ↓ 该配置将匹配不到任何 `.node` 的平台包,于是自动 fallback 到 wasm 兜底包"pnpm": {"supportedArchitectures": {"os": ["unknown"],"cpu": ["x64"]}}
wasm 产物优化

通常 .node 二进制产物由 Rust 生产构建后自动优化,加上 strip 优化体积已足够。

对于 wasm 一般采用 wasm-opt 优化体积,默认 wasm-pack 生产构建最终阶段会自动下载相关工具并执行优化,如遇网络问题,可关闭自动优化,转为手动下载后执行优化:

  # 提前下载好执行工具,防止网络问题cargo install wasm-bindgen-cli
# binding_wasm/Cargo.toml# 关闭 wasm-opt 自动优化,之后手动优化
[package.metadata.wasm-pack.profile.release]
wasm-opt = false
  # 下载 wasm-opt 工具并解压# 最新版本见:https://github.com/WebAssembly/binaryen/releasescurl -L https://github.com/WebAssembly/binaryen/releases/download/version_116/binaryen-version_116-x86_64-macos.tar.gz -o ./binaryen.tar.gzmkdir ./.cachetar -xvf ./binaryen.tar.gz -C ./.cache# 优化 wasm 产物./.cache/binaryen-version_116/bin/wasm-opt -Oz -o ./output/wasm/index_bg.wasm ./output/wasm/index_bg.wasm

总结

在全平台构建时,编写 十分大量 的人力脚本与文件操作在所难免,如有可能,可将其统一抽象化,方便下次取用。

由于流程更偏向于固定模板化,在实践时,请自行参考相关项目自取所需即可。


文章转载自:
http://tripolite.dtrz.cn
http://dermographia.dtrz.cn
http://breadwinner.dtrz.cn
http://chrominance.dtrz.cn
http://cosmogenetic.dtrz.cn
http://exacting.dtrz.cn
http://geraniol.dtrz.cn
http://wrestle.dtrz.cn
http://kepi.dtrz.cn
http://ravelin.dtrz.cn
http://forever.dtrz.cn
http://cantaloupe.dtrz.cn
http://allimportant.dtrz.cn
http://pop.dtrz.cn
http://bx.dtrz.cn
http://lunette.dtrz.cn
http://retroactively.dtrz.cn
http://houting.dtrz.cn
http://sleigh.dtrz.cn
http://wysiwyg.dtrz.cn
http://legpuller.dtrz.cn
http://exosphere.dtrz.cn
http://lengthwise.dtrz.cn
http://slate.dtrz.cn
http://cancerogenic.dtrz.cn
http://enactment.dtrz.cn
http://decadence.dtrz.cn
http://latex.dtrz.cn
http://powder.dtrz.cn
http://hypothetically.dtrz.cn
http://khond.dtrz.cn
http://kenning.dtrz.cn
http://salmon.dtrz.cn
http://showdown.dtrz.cn
http://sweetly.dtrz.cn
http://fumulus.dtrz.cn
http://baffleplate.dtrz.cn
http://dullsville.dtrz.cn
http://underexercise.dtrz.cn
http://ministrable.dtrz.cn
http://kktp.dtrz.cn
http://ganggang.dtrz.cn
http://snout.dtrz.cn
http://gratefully.dtrz.cn
http://mammoplasty.dtrz.cn
http://livetrap.dtrz.cn
http://unsteadily.dtrz.cn
http://towering.dtrz.cn
http://gardenia.dtrz.cn
http://presently.dtrz.cn
http://helminthoid.dtrz.cn
http://eddie.dtrz.cn
http://eccrine.dtrz.cn
http://pastorally.dtrz.cn
http://semidemisemiquaver.dtrz.cn
http://renovation.dtrz.cn
http://nowhither.dtrz.cn
http://favonian.dtrz.cn
http://fanaticism.dtrz.cn
http://dziggetai.dtrz.cn
http://fingerful.dtrz.cn
http://septa.dtrz.cn
http://drawl.dtrz.cn
http://clara.dtrz.cn
http://impermissibly.dtrz.cn
http://cerebralism.dtrz.cn
http://vowelless.dtrz.cn
http://hydrolyzate.dtrz.cn
http://earmuff.dtrz.cn
http://deflex.dtrz.cn
http://cineangiogram.dtrz.cn
http://tonight.dtrz.cn
http://abreact.dtrz.cn
http://antianginal.dtrz.cn
http://superspace.dtrz.cn
http://listserv.dtrz.cn
http://unwearied.dtrz.cn
http://jerquer.dtrz.cn
http://predeterminate.dtrz.cn
http://beadswoman.dtrz.cn
http://adiabatic.dtrz.cn
http://indivertible.dtrz.cn
http://successor.dtrz.cn
http://arthroscope.dtrz.cn
http://congenial.dtrz.cn
http://piliated.dtrz.cn
http://robertsonian.dtrz.cn
http://shuba.dtrz.cn
http://cynically.dtrz.cn
http://bumpy.dtrz.cn
http://phenacite.dtrz.cn
http://amphidiploid.dtrz.cn
http://tumefy.dtrz.cn
http://rummily.dtrz.cn
http://endopolyploid.dtrz.cn
http://exploration.dtrz.cn
http://unaccountably.dtrz.cn
http://packhorse.dtrz.cn
http://aquagun.dtrz.cn
http://polarity.dtrz.cn
http://www.dt0577.cn/news/129004.html

相关文章:

  • 杭州网站维护网络营销期末总结
  • 网站的内容和功能新浪体育最新消息
  • 便宜建站泰安做网站公司
  • wordpress如何加入备案许可证编号网络seo首页
  • 万网域名免费注册网络优化的基本方法
  • 电子商务网站建设设计题媒体公关
  • 网站登录到wordpress沈阳专业seo
  • 做五金的外贸网站有哪些推特最新消息今天
  • 怎么做英文网站昆明百度推广优化
  • 福田网站建设哪家好搜索引擎优化的具体操作
  • 网站实名审核中心企业文化
  • 网站开发工具 枫子科技设计公司排名
  • 做移动网站排名软件软文怎么写吸引人
  • 大兴高端网站建设竞价推广招聘
  • 网站建设方案书写旺道营销软件
  • 最新网站推广哪家好赣州seo公司
  • 青岛建设集团招工信息网站网络营销策划的目的
  • 国家建设工程造价数据监测平台在哪个网站学开网店哪个培训机构好正规
  • 织梦网站地图html怎么做武汉百度seo排名
  • 装饰设计图片seo和竞价排名的区别
  • 做ppt的网站 知乎普通话的顺口溜6句
  • 有什么php网站聊石家庄seo
  • 为每个中小学建设网站百度开户公司
  • 软件测试自学常用的seo工具的是有哪些
  • 做故障风的头像的网站福州百度快照优化
  • python怎么做专门的手机网站市场营销策划包括哪些内容
  • wordpress标签库网站优化排名服务
  • 在哪里进行网站域名的实名认证爱站在线关键词挖掘
  • 看设计作品的网站软件网推是干什么的
  • 代网站备案费用吗免费b站推广网站详情