- 增强原生小程序开发,构建 tailwind + postcss + scss 最小化工具链
前言 书接上回 tailwindcss 小程序定制化之旅 我们知道 [代码]uni-app[代码] 和 [代码]tarojs[代码] 在最终打包成小程序运行的时候,都是使用的 [代码]webpack[代码],所以在这 2 个框架中,我们可以使用 [代码]*-loader[代码] 轻而易举的赋予它们这方面的能力。 但是,假如我们使用的是原生开发呢? 原生开发的选项 使用微信开发工具的小伙伴们,肯定注意到,在 [代码]项目详情[代码] -> [代码]本地设置[代码] 中, 有上传代码时 [代码]样式自动补全[代码],[代码]自动压缩样式[代码], [代码]自动压缩混淆[代码] 等等选项。 它们的本质,不过是几个插件罢了: [代码]样式自动补全[代码] -> [代码]autoprefixer[代码] [代码]自动压缩样式[代码] -> [代码]cssnano[代码] [代码]自动压缩混淆[代码] -> [代码]uglify-js[代码]/[代码]terser[代码] 所以我们完全可以自定义,以获得更强更自由的能力。 最小化的自定义样式工具链 1. Scss与Postcss支持 我们知道 在 [代码]webpack[代码] 里 [代码]sass-loader[代码], [代码]postcss-loader[代码] ,[代码]babel-loader[代码] 这类,只是编译核心们和 [代码]webpack[代码] 做粘合的胶水代码。 在不使用 [代码]webpack[代码] [代码]gulp[代码] [代码]rollup[代码] … 这类的打包工具的情况下,我们当然可以去自定义一个最小化的样式编译工具。 首先,直接安装 [代码]dart-sass[代码],和 [代码]postcss[代码] [代码]yarn add -D sass postcss [代码] 安装后,可以看到 , [代码]sass[代码] 渲染函数签名 [代码]// sass函数签名 export function render(options: Options, callback: (exception: SassException, result: Result) => void): void; export function renderSync(options: Options): Result; [代码] 然后我们又知道 [代码]webpack[代码] 的 [代码]loader[代码] 选择了 [代码]compose[代码] 方式的执行方式。 函数式编程中, [代码]compose[代码] 从右到左执行, [代码]pipe[代码] 从左到右执行 于是我们知道了执行顺序,那么就可以确定 [代码]*.scss[代码] 文件,先交给 [代码]sass[代码] 处理,再交由 [代码]postcss[代码] 处理, 然后就直接打成 [代码]xxpage.wxss[代码] 这类 局部页面样式 , 又或者打成 [代码]app.wxss[代码] 作为全局样式。 那么写代码实现就是探囊取物了: [代码]// 不考虑 preset merge的情况下 const sass = require('sass') const postcss = require('postcss') const { plugins } = require('./postcss.config.js') function handleScss (path) { sass.render({ file: path, // fiber: Fiber }, (err, result) => { if (err) { console.error(err) } const destPath = path.replace(/\.scss$/, '.wxss') postcss(plugins).process(result.css, { from: path, to: destPath }).then(result => { fs.writeFile(destPath, result.css, () => true) if (result.map) { fs.writeFile(destPath + '.map', result.map.toString(), () => true) } }) }) } [代码] 上面这段代码就是 [代码]scss[代码] -> [代码]postcss[代码] -> [代码]wxss[代码] 的转化链路 而且还可以在里面,随意的装 [代码]postcss plugin[代码] , 比如 [代码]autoprefixer[代码] , [代码]cssnano[代码] , [代码]tailwindcss[代码] 之前笔者写的 [代码]tailwindcss-miniprogram-preset[代码] 也可以无缝的嵌入这套机制中去,给原生小程序使用。 2. 文件监控 我们开发的时候,会经常去创建,修改,删除文件,这么获取到这些 [代码]timing[代码] 对文件进行重新编译呢? [代码]fs.watch[代码],[代码]fs.watchFile[代码] 固然可以,不过更推荐的还是 [代码]chokidar[代码] [代码]yarn add -D chokidar[代码] 在 [代码]chokidar[代码] 的 [代码]README.md[代码] 中详细介绍了它的优势,这里不再叙述。 [代码]const watcher = chokidar.watch(`${someGlob}`, { ignored: /(^|[\/\\])\../, persistent: true }) // EventEmitter 的写法,把监控安排的明明白白 watcher .on('add', (path,stats) => { // 添加文件 }) .on('change', (path,stats) => { // 修改文件 }) .on('unlink', (path,stats) => { // 删除文件 }) .on('error', error => { // 发生错误 }) .on('ready', () => { // watch ready after add files }) [代码] 通过 [代码]watcher[代码] 的持续性监控,我们可以很容易得出结论,我们需要在 [代码]*.scss[代码] 文件变动的时候,重新编译, 即 [代码]add[代码],[代码]change[代码] 的时间点, 在 [代码]unlink[代码] 的时间点,也要同时 [代码]unlink[代码] 对应的 [代码]*.wxss[代码] 文件。 假如 [代码]purgecss[代码] 开启,则需要在 [代码]wxml[代码] 文件发生变更时,通知重新编译 [代码]app.scss[代码] 和文件对应的 [代码]page.scss[代码],一般开发时不开启此工具。 3. IDE智能提示设置 前面这一套机制,搭建完成后 在 [代码]app.scss[代码] 里加一行 [代码]@tailwind utilities;[代码] 就可以顺利使用 [代码]tailwindcss[代码] 了 但是我们需要我们的编辑器根据 [代码]tailwindcss[代码] 配置,自动生成 class 的智能提示怎么做呢? 这里我们以 [代码]vscode[代码] 为例: 安装 [代码]WXML - Language Services 插件[代码](一搜wxml下载量最多的就是了) 安装 [代码]Tailwind CSS IntelliSense 插件[代码] 接着找到 [代码]Tailwind CSS IntelliSense[代码] 的 [代码]扩展设置[代码] 在 [代码]include languages[代码],手动标记 [代码]wxml[代码] 的类型为 [代码]html[代码] [图片] 智能提示就出来了: [图片] 是不是非常方便,同时也能大大提升开发效率。 代码工程化方案 其实这篇文章,拆开了 [代码]webpack[代码] 的部分黑盒, 探讨了场景定制化的代码加工生产线,以期来帮助开发者提升效率。 [代码]typescript[代码] + [代码]@babel/core[代码] + [代码]rollup[代码] 这种处理[代码]js[代码]的组合也见过。 只要能提升开发者生产效率,提升开发体验,提升可维护性的工具还是值得一做的。 附录 源代码
2021-09-01 - [开盖即食]小程序Canvas官方新版API实战
[图片] [图片] 最近本人在开发一个新项目的时候,注意到官方在2.9.0开始支持了一个canvas 2D的新API,同时对webGL上支持也有了很大的改进,相信很多人用canvas的组件做一些分享海报,战绩和新闻帖功能。 [图片] 这里是新的引入方式。 官方文档地址: https://developers.weixin.qq.com/miniprogram/dev/component/canvas.html 那么新的canvas2D API有啥好处呢? 原本的API微信有做一定的修改,现在全面支持源生H5 JS的写法,迁移H5的老代码变成更加容易,学习成本更低 修复了一些诡异的BUG,例如原本在IOS早期版本写法顺序会导致clip()图片裁切失效等~ 性能上的优化和提升,复杂动画上帧数明显 举例写法上的一些改变: 1、设置font的写法: [代码]//原本(传值的写法) ctx.setFontSize(20); ctx.fillText('MINA', 100, 100) ctx.draw() //现在(和源生H5写法一致,赋值) ctx.font = "16px"; ctx.fillStyle = 'blue'; //可以直接写颜色,原本的不支持 //不需要 ctx.draw() [代码] 2、获取并添加图片写法: [代码]//原本 //使用的是 wx.getImageInfo的方法 wx.getImageInfo({ src: mainImg,//服务器返回的图片地址 success: function (res) { console.log(res); ctx.drawImage(res.path, 0, 0); ctx.draw(true); }, fail: function (res) { //失败回调 } }); //现在 //可以直接img.onload调用 const headerImg = canvas.createImage(); headerImg.src = headImage;//微信请求返回头像 headerImg.onload = () => { ctx.save(); ctx.beginPath()//开始创建一个路径 ctx.arc(38, 288, 18, 0, 2 * Math.PI, false)//画一个圆形裁剪区域 ctx.clip()//裁剪 ctx.drawImage(headerImg,0,0); ctx.closePath(); ctx.restore(); } [代码] 3、将canvas生成虚拟地址便于下载(重点): [图片] 由于官方文档没有写清楚,误导了挺多人的。这里canvas对象必须通过选择器获取,并获得对应的node节点。 [代码]async saveImg() { let self = this; //这里是重点 新版本的type 2d 获取方法 const query = wx.createSelectorQuery(); const canvasObj = await new Promise((resolve, reject) => { query.select('#posterCanvas') .fields({ node: true, size: true }) .exec(async (res) => { resolve(res[0].node); }) }); console.log(canvasObj); wx.canvasToTempFilePath({ //fileType: 'jpg', //canvasId: 'posterCanvas', //之前的写法 canvas: canvasObj, //现在的写法 success: (res) => { console.log(res); self.setData({ canClose: true }); //保存图片 wx.saveImageToPhotosAlbum({ filePath: res.tempFilePath, success: function (data) { wx.showToast({ title: '已保存到相册', icon: 'success', duration: 2000 }) // setTimeout(() => { // self.setData({show: false}) // }, 6000); }, fail: function (err) { console.log(err); if (err.errMsg === "saveImageToPhotosAlbum:fail auth deny") { console.log("当初用户拒绝,再次发起授权") } else { util.showToast("请截屏保存分享"); } }, complete(res) { wx.hideLoading(); console.log(res); } }) }, fail(res) { console.log(res); } }, this) }, [代码] 分享个canvas海报的代码片段: [图片] 片段名: PoCf4emw7TgE 片段link: https://developers.weixin.qq.com/s/PoCf4emw7TgE [图片] [图片] 总结,相对之前还要看官方文档的canvas自定义API,现在写起来更加的方便,老代码迁移起来得心应手,只要你之前会canvas,那么各种效果和动画,拿来就怼,没什么大问题~ 一些奇怪的问题(注意!!!) canvas 2d 目前(2020年4月3日)还不支持真机调试,会报错!!! IDE工具 1.02.2003190 直接保存新版本canvas的API图片是打不开的,但是直接用手机保存在相册是没问题的,请更新到1.02.2003250 最新版即可解决~ 一些老款手机用新的API保存图片会有报错问题,如华为NOTE10,请更新系统到能支持的最新,且微信也是,即可解决~ 部分Android设备诡异的闪退和报错 [图片] 这种有可能是代码写法的问题,比如: [代码]//缺省写法 会导致部分Android机器 闪退 ctx.font = "bold 16px"; ctx.fillStyle = "#000" //在canvas 2D的写法中,所以写法必须规范且完整 ctx.font = "normal bold 12px sans-serif"; ctx.fillStyle = '#707070'; [代码] 所以在canvas 2D 的环境,所以写法必须原始且规范,不能用缺省写法,不然就会有诡异的闪退/报错。 后续:官方在7.0.13的Android版本已修复。 https://developers.weixin.qq.com/community/develop/doc/00088c13e1437890692afd8d85ec00 看完觉得有帮助记得点个赞哦~ 你的赞是我继续分享的最大动力!^-^
2020-05-09