背景

在开发快应用时,少不了构建操作:npm run build(官方 IDE 集成了这些操作,本质上也是调用同样方法)。这是因为快应用有自己的 DSL 语法,直接写出来,在底层不能识别,需要把业务代码编译成底层能运行的代码(感兴趣的同学,可在 build 文件夹查看编译后的代码产物)。整个过程就跟 Vue 和 React 工程的打包一样。等待的过程总是漫长,当项目越来越大的时候,难免还要花上点时间。可谁不希望这个过程越快越好呢?本篇就在于探讨,如何有效提升快应用(Webpack)编译速度。

快应用工程是基于 hap-toolkit 编译打包的。而它的功能,部分是基于 Webpack 开发。所以下面跟大家分享的,关于提升快应用编译速度的方法,同样也适用于基于 Webpack 构建的 Web 应用。

基于插件

不过毕竟是 Webpack 上的封装,所以不是所有方法都可以用上。现在 hap-toolkit 支持一些自定义配置了,可以使用部分 loader 和 plugin。详情请查看 ToolKit 项目配置 里面有自定义 webpack plugin 的代码示例。我们这里要讲的就是使用 hard-source-webpack-plugin 插件来为编译加速。

对于做过 Webpack 性能优化的同学,可能有用到过 HardSourceWebpackPlugin 插件,用于为模块提供中间缓存步骤。它能明显提升第二次构建速度:

HardSourceWebpackPlugin is a plugin for webpack to provide an intermediate caching step for modules. In order to see results, you'll need to run webpack twice with this plugin: the first build will take the normal amount of time. The second build will be significantly faster.

安装

yarn add --dev hard-source-webpack-plugin

// OR

npm i hard-source-webpack-plugin --save-dev

使用

在项目根目录下增加 quickapp.config.js 文件,做如下代码配置:

const HardSourceWebpackPlugin = require("hard-source-webpack-plugin");

module.exports = {

webpack: {

plugins: [new HardSourceWebpackPlugin()],

},

};

如上,一点简单的配置,即可轻松使用。当然,也可以通过添加参数,来“量身”定制。下面拿快应用官方 Sample 来看一下。

参数介绍

首先,完全的第一次编译,会花费较长时间。这是因为编译过程需要依赖到 babel 模块,在 webpack 里它化身为 babel-loader,编译过程需要解析成 AST,再转换成我们要的输出格式(对该部分知识感兴趣的同学可自行查阅)。这一过程极为耗时,所以作为一个有担当的依赖,它也应该有自己的缓存。

这一配置已经在 hap-toolkit 写好了。可以在项目目录下node_modules/.cache/babel-loader看到 babel 缓存。

使用 hard-source-webpack-plugin 插件,编译速度会有显著提高。

在上述存放缓存的地点,可以发现多了个 hard-source 的文件夹,里面正是存放着插件生成的缓存。再看看一些参数的介绍,我们直接在代码上以注释的形式展示:

new HardSourceWebpackPlugin({

// 缓存存放的地址,以 webpack 的执行目录加该字段拼接而成,一般都是存放于项目目录下

// 也可以写成绝对路径,存放到别的地方

cacheDirectory: "node_modules/.cache/hard-source/[confighash]",

// 缓存文件夹的名字生成方式,这里的值对于上方的 configHash

configHash: function (webpackConfig) {

return require("node-object-hash")({ sort: false }).hash(webpackConfig);

},

// 环境hash,其实就是监听依赖有没有更改,有的话也更新缓存

// 一般 files 填一个 package-lock.json 也够了

environmentHash: {

root: process.cwd(),

directories: [],

files: ["package-lock.json", "yarn.lock"],

},

cachePrune: {

// 缓存的存在时间,默认为两天

maxAge: 2 * 24 * 60 * 60 * 1000,

// 缓存的最大容量,默认为 50 MB

sizeThreshold: 50 * 1024 * 1024,

},

});

需要注意下,如果用官方 IDE 来打开项目,由于 IDE 的运行路径,与项目路径不一致,会导致报错,需要设置 environmentHash 来修正:

new HardSourceWebpackPlugin({

environmentHash: {

root: __dirname,

},

});

基于文件操作

一 移除 source-map

source-map,简而言之,就是编译后的代码与源代码的一个映射。在进行代码调试时候,执行环境运行的是编译后的代码,但可以看到对应的源代码;最常见的就是浏览器中,通过打断点,定位到源代码去,这样就可以发现源代码出现的问题。

通过阅读 Webpack Devtool 文档,可以知道,source-map 构建也需要时间;且跟还原度也有关系,越精确越耗时间,尤其是值为 source-map 模式。

在 hap-toolkit 默认设置,release 就是设置为 “none”;debug 模式由于要考虑到还原度,选择了 “cheap-eval-source-map”。那么,如果平时无需 source-map,可以直接将其设置为 “none”,即可进一步加快速度。同时,也会带来问题,即调试之时,无法精确对应源代码。您可以有两种方式,来关闭 source-map:

通过修改 quickapp.config.js 配置:

module.exports = {

cli: {

devtool: "none",

},

};

通过命令行

// 此方法,在 IDE 中不适用

npm run build -- --devtool none

这个对于速度有小幅提升。这个虽然效果不如缓存提升得那么明显,但是胜在作用于每次打包,对于首次打包也是有效的。

二 减少编译代码

我们知道,编译速度跟代码量也有关系,那么减少“需要编译的文件”,当然就可以加快速度。开发时候,通常都是一个或者几个相关页面来开发。所以开发过程中可以只编译当前需要的页面。

hap-toolkit 收集页面是通过 manifest.json 的 router.page 配置,而不是通过工程的 src 下具体文件。所以可以先去掉不相干的页面配置,而不需要去除实际文件。

最简单情况可以只留下单个页面,对比起好几个甚至十几个页面的编译速度,提速效果还是相当明显的。

三 加快文件搜索

代码量对编译速度有影响,自然的,寻找需要编译的文件也要花时间的。

我们在代码中对文件的引用,写了很多相对路径,而且也习惯不写文件后缀。webpack 没有那么神可以洞察开发者内心的诉求,而是根据配置好的搜索条件,不断地循环查找。

webpack 的 resolve 配置就是干这个活的。

我们摘取其中实用的来说,先上代码,在快应用中 quickapp.config.js 配置:

const path = require("path");

module.exports = {

webpack: {

resolve: {

alias: {

"@src": path.resolve(__dirname, "src"),

},

modules: ["./src/components"],

},

},

};

1、resolve.modules:配置 Webpack 去哪些目录下寻找第三方模块,默认配置是去 node_modules 目录下寻找。

有时做了一个公用组件库,给不同的地方调用。在不同地方的引入,就有可能导致这个路径会很长,如 import '../../../components/button'。这时可以利用 modules 配置项优化,假如组件库在 ./src/components 目录下,就可以给 modules 增加'./src/components'这样一个地址,供 webpack 快速命中资源位置。

2、resolve.alias: 给路径起别名。当代码中使用了众多相对路径,不仅我们去找这个文件费劲,webpack 也是需要时间去解析。所以直接配置好绝对路径,在代码中用别名代替冗长的路径。于编译解析,于代码书写,都是利好,两开花!

3、resolve.extensions: 则是告知 webpack 获取哪些类型的文件。比如:['js', 'ux'],当我们引用文件是这样写 import util from './util',在定位到目录之后,就开始按照 util.js -> util.ux 的顺序去寻找该文件。

也就是这个字段配置作用是方便了代码的书写,但是增加 webpack 的搜索时间(故此字段仅为介绍,无需增加配置)。所以如果代码中精确到完整文件名,在大工程多引用文件数的情况下,也是能节省一笔可观的时间消耗哟。

随着工具的升级,及开放自定义程度的提高,整体编译速度也会不断提升,敬请期待。

您可能会感兴趣的文章

npm 编译慢_如何有效提升快应用(Webpack)编译速度相关推荐

  1. vc2010解决方案项目编译顺序_科学网—VS2012 (2008,2010) 编译问题解决合集 - 冯博远的博文...

    问题一: VS2012 (包括从VS2008,VS2010) 出现编译错误:LINK : fatal error LNK1104: cannot open file 'LIBC.lib' 的解决办法: ...

  2. ubuntu编译内核_鸿蒙源码下载并编译

    第一章 下载源码并编译 1.1 在Ubuntu中安装开发环境 如果你是从头看文档,并且按照文档操作,那么你已经按照<5.2 安装Ubuntu软件>下载并运行了这个脚本:Configurin ...

  3. kotlin编译失败_关于应用Kotlin后的编译速度问题

    2017年 Kotlin 被 Google 钦定为 Android 开发官方语言之一后,便如火如荼.很多团队开始应用了Kotlin,可谓是收益良多,可是也有一些问题,一个比较明显的就是Kotlin应用 ...

  4. vue代码可以反编译吗_避免小程序被反编译获取源码(转载)

    原地址:https://www.cnblogs.com/taltao/p/10082084.html 众所周知,微信小程序的代码安全性很弱,很容易被别人反编译获取源码.我自己的小程序也被别人反编译拿到 ...

  5. python 预编译加速_让Python代码运行更快的最佳方式

    Python因其强大.灵活且易于使用等特性,而赢得了声誉.这些优点使其在各种各样的应用程序.工作流程和领域中得到了广泛应用.但是就语言的设计,也就是它天然的解释能力还有它的运行时的动态性而言,Pyth ...

  6. 反编译小程序_小程序/小游戏 反编译教程

    使用的反编译脚本叫做wxappUnpacker 开搞吧,我们通过电脑上的安卓模拟器来获取,我这里使用的是夜神模拟器,启动后安装微信,RE管理器,QQ(用来传输文件) 登陆微信后,在下拉框中找到我们要获 ...

  7. VS2013_QT5.4_静态编译问题_已经解决

    VS2013_QT5.4_静态编译问题_已经解决 参考文章: (1)VS2013_QT5.4_静态编译问题_已经解决 (2)https://www.cnblogs.com/listensong/p/4 ...

  8. 第一段Java程序_借助Win控制命令台编译执行 编辑器Notepad++

    第一段Java程序_借助Win控制命令台编译执行 编辑器Notepad++ 准备代码: 第一次编译: 显然需要先配置环境变量: 先找到java.exe和javac.exe所在的文件夹位置: 此电脑-& ...

  9. 添加编译宏_软件开发——编译链接

    对于平常的应用程序开发,我们很少需要关注编译和链接过程.我们平常Xcode开发就是集成的的开发环境(IDE),这样的IDE一般都将编译和链接的过程一步完成,通常将这种编译和链接合并在一起的过程称为构建 ...

  10. vue代码可以反编译吗_微信小程序源码提取反编译

    一.前言 微信小程序源码提取反编译,听起来很屌,其实还是简单的,基本是傻瓜式操作.要想拿到微信小程序源码,找到源文件在手机存放的位置就行,源文件拿到,用反编译脚本跑一下,微信小程序代码包里的所有文件. ...

最新文章

  1. CentOS系列启动流程详解
  2. DWR重温 DWE例子 如下
  3. 查看控制文件的内容(oracle)
  4. opencv视频处理和检测学习总结
  5. 刚刚,阿里发布AI谣言粉碎机,识别准确率达81%
  6. Spring boot错误处理机制
  7. Thymeleaf语法规则
  8. 【XAudio2】7.如何加载音频数据文件
  9. web前端网页设计作业_网页前端设计快速入门技巧
  10. android jni jstring 转 char*
  11. 170821-关于SpringMVC的知识点
  12. java中泛型上限,下限应用
  13. JVM007_运行时栈帧结构
  14. Java基础语法及其经验总结
  15. 软件加入使用时间_信考宝典 中考软件简介
  16. Mongo 3.6.1版本Sharding集群配置
  17. Python 中非常狗的一个坑(在 `a={1:2},`后面多了一个逗号,自动被判为 tuple 类型了)
  18. MBSE基于模型的系统工程
  19. 89c51单片机流水灯操作
  20. oreo另一个意思_孑孓、仄亾、片爿…看起来天生一对的字,意思竟然大不同

热门文章

  1. unity Scene窗口的任意比例放大和缩小
  2. c++拼接字符串效率比较(+=、append、stringstream、sprintf)
  3. Atitit 趋势管理之道 attilax著
  4. atitit.RandomAccessFile rws rwd 的区别于联系
  5. atitit.sql server2008导出导入数据库大的表格文件... oracle mysql
  6. paip.FTP服务架设选型
  7. LBMALL V3.1.1 多用户商城系统功能说明
  8. paip.接入支付接口功能流程总结
  9. paip.从HTML select 获取数据
  10. 阿里云基础产品技术月刊 2018年12月