使用svelte3框架项目实践(2019.06)
通过上篇《svelte3前端框架入门教程》介绍我们知道,svelte是编译时框架,很明显的优势是编译后不依赖框架库,最后运行时代码得以进一步减少,同时它也是响应式的。虽然目前并没有太多的实践项目,但是我觉得这个明显的优化收益值得思考它的使用场景。
通过上篇《svelte3前端框架入门教程》介绍我们知道,svelte是编译时框架,很明显的优势是编译后不依赖框架库,最后运行时代码得以进一步减少,同时它也是响应式的。虽然目前并没有太多的实践项目,但是我觉得这个明显的优化收益值得思考它的使用场景。
背景
在这个月,我接到了一个前端任务,是一个关于客户端路由器预订活动的前端功能开发。路由器预订分为路由器商品详情页面、快递表单提交页面、支付页面、订单列表页面,就这么一个功能,如果用以前的技术栈的话,先对比一下优缺点:
- 原生:代码体积小,解析快,开发时间稍长。
- jquery:引入jquery及jquery插件体积变大,解析稍慢,开发时间比原生短一些。
- vue:引入框架库,框架代码稍微比jquery小,解析稍慢,开发时间比使用jquery短。
首先注意上面只对比了代码大小、js解析时间、开发时间,其实还有许多因素未考虑,显然这是为了给svelte出场机会。如果我们用svelte3开发的话,代码既小,在熟悉svelte3框架的情况下开发时间也很短,这是理论上的,现实的一些情况还是值得我们去考虑的,比如svelte3的生态、周边配套,这些也决定了开发时间的长短,踩坑多少。不管怎么样,因为路由器预订活动页面是在客户端浏览,不需要太考虑兼容性问题(看了它文档没说兼容相关的问题),在估计能按时完成的情况下,决定吃一次螃蟹。
收获
通过开发中的实践,确实多多少少遇到了些问题,不过大都是预期中的。获得的效果也是很明显的,整个项目压缩完在没开启gzip的情况下只有58kb,感到非常满意。收获不是这篇文章重点要讲的,遇到的问题我觉得才是重点,可以和大家分享下。开发中的问题:
- 构建工具问题:svelte3是没有成熟的脚手架,初始化项目分为两种,分为直接下载和模板。个人建议使用模板,官方推荐rollup作为构建工具,也可以使用webpack。不过这两种构建工具模板都只进行了简单的支持,提供了处理svelte格式文件的能力,其它东西(eslint、scss、ts、图片处理...)还需要自己花时间去配置,不像vue-cli开箱即用、成熟、灵活。
- 社区不成熟:svelte官方文档和教程都比较简单(目前还没发现中文版的),看完这些大部分代码上的问题都可以解决。其它问题主要还是到github的issues去找找看,去stackoverflow、百度、谷歌能找到答案的不多。svelte相关的文章也不多,最佳实践和方案只有自己去摸索。
- 面条代码:缺乏经验的用户可能会写出 “面条代码”,因为在svelte文件里的script标签里可以自由发挥,不过我们可以通过抽取函数去组织代码,让代码更简洁、容易理解和维护。另外svelte3写代码的方式有点像还未发布的vue3,可以参考一下这篇文章《Vue Function-based API RFC》。
- IDE支持问题:目前IDE对svelte文件的支持还不是很完善,对于webstorm用户,可以安装Svelte插件来获取部分支持,然后通过设置Editor->File Types找到Vue.js Templates添加*.svelte来获取进一步的支持。
浏览器兼容方案
我是用webpack去构建前端代码的,如果要使svelte开发的项目兼容ie9+的话,就需要babel-loader的加持。大概配置如下:
const babelLoaderConfig = {
loader: 'babel-loader',
options: {
presets: [['@babel/preset-env', {
targets: ['> 1%', 'last 2 versions', 'ie >= 9'],
useBuiltIns: 'entry'
}]]
}
};
const svelteLoaderConfig = {
loader: 'svelte-loader',
options: {
emitCss: true,
hotReload: true,
preprocess: require('svelte-preprocess')({ /* options */ }),
legacy: true
}
};
rules: [{
test: /\.(html|svelte)$/,
use: prod ? [ babelLoaderConfig, svelteLoaderConfig ] : [svelteLoaderConfig]
},
{
test: /\.(html|m?js)$/,
use: [ babelLoaderConfig ]
}]
最后
文章就写到这里了,希望能给你带来帮助。