前端项目模块化的实践2:使用 Webpack 打包基础设施代码

以下是关于前端项目模块化的实践,包含以下内容: 搭建 NPM 私有仓库管理源码及依赖; 使用 Webpack 打包基础设施代码; 使用 TypeScript 编写可靠类库 使用 TypeScript 的收益 使用 Mocha/Jest 进行单元测试 [实现中] 本文是关于前端项目模板化的第2部分 现状 实际项目远远比示例使用的 myGreeting 复杂,比如 为了提高可维护性我们将项目折成了许多功能模板; 我们希望使用 Promise 等语法等,但是顾忌目标环境的支持能力; 可能依赖了多个第三方类库; 为了提高加载速度我们打包时需要进行很多额外工作; 代码压缩; Tree Shaking(参考文末); 既能运行在 WEB 浏览器,也能在 NodeJS 中使用; 假设我们有一个工具集项目 myHammer,包含 base64 转换功能和一个简单版的字典树实现,项目结构如下: busybruce@DESKTOP-B8KJKRS /d/Documents/MyGit/PracticeInNPM/myHammer $ tree src/ test/ src/ ├── base64.js ├── index.js └── TrieFilter.js test/ ├── base64.test.js └── TrieFilter.test.js 0 directories, 5 files index.js 导出了项目中的功能模块: const base64 = require('./base64'); const TrieFilter = require('./TrieFilter') module.exports = { base64, TrieFilter, } 如果不打包,单独发布当前项目到 NPM 仓库并没有问题,只是 依赖本项目的时候写法比较纠结,形如 const base64 = require('myHammer/src/base64'); 可能存在到目标环境的适配问题,如前文所述; 目标环境不支持 Promise 等语法等 源码是 CoffeeScript 或者 TypeScript,没法直接引用 下面使用 Webpack 来解决这些问题。 Webpack 打包基础类库 Webpack 文档内容多,网上教程多是关于应用打包,现整理如下。 本文并非 Webpack 的使用指南,只提及类库打包,行文时Webpack已更新至4.x 版本。 package.json 需要配置 package.json 的 main 节点供 NodeJS 环境使用。 "main": "src/index.js", NodeJS 运行环境作了约定,使用 require('xxx')时将读取该配置。 避免形如 require('myHammer/src/base64')类似的引用完整路径的写法 如果源码使用了高版本的语言特性,可以转译和打包代码到形如 dist/inde-es5.js 的路径,再修改该配置指向该文件以向下兼容 使用需要转译成 JavaScript 语言同理 在部分 IDE 时我们查找引用时,往往发现函数声明有好多处实现,原因就在于代码转译、打包成了很多份,如下图所示。 webpack.config.js 类库打包需要对 webpack.config.js 中的 output 进行配置,摘取如下: output : { library : "hammer", libraryTarget: "umd", globalObject : "this", path : path.join(__dirname, "dist"), filename : "hammer.js", } 其他配置请自行阅读文档,完整内容见代码 webpack.config.js。 libraryTarget: 为了在浏览器和 NodeJS 环境中同时生效,需要使用 umd 作为目标,参考 output-librarytarget globalObject: 使用 this替换默认的 window,参考 Webpack 4.0.1 | WebWorker window is not defined #6642 如前文所述,在不考虑语言、版本、目标平台的差异的情况下,直接将源码发布到 NPM 仓库,再添加依赖和引用并无问题。在业务日益复杂的情况下,手写代码在实现层面直接消除这些差异是无比巨大的工作量,使用 Webpack 让我们更专注业务本身, Make life easier。 发布到 NPM 和使用依赖 在完成了具体业务后,我们打包项目并发布到私有 NPM 仓库 webpack --mode development # 视具体需求 npm publish --registry http://ubuntu-17:4873 # --force 在 myDemo 项目中我们添加引用 yarn add myHammer --registry http://ubuntu-17:4873 修改 index.js 如下: const myGreeting = require('myGreeting'); const {base64} = require('myHammer'); (function () { let greeting = myGreeting('Rattz'); console.log(base64.encode(greeting)); })(); 运行起来 $ node index.js SGVsbG8gUmF0dHo= 关于 Tree Shaking 略微提及一下 Tree Shaking ,简单地说 Tree Shaking 通过不引用没有依赖的代码,能有效缩减打包后的文件大小。 举例来说,我们使用了 ES2016 的语法,希望最后编译在 ES2015 环境使用。这里有若干种可行方案,其中一种是 使用 babel 全家桶包含 babel-cli, babel-core, babel-loader, babel-preset-env; 添加 .babelrc 文件写入内容 {"presets":["env"]}; 在入口代码的首行使用 require('babel-polyfill'); babel 进行语法转换,补丁文件进行对低版本 ES2015 的适配,该方案中 babel-polyfill 被完整引用, 打包完成后占用120k 左右大小,往往比业务代码还多。 Tree Shaking 即为解决该问题而来,比如某模板同时提供了加法和减法,而我们只依赖了加法方法,如果打包工具支持 Tree Shaking,就能在打包时剔除掉未使用的减法相关代码。 Webpack 提供了相关支持,见于 Tree Shaking - webpack。 项目所使用源码已发布 github,jusfrw 原创https://www.cnblogs.com/Jusfr/p/9551119.html
50000+
5万行代码练就真实本领
17年
创办于2008年老牌培训机构
1000+
合作企业
98%
就业率

联系我们

电话咨询

0532-85025005

扫码添加微信