如何有效提升快应用(Webpack)编译速度

背景 在开发快应用时,少不了构建操作:npm run build(官方 IDE 集成了这些操作,本质上也是调用同样方法)。这是因为快应用有自己的 DSL 语法,直接写出来,在底层不能识别,需要把业务代码编译成底层能运行的代码(感兴趣的同学,可在 build 文件夹查看编译后的代码产物)。整个过程就跟 Vue 和 React 工程的打包一样。等待的过程总是漫长,当项目越来越大的时候,难免还要花上点时间。可谁不希望这个过程越快越好呢?本篇就在于探讨,如何有效提升快应用(Webpack)编译速度。 快应用工程是基于 hap-toolkit 编译打包的。而它的功能,部分是基于 Webpack 开发。所以下面跟大家分享的,关于提升快应用编译速度的方法,同样也适用于基于 Webpack 构建的 Web 应用。 本文原本首发于 vivo 快应用官方博客。 基于插件 不过毕竟是 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 的搜索时间(故此字段仅为介绍,无需增加配置)。所以如果代码中精确到完整文件名,在大工程多引用文件数的情况下,也是能节省一笔可观的时间消耗哟。 随着工具的升级,及开放自定义程度的提高,整体编译速度也会不断提升,敬请期待。 您可能会感兴趣的文章 Prettier 插件为更漂亮快应用代码 快应用脚手架,为优雅而生 云集优站,尽在「倾城之链」其二 快应用之开发体验纪要 快应用开发资源、教程汇聚 TOP 100 大前端超棒精选列表 如何优雅处理「快应用」数据请求

本文章由javascript技术分享原创和收集

发表评论 (审核通过后显示评论):