4 min read

使用svelte3框架项目实践(2019.06)

通过上篇《svelte3前端框架入门教程》介绍我们知道,svelte是编译时框架,很明显的优势是编译后不依赖框架库,最后运行时代码得以进一步减少,同时它也是响应式的。虽然目前并没有太多的实践项目,但是我觉得这个明显的优化收益值得思考它的使用场景。

通过上篇《svelte3前端框架入门教程》介绍我们知道,svelte是编译时框架,很明显的优势是编译后不依赖框架库,最后运行时代码得以进一步减少,同时它也是响应式的。虽然目前并没有太多的实践项目,但是我觉得这个明显的优化收益值得思考它的使用场景。

背景

在这个月,我接到了一个前端任务,是一个关于客户端路由器预订活动的前端功能开发。路由器预订分为路由器商品详情页面、快递表单提交页面、支付页面、订单列表页面,就这么一个功能,如果用以前的技术栈的话,先对比一下优缺点:

  1. 原生:代码体积小,解析快,开发时间稍长。
  2. jquery:引入jquery及jquery插件体积变大,解析稍慢,开发时间比原生短一些。
  3. vue:引入框架库,框架代码稍微比jquery小,解析稍慢,开发时间比使用jquery短。

首先注意上面只对比了代码大小、js解析时间、开发时间,其实还有许多因素未考虑,显然这是为了给svelte出场机会。如果我们用svelte3开发的话,代码既小,在熟悉svelte3框架的情况下开发时间也很短,这是理论上的,现实的一些情况还是值得我们去考虑的,比如svelte3的生态、周边配套,这些也决定了开发时间的长短,踩坑多少。不管怎么样,因为路由器预订活动页面是在客户端浏览,不需要太考虑兼容性问题(看了它文档没说兼容相关的问题),在估计能按时完成的情况下,决定吃一次螃蟹。

收获

通过开发中的实践,确实多多少少遇到了些问题,不过大都是预期中的。获得的效果也是很明显的,整个项目压缩完在没开启gzip的情况下只有58kb,感到非常满意。收获不是这篇文章重点要讲的,遇到的问题我觉得才是重点,可以和大家分享下。开发中的问题:

  1. 构建工具问题:svelte3是没有成熟的脚手架,初始化项目分为两种,分为直接下载和模板。个人建议使用模板,官方推荐rollup作为构建工具,也可以使用webpack。不过这两种构建工具模板都只进行了简单的支持,提供了处理svelte格式文件的能力,其它东西(eslint、scss、ts、图片处理...)还需要自己花时间去配置,不像vue-cli开箱即用、成熟、灵活。
  2. 社区不成熟:svelte官方文档和教程都比较简单(目前还没发现中文版的),看完这些大部分代码上的问题都可以解决。其它问题主要还是到github的issues去找找看,去stackoverflow、百度、谷歌能找到答案的不多。svelte相关的文章也不多,最佳实践和方案只有自己去摸索。
  3. 面条代码:缺乏经验的用户可能会写出 “面条代码”,因为在svelte文件里的script标签里可以自由发挥,不过我们可以通过抽取函数去组织代码,让代码更简洁、容易理解和维护。另外svelte3写代码的方式有点像还未发布的vue3,可以参考一下这篇文章《Vue Function-based API RFC》
  4. 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 ]
  }]

最后

文章就写到这里了,希望能给你带来帮助。